hunting/doc/design.md
2023-08-15 16:04:38 -07:00

440 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1. 设计文档
## 1.1. 产品概述
## 1.2. 结构设计
1. 迷彩外观;
2. 抽屉式电池箱组;
3. 捆绑/相机支架安装方式;
4. 案件翻盖保护;
5. 可拓展4G模块
6. 户外防水;
## 1.3. 硬件设计
### 1.3.1. 关键外设
1. 摄像头;
2. PIR sensor
3. IR leds
4. 电池(箱体);
5. 启动模式拨键(三键);
6. 按键:同步/复位/格式化;
7. SD card
8. usb接口
9. NFC绑定APP
10. 光感传感器:白天/黑夜;
11. 指示灯:设备状态/SD卡状态/电量/无线信号灯/账号状态;
### 1.3.2. 生产测试/研发调试
## 1.4. 软件设计
### 1.4.1. 多态单例设计模式
   多态单例模式包含两部分:抽象接口 + 抽象接口实例,代码基于抽象接口存在,业务基于抽象接口实例存在。
#### 1.4.1.1. 多态单例图示
   下述图示分别为:类图 / 依赖关系图 / 编译链接关系图
```mermaid
classDiagram
APP --> AbstractInterface:使用
AbstractInterface <|.. Instance:实现
应用 --> 抽象接口库:依赖
抽象接口库 ..> 实例库:依赖
main线程 --> 抽象接口代码库:链接
main线程 --> 实例代码库:链接
```
#### 1.4.1.2. 多态单例模块使用时序图
&emsp;&emsp; 在使用多态单例设计模式开发功能模块时,使用统一的命名规则:
* 抽象接口命名xxx + Abstract例如libLogAbstract.a;
* 实例库命名xxx + 具体实例名称例如libLogEasylogging.a
**调用关系如下图**
```mermaid
sequenceDiagram
User ->> +libLogAbstract.a:调用抽象接口
libLogAbstract.a --> +libLogEasylogging.a:实际调用实例接口
libLogEasylogging.a --> -libLogAbstract.a:return
libLogAbstract.a -->> -User:return
```
**只有main函数实际调用实例库的实例化接口时log功能才会生效。**
#### 1.4.1.3. 多态单例目录结构规范
&emsp;&emsp; 根据多态单例设计模式,指定使用多态单例模式开发的模块的源码目录结构,耦合思路清晰。
```
└── Log // 多态单例模式模块的目录
├── include // 多态单例模块对外暴露的头文件目录,抽象接口定义
│   └── ILogAbstract.h
├── abstract // 多态单例模式抽象接口声明
│   └── ILogAbstract.cpp
└── src // 多态单例接口实例代码,目录名称可根据实际功能定义
├── LogAstract.cpp
└── LogAstract.h
```
&emsp;&emsp; 构建时把abstract目录和src目录的源码分别编译成库main线程根据实际需要链接并实例化即可。
#### 1.4.1.4. 多态单例总结:
1. 应用代码只使用抽象接口,禁止直接依赖实例代码;
2. 应用代码只有在main线程初始化时实例化实例模块即可
3. 多态单例模块由两个库组成,一个是抽象接口库,一个是实例代码库,支持静态多态和动态多态;
### 1.4.2. 根据软件模块作用域分层
#### 1.4.2.1. 应用层application
##### 1.4.2.1.1. 应用层概述
&emsp;&emsp; 应用层负责处理产品级的复杂业务关系是产品功能的直接体现应用层模块全部使用C++接口的多态单例模式设计,各模块之间可以互相调用接口,应用层各库可以随意任意调用中间件或者工具类接口。
##### 1.4.2.1.2. 网络服务模块
###### 1.4.2.1.2.1. 网络服务概述
&emsp;&emsp; 根据产品联网属性,网络服务模块分为不联网 / 联网B端/ 联网自研三个多态属性。联网时IPC的图片 / 视频资源通过网络服务器进行管理。
1. 不联网版本:网络服务模块不实例化即可;
2. 联网B端媒体资源由三方服务器管理
3. 联网(自研):媒体资源由自研服务器管理;
###### 1.4.2.1.2.2. 网络服务多态设计模式
&emsp;&emsp; 通过构建配置文件选择需要实例化的网络服务模块代码。
#### 1.4.2.2. 中间件middleware
##### 1.4.2.2.1. 中间件概述
&emsp;&emsp; 一些相对中性的业务功能库这些库可以提供给不同的产品需求使用在应用层不同的调用方式可实现不同的产品功能。中间件只能被应用层调用或者向下调用适配层或者调用工具库中间件各模块之间不能互相调用。中间件库接口可以使用C或者C++接口。
##### 1.4.2.2.2. 外设管理模块
&emsp;&emsp; 应用层唯一的硬件外设接口库。包含灯 / 按键 / GPIO / SD卡等。
##### 1.4.2.2.3. 相机管理模块
&emsp;&emsp; 应用层唯一的摄像头接口库。
##### 1.4.2.2.4. MCU管理模块
&emsp;&emsp; MCU通信接口库一般使用串口进行通信需要考虑多态其它接口例如I2C考虑多态协议数据结构。MCU负责管理外设的电源控制 / 充当硬狗等。
###### 1.4.2.2.4.1. MCU管理模块设计模式
&emsp;&emsp; 使用C++接口的多态单例模式。
基本功能:
1. 使用utils当中的串口功能模块支持多态切换到其它串口功能模块
2. 设置MCU管理的监视器monitor用于回调处理MCU接受到的业务事件
3. 通信协议不暴露,内部处理基于协议的数据解析 / 组包;
4. 通信协议支持多态拓展,通信协议独立成库;
##### 1.4.2.2.5. IPC配置库
&emsp;&emsp; 负责管理IPC产品相关的配置数据。
###### 1.4.2.2.5.1. IPC配置库设计模式
&emsp;&emsp; 使用多态单例设计模式对外提供C语言接口内部不局限使用C或者C++。
**基本功能**
1. 敏感数据(例如:账号 / 密码)需要加密处理;
2. 读到内存使用二进制数据,缓存到数据结构体;
3. 调用utils工具里面的配置库对配置文件进行读 / 写;
4. 使用二进制结构体 + 明文配置文件结合的模式,既可减少内存消耗,又可以规避二进制数据升级迭代数据匹配困难问题;
5. 使用枚举方式管理IPC配置数据定义当使用纯16进制保存数据时可不链接utils工具里面的配置库直接保存16进制数据到文件系统即可
6. 应用程序全局唯一可以操作IPC配置文件的库保证配置文件正确读写
###### 1.4.2.2.5.2. IPC配置库类图
```mermaid
classDiagram
i_ipc_config <.. ipc_config:实现
ipc_config --> i_config_manager:依赖
ipc_config --> IHal:依赖
i_config_manager <.. config_manager:实现
config_manager --> libconfig开源库:依赖
```
###### 1.4.2.2.5.3. 关键业务时序图
&emsp;&emsp; **时序图会忽略抽象接口直接使用实例接口表示。**
* IPC配置库初始化 / 解初始化
```mermaid
sequenceDiagram
participant User
participant ipc_config
participant i_config
participant IHal
User ->> +ipc_config:初始化
ipc_config ->> +IHal:获取文件系统路径
IHal -->> -ipc_config:return
ipc_config ->> +i_config:打开配置文件
i_config -->> -ipc_config:return
alt 打开成功
loop 读取所有数据到IPC数据结构体
ipc_config ->> +i_config:读取一个数据到IPC数据结构体
i_config -->> -ipc_config:return
opt 读取失败
ipc_config ->> ipc_config:生成默认数据
ipc_config ->> +i_config:设置默认数据
i_config ->> -ipc_config:return
end
end
ipc_config ->> +i_config:关闭配置文件
i_config -->> -ipc_config:return
else 打开失败
ipc_config ->> ipc_config:生产默认数据
ipc_config ->> +i_config:创建配置文件
i_config -->> -ipc_config:return
ipc_config ->> +i_config:设置默认数据
i_config -->> -ipc_config:return
ipc_config ->> +i_config:关闭配置文件
i_config -->> -ipc_config:return
end
ipc_config -->> -User:return
User ->> +ipc_config:解初始化
ipc_config ->> ipc_config:释放内存中的数据
ipc_config -->> -User:return
```
* 读 / 写(修改)数据
```mermaid
sequenceDiagram
participant User
participant ipc_config
User ->> +ipc_config:读取数据
ipc_config ->> ipc_config:返回内存保存的数据
ipc_config -->> -User:return
User ->> +ipc_config:修改数据
ipc_config ->> ipc_config:修改内存保存的数据
ipc_config -->> -User:return
```
* 保存数据
```mermaid
sequenceDiagram
participant User
participant ipc_config
participant i_config
User ->> +ipc_config:保存
ipc_config ->> +i_config:打开配置文件
i_config -->> -ipc_config:return
ipc_config ->> +i_config:同步数据
i_config -->> -ipc_config:return
ipc_config ->> +i_config:保存配置文件
i_config -->> -ipc_config:return
ipc_config ->> +i_config:关闭配置文件
i_config -->> -ipc_config:return
ipc_config -->> -User:return
```
##### 1.4.2.2.6. 高级配置库
&emsp;&emsp; 对配置库的二级封装,提供更便捷的功能服务,例如:可以监控文件的修改事件 / 可以直接捕获某个配置文件或者数据的操作对象。
###### 1.4.2.2.6.1. 高级配置库设计
&emsp;&emsp; 对外暴露C++接口,使用多态单例设计模式。
##### 1.4.2.2.7. 状态机管理
&emsp;&emsp; 提供实现状态机管理机制C++接口,使用鸿蒙状态机开源源码进行改造封装。
###### 1.4.2.2.7.1. 状态机管理设计模式
&emsp;&emsp; 使用多态单例设计模式,暂定使用鸿蒙状态机开源代码改造实现,后续可替换其它源码或者自研代码。
#### 1.4.2.3. 硬件适配层hal
&emsp;&emsp; 负责适配不同的硬件平台。
##### 1.4.2.3.1. 硬件适配层设计模式
&emsp;&emsp; 基于C语言接口的多态单例模式编译时静态多态链接对应的芯片平台适配代码实现芯片接口的标准功能定义。
##### 1.4.2.3.2. 媒体适配方案:
&emsp;&emsp; IPC应用在适配芯片平台的多媒体接口时使用多进程的方式实现。满足IPC应用可以快起无需等待媒体相关的初始化的需求。
**媒体基本需求**
1. 图片抓拍;
2. 视频抓拍;
**多进程通信方案**
&emsp;&emsp; 使用本地socket的方式进行多进程通信媒体进程为客户端IPC应用为服务端IPC先启动
1. 客户端可自动重连;
2. 服务端可多次关闭和开启满足gtest资源回收需求
##### 1.4.2.3.3. 适配层多进程类图
```mermaid
classDiagram
i_hal <.. hal:实现
hal --> v_media_handle:依赖
v_media_handle --> local_socket:依赖
local_socket .. media进程:跨进程
media进程 --> 芯片媒体API:依赖
```
##### 1.4.2.3.4. 跨进程业务时序图
* 本地socket链接
```mermaid
sequenceDiagram
participant hal
participant v_media_handle
participant local_socket_s
participant local_socket_c
participant media进程
participant 芯片媒体API
hal ->> +v_media_handle:初始化
v_media_handle ->> +local_socket_s:本地socket服务端启动
par 本地socket初始化
local_socket_s -->> -v_media_handle:return
v_media_handle -->> -hal:return
and
media进程 ->> media进程:启动
media进程 ->> +local_socket_c:初始化服务端
local_socket_c -->> local_socket_s:链接
local_socket_c -->> -media进程:return
local_socket_s -->> local_socket_c:初始化媒体
local_socket_c ->> media进程:回调回传协议事件
media进程 ->> +芯片媒体API:初始化媒体
芯片媒体API -->> -media进程:return
end
```
* 存在问题:
使用C语言开发时如何解决智能指针问题
#### 1.4.2.4. 工具库utils
##### 1.4.2.4.1. 工具库概述
&emsp;&emsp; 工具库是功能单一的不依赖任何三方库的独立库日志库和返回码管理库除外必须提供C语言接口内部实现不限于C或者C++。工具类库可以被任意的其它模块调用特别指hal/component/application三大层级。
##### 1.4.2.4.2. 日志库
###### 1.4.2.4.2.1. 日志库概述
&emsp;&emsp; 提供程序的日志管理功能,含日志的实时打印/保存/跟踪(实时上传云端)。
###### 1.4.2.4.2.2. 日志库设计模式
&emsp;&emsp; C语言接口的多态单例模式可动态/静态加载多态实例。
###### 1.4.2.4.2.3. 日志库启动
&emsp;&emsp; 日志库是否启用一般来讲是dubug版本启用日志功能release版本禁用日志功能考虑到release版本的维护问题标准启动时main线程在启动时使用dlopen系列函数去加载日志库多态特殊版本仍可在main线程加载日志库后二次实例化日志库多态来实现不同的日志功能。
1. 标准流程main线程加载sd卡动态库如有即可动态实现日志功能正常出货sd卡不带日志库此时没有日志功能
2. 可以通过配置参数决定是否启用日志;
3. sd卡的日志动态根据实际售后维护可以是实时打印log/保存本地log/云log的多态实例库
4. 多态日志功能可以忽略debug和release版本的区别只发布一个版本即可
##### 1.4.2.4.3. 返回码管理库
###### 1.4.2.4.3.1. 返回码管理库概述
&emsp;&emsp; 提供整个应用程序的返回码管理功能例如打印返回码的字符串含义。提供C语言接口纯C语言开发的模块形成项目内部唯一返回码标准。
1. 创建返回码操作“句柄”;
2. 打印返回码/获取返回码(字符串);
3. 不同的模块可继承实现各自的返回码处理接口;
##### 1.4.2.4.4. 系统标准接口库
&emsp;&emsp; 对系统标准接口的套壳封装,主要是为了对系统标准打桩满足测试需求。
&emsp;&emsp; 使用普通的C语言接口封装即可通过使用gcc编译参数在Linux x86系统中满足打桩需求在交叉编译担心工具链兼容问题测试程序中无法对系统标准接口进行打桩。
##### 1.4.2.4.5. 通用配置库
###### 1.4.2.4.5.1. 通用配置库概述
&emsp;&emsp; 配置库负责管理软件配置参数,对配置数据进行设置 / 获取 / 存储 / 备份 / 升级等功能;通用配置库不限制使用场景,是一个通用的配置文件管理库。
###### 1.4.2.4.5.2. 配置库设计模式
&emsp;&emsp; 对外提供C语言接口内部不局限使用C或者C++。整个软件唯一可以直接操作文件系统配置文件的库。配置库可以理解为简单的三方库的接口直接封装,使用多态单例设计模式实现静态或者动态切换三方库的使用。
**基本功能**
1. 使用**三方库**保存明文格式的配置文件到文件系统;
2. 可注册回调函数,监听文件的操作事件;
3. 使用字符串名字key + 值的方式管理配置文件,作为通用的配置文件管理库;
###### 1.4.2.4.5.3. 开源库
两种方案:
1. 使用libconfig作为文件操作的开源库实现文件和数据的读 / 写。
2. 使用sqlite3作为文件操作的开源库作为数据库文件处理。
###### 1.4.2.4.5.4. 通用配置库类图
&emsp;&emsp; 多态单例设计模式main线程静态链接多态库。
```mermaid
classDiagram
i_config_manager <.. config_manager:实现
config_manager --> libconfig开源库:依赖
i_config_manager <.. sqlite_manager:实现
sqlite_manager --> sqlite3数据库:依赖
```
###### 1.4.2.4.5.5. 备份机制
&emsp;&emsp; 备份数据用于数据异常时可还原旧数据。
方案选择:
1. 出厂默认配置文件为只读文件,在数据破坏时还原;
###### 1.4.2.4.5.6. 升级机制
&emsp;&emsp; 程序升级后配置数据发生增 / 删时如何兼容和还原。
##### 1.4.2.4.6. 串口功能模块
&emsp;&emsp; 串口的打开 / 关闭 / 数据读 / 数据写 功能。
###### 1.4.2.4.6.1. 串口开源库
使用下述开源库对串口数据进行收发。
```
https://gitee.com/RT-Thread-Mirror/TinyFrame
```
##### 1.4.2.4.7. MCU协议库
&emsp;&emsp; 负责MCU通信协议的组包 / 拆包 / 事件转换。
###### 1.4.2.4.7.1. MCU协议库设计模式
&emsp;&emsp; 基于C语言的多态单例设计模式。
###### 1.4.2.4.7.2. 协议数据结构
##### 1.4.2.4.8. 多进程协议库
&emsp;&emsp; 负责IPC应用和媒体进程之间的协议组包 / 拆包,在协议和业务之间进行转换接口的封装。
## 1.5. 自动化测试
### 1.5.1. 自动化测试概述
&emsp;&emsp; 自动化测试是该产品设计的一大特点,需要严格执行。自动化测试指使用纯代码对业务设计进行测试用例设计,实现业务集成测试的能力。
### 1.5.2. 自动化测试规范
1. 每个源码文件在开发时均要写调试的example用于验证该文件的接口功能测试文件的命名规则为文件名 + “_Test.c(pp)”;
例如:
* C语言log_impl.c对应的测试文件为log_impl_Test.cpp;
* C++:LogImpl.cpp对应的测试文件为LogImpl_Test.cpp;
2.