diff --git a/CMakeLists.txt b/CMakeLists.txt index 96cb97b..078ab46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5.1) +cmake_minimum_required(VERSION 3.5) unset(CLANG_TIDY_EXE CACHE) set(CMAKE_SOURCE_DIR_IPCSDK "${CMAKE_CURRENT_SOURCE_DIR}" CACHE STRING INTERNAL) diff --git a/README.md b/README.md index 4f9f28c..57dbc3d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ ### 1.2.1. Ubuntu系统 在项目根目录下执行命令: -``` + +```code make clean // 如果之前有跨平台编译过,需要先make clean make cmake // 构建源码,生成Makefile文件 cd cmake-shell/ // 在中间文件目录进行编译,把所有中间文件创建在此目录 @@ -27,11 +28,30 @@ make // 编译全部输出构建文件 参考: -``` +```code //build/cmake/toolchain/linux.toolchain.cmake //Makefile ```   参考上述文件新建一份配置文件,建议不要修改原文档,新建一个交叉编译工程,把IPC SDK工程作为子仓库进行git管理,维护SDK的绝对跨平台属性。 -  交叉编译请参考基于IPC SDK作为子仓库的工程配置,此处忽略。 \ No newline at end of file +  交叉编译请参考基于IPC SDK作为子仓库的工程配置,此处忽略。 + +### 1.2.3. 小技巧 + +#### 1.2.3.1. 代码阅读辅助工具(基于vscode) + +  为了方便代码跳转阅读,除了安装基本的c++插件外,结合cmake构建工具生成的compile_commands.json文件可实现代码之间的精准跳转。 + +**compile_commands.json文件生成路径:** + +```code +//cmake-shell/compile_commands.json +``` + +**compile_commands.json文件配置方法:** + +```code +在//.vscode/settings.json配置文件中添加: +"C_Cpp.default.compileCommands": "/home/xiaojiazhu/project/ipc-sdk/ipc/cmake-shell/compile_commands.json", +``` diff --git a/build/cmake/toolchain/linux.toolchain.cmake b/build/cmake/toolchain/linux.toolchain.cmake index 40fa3c6..2f4b9a0 100755 --- a/build/cmake/toolchain/linux.toolchain.cmake +++ b/build/cmake/toolchain/linux.toolchain.cmake @@ -24,10 +24,8 @@ add_definitions(-Wall -O2 -Os) add_definitions(-Wno-unused-local-typedefs) add_definitions(-Wstrict-aliasing -Wwrite-strings) - set(TOOLCHAIN_NAME arm-linux-gnueabihf) - set(TARGET_PLATFORM "linux") set(SUBMODULE_PATH_OF_IPC_SDK "") set(PLATFORM_PATH "${CMAKE_CURRENT_SOURCE_DIR}") @@ -42,6 +40,7 @@ set(CURL_OPENSSL_LIB_SHARED_ENABLE "false") # ------------ build IpcConfig ------------ # set(IPC_CONFIG_FILE_PATH "./ipc_config") +set(USERDATA_MOUNT_PATH "/userdata") # ------------ build IpcConfig end ------------ # # ------------ build log ------------ # diff --git a/customization/README.md b/customization/README.md index fad1dca..f04cd31 100644 --- a/customization/README.md +++ b/customization/README.md @@ -13,4 +13,54 @@ ### 1.2.3. 其它定制版本 -   基于公版,继承派生出来的特殊功能的商业化版本。 \ No newline at end of file +   基于公版,继承派生出来的特殊功能的商业化版本。 + +``` +#include +#include +#include + +int is_mounted(const char *dirpath) { + FILE *fp; + char line[1024]; + char mount_point[1024]; + + // 尝试打开 /proc/mounts 文件 + fp = fopen("/proc/mounts", "r"); + if (fp == NULL) { + perror("Error opening /proc/mounts"); + return -1; + } + + // 逐行读取并查找挂载点 + while (fgets(line, sizeof(line), fp) != NULL) { + if (sscanf(line, "%*s %1023s %*s %*s %*d %*d\n", mount_point) == 1) { + // 检查当前行中的挂载点是否与所查找的目录匹配 + if (strcmp(dirpath, mount_point) == 0) { + fclose(fp); + return 1; // 已挂载 + } + } + } + + fclose(fp); + return 0; // 未挂载 +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + const char *dirpath = argv[1]; + + if (is_mounted(dirpath)) { + printf("Directory '%s' is mounted.\n", dirpath); + } else { + printf("Directory '%s' is not mounted.\n", dirpath); + } + + return 0; +} +``` \ No newline at end of file diff --git a/doc/git_guide.md b/doc/git_guide.md index 6afb8c6..35e26f5 100644 --- a/doc/git_guide.md +++ b/doc/git_guide.md @@ -18,23 +18,27 @@   当主干发生较大变化,例如:原厂更新sdk时,需要新建分支,划分界限。 -``` +```code $ git branch -a +---------------- * master remotes/origin/HEAD -> origin/master remotes/origin/app_test remotes/origin/master $ git checkout -b master-sdk-202405 origin/master +------------------------------------------------- M ipc-sdk Branch 'master-sdk-202405' set up to track remote branch 'master' from 'origin'. Switched to a new branch 'master-sdk-202405' $ git branch -a +---------------- master * master-sdk-202405 remotes/origin/HEAD -> origin/master remotes/origin/app_test remotes/origin/master $ git push origin master-sdk-202405:sdk-202405 +---------------------------------------------- Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Delta compression using up to 8 threads @@ -47,6 +51,7 @@ remote: https://gitee.com/shenzhen-jiuyilian/ipc-rk1106/pull/new/shenzhen-ji To gitee.com:shenzhen-jiuyilian/ipc-rk1106.git * [new branch] master-sdk-202405 -> sdk-202405 $ git branch -a +--------------- master * master-sdk-202405 remotes/origin/HEAD -> origin/master @@ -55,6 +60,120 @@ $ git branch -a remotes/origin/sdk-202405 ``` +### 1.4.2. git获取远端分支 + +  当想知道远端是否新建了分支,可使用git fetch命令获取远端分支。 + +**git fetch示例:** + +```code +$ git fetch +------------ +remote: Enumerating objects: 21, done. +remote: Counting objects: 100% (21/21), done. +remote: Compressing objects: 100% (11/11), done. +remote: Total 14 (delta 8), reused 0 (delta 0), pack-reused 0 +Unpacking objects: 100% (14/14), 2.14 KiB | 156.00 KiB/s, done. +From gitee.com:shenzhen-jiuyilian/ipc-rk1106 + bf71a01..2b9b803 master -> origin/master + * [new branch] sdk-202402 -> origin/sdk-202402 // 此处发现远端新建了分支 +Fetching submodule ipc-sdk +From gitee.com:shenzhen-jiuyilian/ipc + 7c261bd..eec9fb4 master-develop -> origin/master-develop +``` + +**多个远端仓库git fetch示例:** + +```code +$ git remote -v +---------------- +dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (fetch) +dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (push) +rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (fetch) +rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (push) +$ git fetch dgiot // git fetch + 远端仓库名称 +--------------------------------------------- +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (7/7), done. +remote: Total 9 (delta 3), reused 5 (delta 2), pack-reused 0 +Unpacking objects: 100% (9/9), 8.74 KiB | 746.00 KiB/s, done. +From gitee.com:shenzhen-jiuyilian/fastbootserver + * [new branch] sdk-202405 -> dgiot/sdk-202405 +``` + +### 1.4.3. git新增远端地址 + +  在一个git仓库中,可以同时管理多个远端地址,例如:在原厂的git仓库中,可以在仓库添加一个私人的git仓库,这样后续把修改提交到自己的仓库进行代码管理。 + +**git remote add示例:** + +命令格式: + +```code +git remote add +``` + +示例: + +```code +$ git remote add dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git +--------------------------------------------------------------------------- +$ git remote -v +---------------- +dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (fetch) +dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (push) +rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (fetch) +rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (push) +$ git fetch dgiot +------------------ +remote: Enumerating objects: 107, done. +remote: Counting objects: 100% (104/104), done. +remote: Compressing objects: 100% (45/45), done. +remote: Total 99 (delta 47), reused 89 (delta 42), pack-reused 0 +Unpacking objects: 100% (99/99), 29.55 KiB | 315.00 KiB/s, done. +From gitee.com:shenzhen-jiuyilian/fastbootserver + * [new branch] master -> dgiot/master + * [new branch] sdk-202405 -> dgiot/sdk-202405 +$ git branch -a +---------------- +* (HEAD detached at bf91101) + remotes/dgiot/master + remotes/dgiot/sdk-202405 + remotes/m/master + remotes/rk/master +$ git checkout -b sdk-202405 m/master +-------------------------------------- +Switched to a new branch 'sdk-202405' +$ git branch -a +---------------- +* sdk-202405 + remotes/dgiot/master + remotes/dgiot/sdk-202405 + remotes/m/master + remotes/rk/master +$ git pull dgiot sdk-202405 +--------------------------- +From gitee.com:shenzhen-jiuyilian/fastbootserver + * branch sdk-202405 -> FETCH_HEAD +Updating bf91101..dc76264 +Fast-forward + .clang-format | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + .gitmodules | 3 +++ + README.md | 30 ++++++++++++++++++++++++++++++ + rv1106_ipc_sdk | 1 + + 4 files changed, 170 insertions(+) + create mode 100644 .clang-format + create mode 100644 .gitmodules + create mode 100755 README.md + create mode 160000 rv1106_ipc_sdk +$ git submodule update --init +----------------------------- +Submodule 'rv1106_ipc_sdk' (git@gitee.com:shenzhen-jiuyilian/ipc-rk1106.git) registered for path 'rv1106_ipc_sdk' +Cloning into '/home/xiaojiazhu/project/rkipc/ipc_20240517/project/app/component/fastboot_server/rv1106_ipc_sdk'... +Submodule path 'rv1106_ipc_sdk': checked out 'ff8da760b201d365300aed78190de8564f0d2171' +``` + ## 1.5. 存疑 * 不同的分支之间如何同步某个文件? diff --git a/middleware/AppManager/README.md b/middleware/AppManager/README.md index e3c6592..f41a057 100644 --- a/middleware/AppManager/README.md +++ b/middleware/AppManager/README.md @@ -3,6 +3,7 @@ | 版本 | 时间 | 说明 | | ---- | ---- | ---- | | V1.0 | 2024-5-21 | 首次评审。 | +| V1.1 | 2024-5-25 | 增加标准设置项和动态设置参数协议。 | ## 1.1. 概述 @@ -99,57 +100,63 @@ **记录仪当前参数列表:** -| 参数名称 | 数据类型 | 取值说明 | 备注 | -| ---- | ---- | ---- | ---- | -| 记录仪WiFi名称 | ---- | ---- | ---- | -| 记录仪WiFi密码 | ---- | ---- | ---- | -| 固件版本 | ---- | ---- | ---- | -| 格式化存储卡 | ---- | ---- | ---- | -| 恢复出厂设置 | ---- | ---- | ---- | +| 参数名称 | 数据类型 | 取值说明 | 公版支持 | 备注 | +| ---- | ---- | ---- | ---- | ---- | +| 记录仪WiFi名称 | ---- | ---- | 支持 | ---- | +| 记录仪WiFi密码 | ---- | ---- | 支持 | ---- | +| 固件版本 | ---- | ---- | 支持 | ---- | +| 格式化存储卡 | ---- | ---- | 支持 | ---- | +| 恢复出厂设置 | ---- | ---- | 支持 | ---- | **打猎机参数需求列表:** -| 参数名称 | 数据类型 | 取值说明 | 备注 | -| ---- | ---- | ---- | ---- | -| 记录仪WiFi名称 | ---- | ---- | ---- | -| 记录仪WiFi密码 | ---- | ---- | ---- | -| 固件版本 | ---- | ---- | 仅显示 | -| ---- | ---- | ---- | ---- | -| 电量 | ---- | ---- | 仅显示 | -| 工作模式 | 数字 | 0:图片
1:图片+视频 | ---- | -| 连拍|数字 | 1/2/3 | 单位:P | -| 连拍间隔 | 数字 | 0~60 | 单位:s | -| 图片大小 | 数字 | 8/16/24/32/40 | 单位:M | -| 视频长度 | 数字 | 10/15 | 单位:s | -| PIR延时 | 数字 | 0~60 | 单位:s | -| 工作时间 | 时间 | 起始的时间设置
例如:起点20:00至终点6:00 | ---- | -| 循环存储 | 数字 | 0:OFF
1:ON | ---- | -| 红外灯功率 | 数字 | 0/1/2 | 低/中/高 | -| PIR灵敏度 | 数字 | 0~9 | ---- | -| 恢复出厂 | ---- | ---- | 功能 | -| 格式化SD卡 | ---- | ---- | 功能 | -| 重启 | ---- | ---- | 功能 | +| 参数名称 | 数据类型 | 取值说明 | 公版支持 | 备注 | +| ---- | ---- | ---- | ---- | ---- | +| 记录仪WiFi名称 | ---- | ---- | 支持 | ---- | +| 记录仪WiFi密码 | ---- | ---- | 支持 | ---- | +| 固件版本 | ---- | ---- | 支持 | 仅显示 | +| ---- | ---- | ---- | ---- | ---- | +| 电量 | ---- | ---- | 未支持 | 仅显示 | +| 工作模式 | 数字 | 0:图片
1:图片+视频 | 未支持 | ---- | +| 连拍|数字 | 1/2/3 | 未支持 | 单位:P | +| 连拍间隔 | 数字 | 0~60 | 未支持 | 单位:s | +| 图片大小 | 数字 | 8/16/24/32/40 | 未支持 | 单位:M | +| 录像分辨率 | 数字 | 0:WVGA
1:HD
2:FHD | 未支持 | ---- | +| 录像帧率 | 数字 | 15/30 | 未支持 | 单位:fps | +| 视频长度 | 数字 | 10/15 | 未支持 | 单位:s | +| PIR延时 | 时间 | 00:00:00-23:59:59 | 未支持 | 两个PIR之间的最小间隔 | +| 定时工作 | 时间 | 00:00:00-23:59:59 | 未支持 | 定时唤醒 | +| 工作时间 | 时间 | 起始的时间设置
例如:起点20:00至终点6:00 | 未支持 | ---- | +| 循环存储 | 数字 | 0:OFF
1:ON | 未支持 | ---- | +| 红外灯功率 | 数字 | 0/1/2 | 未支持 | 低/中/高 | +| PIR灵敏度 | 数字 | 0~9 | 未支持 | ---- | +| 恢复出厂 | ---- | ---- | 支持 | 功能 | +| 格式化SD卡 | ---- | ---- | 支持 | 功能 | +| 重启 | ---- | ---- | 未支持 | 功能 | #### 1.2.2.3. 问题列表 1. 针对软件迭代需求,除了一些和APP业务逻辑相关的参数需要特殊处理外,是否可以通过协议来获取设备自定义的参数设置?方便设备可以随意的增加/删除设置参数。 -答:已经支持,看协议能力。 +答:==已经支持==,看协议能力。 2. 没发现升级功能。 答:公版APP不支持升级功能。 ## 1.3. APP定制整改总结 +  **基于WiFi公版基础,未修改原有协议,做界面显示定制和增量开发,方案可控。** + 1. “记录仪”统一修改为“相机”; -答:公版无法修改,需要定制。 +答:需要定制。 2. 本地相册-“紧急”分类,改为“PIR”; -3. APP连接设备后,自动录像,改为默认不录像,可手动录像; +3. **新增标准的设置项,见前面描述:打猎机参数需求列表;** +4. APP连接设备后,自动录像,改为默认不录像,可手动录像; 答:设备返回非记录仪即可,见能力集。 -4. APP上的“循环”改成“全部”,“拍照”改成“手动”,“紧急”改成“PIR”,“停车”改成“定时”,**全部包括手动/PIR/定时**; -5. 相机设置需要实现设备自定义设置项功能; +5. APP上的“循环”改成“全部”,“拍照”改成“手动”,“紧急”改成“PIR”,“停车”改成“定时”,**全部包括手动/PIR/定时**; +6. **相机设置需要新增设备自定义设置项功能;** ## 1.4. 设置界面动态渲染方案设计 -  为了实现设置参数可自由定制,例如:可随意的增加/减少常见类型的参数设置。 +  为了实现设置参数可自由定制,例如:可随意的增加/减少常见类型的参数设置。**此功能APP无需多语言翻译,直接显示协议字符即可**。 ### 1.4.1. 常见设置类型 @@ -165,11 +172,130 @@ ### 1.4.2. 动态渲染设置界面 -1. APP获取设置参数列表,协议根据设置类型定义; -2. 设置界面根据设置类型显示设置控件; -3. 有操作后回传自定义控件信息; -4. 设备根据协议解析操作的控件,并执行自定义行为; +#### 1.4.2.1. 新增动态设置参数协议 + +**获取动态设置参数列表** + +| | | +| ---- | ---- | +| 描述 | 获取动态设置参数列表。 | +| 接口 | http://192.168.1.100/app/getdynamicparam | +| 参数 | ?index=all // 获取全部动态设置参数
?index=6 // 获取索引号为6的动态设置参数 | +| 返回参数 | result:0-成功,-1-失败
info:动态参数列表 | + +**获取全部动态参数返回示例:** + +```code +{ + "result": 0, + "info": + [ + { + "name": "SettingName", // 直接显示在APP界面 + "type": "label", // 显示控件类型,只显示 + "value": "0-表示字符串", // 当前值 + "index": 0 // 参数索引,直接回传给设备 + }, + { + "name": "NumberName", + "type": "inputnum", // 数字输入框,带单位显示 + "value": 123456789, + "unit": "s", // 单位,可选,如果有则显示单位 + "index": 1 // 参数索引,直接回传给设备 + }, + { + "name": "SwitchName", + "type": "switch", // 开关,0-关,1-开 + "value": 0, // 当前值,0-关,1-开 + "index": 2 // 参数索引,直接回传给设备 + }, + { + "name": "InputStringName", + "type": "inputstring", // 任意字符输入框,无限制 + "value": "0123abcDEF!@#", // 当前值 + "index": 3 // 参数索引,直接回传给设备 + }, + { + "name": "TimeSettingName", + "type": "time", // 时间设置(24小时制),格式:hh-mm-ss + "value": "23:59:59", // 当前值,格式:hh-mm-ss + "index": 4 // 参数索引,直接回传给设备 + }, + { + "name": "ConfirmName", + "tips": "Confirm?", // 提示信息,没有时使用name + "type": "comfirm", // 功能按钮(确认框) + "index": 5 // 参数索引,直接回传给设备 + }, + { + "name": "OptionName", + "type": "option", // 选项设置 + "items": ["Option0","Option1"], // 选项列表,格式:["选项1","选项2",...] + "value": 1, // 当前值, 索引值,0-Option0,1-Option1 + "index": 6 // 参数索引,直接回传给设备 + } + ] +} +``` + +响应值描述: + +| 参数名 | 类型 | 描述 | +| ---- | ---- | ---- | +| name | String | 直接显示在APP | +| type | String | 控件类型:
label-字符串,仅显示内容,无法修改
inputnum-数字
switch-开关(0-关,1-开)
inputstring-任意字符输入
time-时间设置
comfirm-功能按钮(确认框)
option-选项设置 | +| value | ---- | 当前值,类型根据type定义来确定 | +| unit | String | 单位,如果有则在APP界面显示 | +| index | int | 索引值,设备使用,根据索引值知道修改哪个参数 | + +**动态设置项设置协议** + +| | | +| ---- | ---- | +| 描述 | 动态设置项设置协议 | +| 接口 | http://192.168.1.100/app/dynamicparamset | +| 参数 | ?index=1&value=0123456789 // 数字输入框
?index=2&value=0 // 开关,0-关,1-开
?index=3&value=0123abcDEF!@# // 任意字符输入框
?index=4&value=23:59:59 // 时间
?index=5&value=0 // 0-取消;1-确认
?index=6&value=1 // 0-Option0,1-Option1,以此类推 | +| 返回参数 | result:0-成功,-1-失败
返回成功后重新获取动态参数显示 | + +**动态设置项设置返回示例:** + +```code +{ + "result" : 0, + "info" : "success." +} +``` + +**动态参数显示/设置UML时序图:** + +```mermaid +sequenceDiagram +participant APP +participant CAMERA +APP ->> APP:进入设置界面 +APP ->> +CAMERA:http:getdynamicparam?index=all +CAMERA -->> -APP:return +loop 设置界面停留 + opt 用户修改参数 + APP ->> APP:用户修改参数 + APP ->> +CAMERA:http:dynamicparamset?index=2 + CAMERA -->> -APP:return + alt result=0 + APP ->> APP:修改成功 + APP ->> +CAMERA:http:getdynamicparam?index=2 + CAMERA -->> -APP:return + APP ->> APP:刷新设置项显示 + else result=-1 + APP ->> APP:修改失败 + end + end +end +opt 设备端修改参数 + note over CAMERA: 设备端修改参数未能同步(未发现同步协议) +end +APP ->> APP:退出设置界面 +``` ### 1.4.3. 拓展规划 -  需要考虑拓展为4G版本。 \ No newline at end of file +  后续如何拓展为4G版本? diff --git a/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp b/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp index 0c48db1..5d84c10 100644 --- a/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp +++ b/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp @@ -25,6 +25,8 @@ using std::placeholders::_3; // clang-format off const char *TCP_RESULT_MSGID = "msgid"; const char *CJSON_INFO_STRING = "info"; +const char *CJSON_ITEMS_STRING = "items"; +const char *CJSON_INDEX_STRING = "index"; const char *CJSON_FILES_STRING = "files"; const char *APP_GET_PRODUCT_INFO = "/app/getproductinfo"; const char *APP_GET_DEVICE_ATTR = "/app/getdeviceattr"; @@ -32,6 +34,7 @@ const char *APP_GET_MEDIA_INFO = "/app/getmediainfo"; const char *APP_GET_SD_CARD_INFO = "/app/getsdinfo"; const char *APP_GET_BATTERY_INFO = "/app/getbatteryinfo"; const char *APP_GET_PARAM_VALUE = "/app/getparamvalue"; +const char *APP_GET_PARAM_ITEMS = "/app/getparamitems"; const char *APP_GET_CAPABILITY = "/app/capability"; const char *APP_GET_LOCK_VIDEO_STATUS = "/app/getlockvideostatus"; const char *APP_GET_STORAGE_INFO = "/app/getstorageinfo"; @@ -72,6 +75,7 @@ SixFrameHandle::SixFrameHandle() mResquesHandleFunc[APP_GET_SD_CARD_INFO] = std::bind(&SixFrameHandle::RequestGetSdCardInfo, this, _1, _2, _3); mResquesHandleFunc[APP_GET_BATTERY_INFO] = std::bind(&SixFrameHandle::RequestGetBatteryInfo, this, _1, _2, _3); mResquesHandleFunc[APP_GET_PARAM_VALUE] = std::bind(&SixFrameHandle::RequestGetParamValue, this, _1, _2, _3); + mResquesHandleFunc[APP_GET_PARAM_ITEMS] = std::bind(&SixFrameHandle::RequestGetParamItems, this, _1, _2, _3); mResquesHandleFunc[APP_GET_CAPABILITY] = std::bind(&SixFrameHandle::RequestGetCapability, this, _1, _2, _3); mResquesHandleFunc[APP_GET_LOCK_VIDEO_STATUS] = std::bind(&SixFrameHandle::RequestGetLockVideoStatus, this, _1, _2, _3); @@ -287,25 +291,38 @@ void inline SixFrameHandle::ResponseGetBatteryInfo(cJSON *result, const AppGetBa cJSON_AddNumberToObject(info, "charge", static_cast(param.mChargeStatus)); cJSON_AddNumberToObject(info, "capacity", param.mCapacity); } -AppParamValue inline SixFrameHandle::RequestParamValueParse(const std::string &url) +void inline SixFrameHandle::RequestParamValueParse(const std::string &url, std::map ¶mList) { auto parseFunc = [](const std::string &key, const std::string &value, std::shared_ptr &parse) { - std::shared_ptr> parseImpl = std::dynamic_pointer_cast>(parse); + std::shared_ptr>> parseImpl = + std::dynamic_pointer_cast>>(parse); + if ("param" == key) { + if ("all" == value) { + parseImpl->mData["all"] = true; // means app want to get all value. + } + } if ("param" == key) { if ("rec" == value) { - parseImpl->mData.mRec = SwitchStatus::ON; // means app want to get mRec value. + parseImpl->mData["rec"] = true; // means app want to get rec value. + } + } + if ("param" == key) { + if ("mic" == value) { + parseImpl->mData["mic"] = true; // means app want to get mic value. } } }; - std::shared_ptr parse = std::make_shared>(); - std::shared_ptr> parseImpl = std::dynamic_pointer_cast>(parse); + std::shared_ptr parse = std::make_shared>>(); + std::shared_ptr>> parseImpl = + std::dynamic_pointer_cast>>(parse); ExtractParamsFromUrl(url, parseFunc, parse); - return parseImpl->mData; + paramList = parseImpl->mData; } void SixFrameHandle::RequestGetParamValue(const std::string &url, ResponseHandle responseHandle, void *context) { LogInfo("RequestGetParamValue.\n"); - // AppParamValue appGetValue = RequestParamValueParse(url); // TODO: + std::map paramList; + RequestParamValueParse(url, paramList); AppParamValue paramDevice; mAppMonitor->GetParamValue(paramDevice); cJSON *result = MakeResponseResult(ResposeResult::SUCCESSFUL); @@ -314,33 +331,144 @@ void SixFrameHandle::RequestGetParamValue(const std::string &url, ResponseHandle responseHandle("Device run out of memory.", context); return; } - ResponseGetParamValue(result, paramDevice); + ResponseGetParamValue(result, paramDevice, paramList); ResponseJsonString(result, responseHandle, context); cJSON_Delete(result); } -void inline SixFrameHandle::ResponseGetParamValue(cJSON *result, const AppParamValue ¶m) +void inline SixFrameHandle::ResponseGetParamValue(cJSON *result, const AppParamValue ¶m, + const std::map ¶mList) { - // cJSON *info = cJSON_CreateArray(); - // if (nullptr == info) { - // LogError("cJSON_CreateArray failed.\n"); - // return; - // } - // cJSON_AddItemToObject(result, CJSON_INFO_STRING, info); - // cJSON *mic = cJSON_CreateObject(); - // if (nullptr != mic) { - // cJSON_AddItemToArray(info, mic); - // cJSON_AddStringToObject(mic, "name", "mic"); - // cJSON_AddNumberToObject(mic, "value", static_cast(param.mMicStatus)); - // } - // cJSON *rec = cJSON_CreateObject(); - // if (nullptr != rec) { - // cJSON_AddItemToArray(info, rec); - // cJSON_AddStringToObject(rec, "name", "rec"); - // cJSON_AddNumberToObject(rec, "value", static_cast(param.mRec)); - // } - cJSON *info = nullptr; - cJSON_AddItemToObject(result, CJSON_INFO_STRING, info = cJSON_CreateObject()); - cJSON_AddNumberToObject(info, "value", static_cast(param.mRec)); + auto it = paramList.find("all"); + if (it != paramList.end()) { + cJSON *info = cJSON_CreateArray(); + if (nullptr == info) { + LogError("cJSON_CreateArray failed.\n"); + return; + } + cJSON_AddItemToObject(result, CJSON_INFO_STRING, info); + cJSON *mic = cJSON_CreateObject(); + if (nullptr != mic) { + cJSON_AddItemToArray(info, mic); + cJSON_AddStringToObject(mic, "name", "mic"); + cJSON_AddNumberToObject(mic, "value", static_cast(param.mMicStatus)); + } + cJSON *rec = cJSON_CreateObject(); + if (nullptr != rec) { + cJSON_AddItemToArray(info, rec); + cJSON_AddStringToObject(rec, "name", "rec"); + cJSON_AddNumberToObject(rec, "value", static_cast(param.mRec)); + } + cJSON *osd = cJSON_CreateObject(); + if (nullptr != osd) { + cJSON_AddItemToArray(info, osd); + cJSON_AddStringToObject(osd, "name", "osd"); + cJSON_AddNumberToObject(osd, "value", 1); + } + } + else { + cJSON *info = nullptr; + cJSON_AddItemToObject(result, CJSON_INFO_STRING, info = cJSON_CreateObject()); + { + auto it = paramList.find("mic"); + if (it != paramList.end()) { + cJSON_AddNumberToObject(info, "value", static_cast(param.mMicStatus)); + return; + } + } + { + auto it = paramList.find("rec"); + if (it != paramList.end()) { + cJSON_AddNumberToObject(info, "value", static_cast(param.mRec)); + return; + } + } + } +} +void SixFrameHandle::RequestGetParamItems(const std::string &url, ResponseHandle responseHandle, void *context) +{ + LogInfo("RequestGetParamItems.\n"); + std::map paramList; + RequestParamValueParse(url, paramList); + AppGetCapability paramDevice; + // mAppMonitor->GetParamValue(paramDevice); + cJSON *result = MakeResponseResult(ResposeResult::SUCCESSFUL); + if (nullptr == result) { + LogError("MakeResponseResult failed.\n"); + responseHandle("Device run out of memory.", context); + return; + } + ResponseGetParamItems(result, paramDevice, paramList); + ResponseJsonString(result, responseHandle, context); + cJSON_Delete(result); +} +void SixFrameHandle::ResponseGetParamItems(cJSON *result, const AppGetCapability ¶m, + const std::map ¶mList) +{ + auto it = paramList.find("all"); + if (it != paramList.end()) { + cJSON *info = cJSON_CreateArray(); + if (nullptr == info) { + LogError("cJSON_CreateArray failed.\n"); + return; + } + cJSON_AddItemToObject(result, CJSON_INFO_STRING, info); + { + cJSON *mic = cJSON_CreateObject(); + cJSON *items = cJSON_CreateArray(); + cJSON *index = cJSON_CreateArray(); + if (nullptr != mic && nullptr != items && nullptr != index) { + cJSON_AddItemToArray(info, mic); + cJSON_AddStringToObject(mic, "name", "mic"); + cJSON_AddItemToObject(mic, CJSON_ITEMS_STRING, items); + cJSON_AddItemToObject(mic, CJSON_INDEX_STRING, index); + cJSON_AddItemToArray(items, cJSON_CreateString("on")); + cJSON_AddItemToArray(items, cJSON_CreateString("off")); + cJSON_AddItemToArray(index, cJSON_CreateNumber(0)); + cJSON_AddItemToArray(index, cJSON_CreateNumber(1)); + } + } + // { + // cJSON *rec = cJSON_CreateObject(); + // cJSON *items = cJSON_CreateArray(); + // cJSON *index = cJSON_CreateArray(); + // if (nullptr != rec && nullptr != items && nullptr != index) { + // cJSON_AddItemToArray(info, rec); + // cJSON_AddStringToObject(rec, "name", "rec"); + // cJSON_AddItemToObject(rec, CJSON_ITEMS_STRING, items); + // cJSON_AddItemToObject(rec, CJSON_INDEX_STRING, index); + // cJSON_AddItemToArray(items, cJSON_CreateString("on")); + // cJSON_AddItemToArray(items, cJSON_CreateString("off")); + // cJSON_AddItemToArray(index, cJSON_CreateNumber(0)); + // cJSON_AddItemToArray(index, cJSON_CreateNumber(1)); + // } + // } + } + else { + cJSON *info = cJSON_CreateObject(); + if (nullptr == info) { + LogError("cJSON_CreateObject failed.\n"); + return; + } + cJSON_AddItemToObject(result, CJSON_INFO_STRING, info); + { + auto it = paramList.find("mic"); + if (it != paramList.end()) { + cJSON *items = cJSON_CreateArray(); + cJSON *index = cJSON_CreateArray(); + if (nullptr == items || nullptr == index) { + LogError("cJSON_CreateArray failed.\n"); + return; + } + cJSON_AddItemToObject(info, CJSON_ITEMS_STRING, items); + cJSON_AddItemToObject(info, CJSON_INDEX_STRING, index); + cJSON_AddItemToArray(items, cJSON_CreateString("on")); + cJSON_AddItemToArray(items, cJSON_CreateString("off")); + cJSON_AddItemToArray(index, cJSON_CreateNumber(0)); + cJSON_AddItemToArray(index, cJSON_CreateNumber(1)); + return; + } + } + } } void SixFrameHandle::RequestGetCapability(const std::string &url, ResponseHandle responseHandle, void *context) { diff --git a/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.h b/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.h index 3d70437..8c4b8e9 100644 --- a/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.h +++ b/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.h @@ -72,9 +72,18 @@ private: void ResponseGetSdCardInfo(cJSON *result, const AppGetSdCardInfo ¶m); void RequestGetBatteryInfo(const std::string &url, ResponseHandle responseHandle, void *context); void ResponseGetBatteryInfo(cJSON *result, const AppGetBatteryInfo ¶m); - AppParamValue RequestParamValueParse(const std::string &url); + /** + * @brief There are many parameters that need to be set for the content that the APP needs to obtain in the protocol + * package, The APP may retrieve all or some of the parameters. + * @param url [in] + * @param paramList [out] + */ + void RequestParamValueParse(const std::string &url, std::map ¶mList); void RequestGetParamValue(const std::string &url, ResponseHandle responseHandle, void *context); - void ResponseGetParamValue(cJSON *result, const AppParamValue ¶m); + void ResponseGetParamValue(cJSON *result, const AppParamValue ¶m, const std::map ¶mList); + void RequestGetParamItems(const std::string &url, ResponseHandle responseHandle, void *context); + void ResponseGetParamItems(cJSON *result, const AppGetCapability ¶m, + const std::map ¶mList); void RequestGetCapability(const std::string &url, ResponseHandle responseHandle, void *context); void ResponseGetCapability(cJSON *result, const AppGetCapability ¶m); void RequestGetLockVideoStatus(const std::string &url, ResponseHandle responseHandle, void *context); diff --git a/middleware/IpcConfig/CMakeLists.txt b/middleware/IpcConfig/CMakeLists.txt index b902352..9bf3c39 100644 --- a/middleware/IpcConfig/CMakeLists.txt +++ b/middleware/IpcConfig/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/Log/include ${UTILS_SOURCE_PATH}/ConfigBase/include + ${UTILS_SOURCE_PATH}/LinuxApi/include ) #do not rely on any other library #link_directories( @@ -20,7 +21,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME IpcConfig) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} ConfigBase StatusCode Log) +target_link_libraries(${TARGET_NAME} LinuxApi ConfigBase StatusCode Log) if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") add_custom_target( diff --git a/middleware/IpcConfig/README.md b/middleware/IpcConfig/README.md index c95f4b2..19e6a53 100644 --- a/middleware/IpcConfig/README.md +++ b/middleware/IpcConfig/README.md @@ -10,6 +10,10 @@ 2. 本库使用结构体保存数据,可拓展不使用第三方开源库,直接保存结构体数据即可;在资源受限时,可动/静态取消第三方开源库; 3. 配置文件明文显示,可加密; +### 1.2.1. 快启加载配置文件 + +  快启的项目当中,可能文件系统并未及时挂载,需要确认文件系统挂载成功之后再去加载配置文件。**因此,为保证应用程序逻辑的严谨性,应用程序在读取数据时,应对出参的变量赋值一个无效的初始值,获取配置参数后,==如果还是默认值代表获取配置参数失败==。** + ## 1.3. 数据丢失还原机制   针对可能发生的数据丢失/损坏,提供数据还原机制。 diff --git a/middleware/IpcConfig/build/ipc_config.cmake b/middleware/IpcConfig/build/ipc_config.cmake index e0db7f9..4666dc8 100644 --- a/middleware/IpcConfig/build/ipc_config.cmake +++ b/middleware/IpcConfig/build/ipc_config.cmake @@ -2,5 +2,11 @@ if (DEFINED IPC_CONFIG_FILE_PATH) add_definitions(-DIPC_CONFIG_FILE_PATH=\"${IPC_CONFIG_FILE_PATH}\") else() - message(FATAL_ERROR "You set define IPC_CONFIG_FILE_PATH in toolchan .cmake file to tell code where to save config file.") + message(FATAL_ERROR "You should set define IPC_CONFIG_FILE_PATH in toolchan.cmake file to tell code where to save config file.") +endif() + +if (DEFINED USERDATA_MOUNT_PATH) + add_definitions(-DUSERDATA_MOUNT_PATH=\"${USERDATA_MOUNT_PATH}\") +else() + message(FATAL_ERROR "You should set define USERDATA_MOUNT_PATH in toolchan.cmake.") endif() \ No newline at end of file diff --git a/middleware/IpcConfig/src/IpcConfigImpl.cpp b/middleware/IpcConfig/src/IpcConfigImpl.cpp index fcc13ee..ad98ff0 100644 --- a/middleware/IpcConfig/src/IpcConfigImpl.cpp +++ b/middleware/IpcConfig/src/IpcConfigImpl.cpp @@ -14,8 +14,12 @@ */ #include "IpcConfigImpl.h" #include "ILog.h" +#include "LinuxApi.h" +#include +#include +#include #include - +#include #define CHECK_MAP(map) (map.size() == 1 ? true : false) const char *CONFIG_WIFI_SSID = "wifi_ssid"; const char *CONFIG_WIFI_SSID_DEFAULT = "Hunting 2024"; @@ -30,69 +34,9 @@ const char *CONFIG_PIR_DELAYED = "pir_delayed"; const char *CONFIG_STORAGE_LOOP = "storage_loop"; const char *CONFIG_INFRARED_POWER = "infrared_power"; const char *CONFIG_PIR_SENSITIVITY = "pir_sensitivity"; -IpcConfigImpl::IpcConfigImpl() +IpcConfigImpl::IpcConfigImpl() : mThreadRuning(false), mCfgChanged(CONFIG_HAS_NOT_CHANGED), mCfg(nullptr) { - mCfgChanged = CONFIG_HAS_NOT_CHANGED; - memset(&mAllData, 0, sizeof(Config_s)); - { - std::map config; - StringConfigPack pack = {WIFI_SSID_BUFF_SIZE, mAllData.mWifiSsid}; - config.insert(std::make_pair(CONFIG_WIFI_SSID, pack)); - mCfgMapStringV2.insert(std::make_pair(IpcConfigKey::WIFI_SSID, config)); - } - { - std::map config; - StringConfigPack pack = {WIFI_PASSWORD_BUFF_SIZE, mAllData.mWifiPassword}; - config.insert(std::make_pair(CONFIG_WIFI_PASSWORD, pack)); - mCfgMapStringV2.insert(std::make_pair(IpcConfigKey::WIFI_PASSWORD, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_WORK_MODE, &mAllData.mWorkMode)); - mCfgMapCharV2.insert(std::make_pair(IpcConfigKey::WORK_MODE, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_INFRARED_POWER, &mAllData.mInfraredPower)); - mCfgMapCharV2.insert(std::make_pair(IpcConfigKey::INFRARED_POWER, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_CONTINUE_SHOT, &mAllData.mContinuousShot)); - mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::CONTINUOUS_SHOT, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_BURST_PHOTO_INTERVAL, &mAllData.mBurstPhotoInterval)); - mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::BURST_PHOTO_INTERVAL, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_IMAGE_SIZE, &mAllData.mImageSize)); - mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::IMGAE_SIZE, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_VIDEO_SIZE, &mAllData.mVideoLength)); - mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::VIDEO_LENGTH, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_PIR_DELAYED, &mAllData.mPirDelayed)); - mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::PIR_DELAYED, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_PIR_SENSITIVITY, &mAllData.mPirSensitivity)); - mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::PIR_SENSITIVITY, config)); - } - { - std::map config; - config.insert(std::make_pair(CONFIG_STORAGE_LOOP, &mAllData.mStorageLoopSwitch)); - mCfgMapBoolV2.insert(std::make_pair(IpcConfigKey::STORAGE_LOOP_SWITCH, config)); - } - // std::map> innerMapWorkMode; // innerMapWorkMode.insert(std::make_pair("work_mode", std::reference_wrapper(mAllData.mWorkMode))); // mCfgMapInt.insert(std::make_pair(IpcConfigKey::WORK_MODE, innerMapWorkMode)); @@ -175,17 +119,28 @@ IpcConfigImpl::IpcConfigImpl() } const StatusCode IpcConfigImpl::Init(void) { - memset(&mAllData, 0, sizeof(Config_s)); - mCfg = OpenConfigFile(IPC_CONFIG_FILE_PATH); - if (nullptr == mCfg) { - LogError("Open config file failed.\n"); - return CreateStatusCode(STATUS_CODE_NOT_OK); - } - ReadAllConfigParameters(); + // memset(&mAllData, 0, sizeof(Config_s)); + // InitConfigMap(); + // mCfg = OpenConfigFile(IPC_CONFIG_FILE_PATH); + // if (nullptr == mCfg) { + // LogError("Open config file failed.\n"); + // return CreateStatusCode(STATUS_CODE_NOT_OK); + // } + // ReadAllConfigParameters(); + auto readingConfig = [](std::shared_ptr impl) { + impl->ReadingConfigThread(); + }; + std::shared_ptr impl = shared_from_this(); + mInitThread = std::thread(readingConfig, impl); return CreateStatusCode(STATUS_CODE_OK); } const StatusCode IpcConfigImpl::UnInit(void) { + mThreadRuning = false; + if (mInitThread.joinable()) { + mInitThread.join(); + } + std::lock_guard locker(mMutex); if (CONFIG_HAS_CHANGED == mCfgChanged) { LogInfo("Save config files.\n"); ConfigSaveFile(mCfg); @@ -195,11 +150,13 @@ const StatusCode IpcConfigImpl::UnInit(void) } const StatusCode IpcConfigImpl::ConfigFileSave(void) { + std::lock_guard locker(mMutex); return ConfigSaveFile(mCfg); } const int IpcConfigImpl::GetInt(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapIntV2.find(key); if (iter != mCfgMapIntV2.end() && CHECK_MAP(iter->second)) { @@ -211,6 +168,7 @@ const int IpcConfigImpl::GetInt(const IpcConfigKey &key) } void IpcConfigImpl::SetInt(const IpcConfigKey &key, const int &value) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapIntV2.find(key); if (iter != mCfgMapIntV2.end() && CHECK_MAP(iter->second)) { @@ -224,6 +182,7 @@ void IpcConfigImpl::SetInt(const IpcConfigKey &key, const int &value) } const short IpcConfigImpl::GetShort(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapShort.find(key); if (iter != mCfgMapShort.end() && CHECK_MAP(iter->second)) { @@ -235,6 +194,7 @@ const short IpcConfigImpl::GetShort(const IpcConfigKey &key) } void IpcConfigImpl::SetShort(const IpcConfigKey &key, const short &value) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapShort.find(key); if (iter != mCfgMapShort.end() && CHECK_MAP(iter->second)) { @@ -249,6 +209,7 @@ void IpcConfigImpl::SetShort(const IpcConfigKey &key, const short &value) } const long IpcConfigImpl::GetLong(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapLong.find(key); if (iter != mCfgMapLong.end() && CHECK_MAP(iter->second)) { @@ -260,6 +221,7 @@ const long IpcConfigImpl::GetLong(const IpcConfigKey &key) } void IpcConfigImpl::SetLong(const IpcConfigKey &key, const long &value) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapLong.find(key); if (iter != mCfgMapLong.end() && CHECK_MAP(iter->second)) { @@ -274,6 +236,7 @@ void IpcConfigImpl::SetLong(const IpcConfigKey &key, const long &value) } const long long IpcConfigImpl::GetLLong(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapLLong.find(key); if (iter != mCfgMapLLong.end() && CHECK_MAP(iter->second)) { @@ -285,6 +248,7 @@ const long long IpcConfigImpl::GetLLong(const IpcConfigKey &key) } void IpcConfigImpl::SetLLong(const IpcConfigKey &key, const long long &value) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapLLong.find(key); if (iter != mCfgMapLLong.end() && CHECK_MAP(iter->second)) { @@ -299,6 +263,7 @@ void IpcConfigImpl::SetLLong(const IpcConfigKey &key, const long long &value) } const char IpcConfigImpl::GetChar(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapCharV2.find(key); if (iter != mCfgMapCharV2.end() && CHECK_MAP(iter->second)) { @@ -310,6 +275,7 @@ const char IpcConfigImpl::GetChar(const IpcConfigKey &key) } void IpcConfigImpl::SetChar(const IpcConfigKey &key, const char &character) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapCharV2.find(key); if (iter != mCfgMapCharV2.end() && CHECK_MAP(iter->second)) { @@ -324,6 +290,7 @@ void IpcConfigImpl::SetChar(const IpcConfigKey &key, const char &character) } const float IpcConfigImpl::GetFloat(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapFloat.find(key); if (iter != mCfgMapFloat.end() && CHECK_MAP(iter->second)) { @@ -335,6 +302,7 @@ const float IpcConfigImpl::GetFloat(const IpcConfigKey &key) } void IpcConfigImpl::SetFloat(const IpcConfigKey &key, const float &value) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapFloat.find(key); if (iter != mCfgMapFloat.end() && CHECK_MAP(iter->second)) { @@ -349,6 +317,7 @@ void IpcConfigImpl::SetFloat(const IpcConfigKey &key, const float &value) } const double IpcConfigImpl::GetDouble(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapDouble.find(key); if (iter != mCfgMapDouble.end() && CHECK_MAP(iter->second)) { @@ -360,6 +329,7 @@ const double IpcConfigImpl::GetDouble(const IpcConfigKey &key) } void IpcConfigImpl::SetDouble(const IpcConfigKey &key, const double &value) { + std::lock_guard locker(mMutex); std::map>>::iterator iter; iter = mCfgMapDouble.find(key); if (iter != mCfgMapDouble.end() && CHECK_MAP(iter->second)) { @@ -374,6 +344,7 @@ void IpcConfigImpl::SetDouble(const IpcConfigKey &key, const double &value) } const long double IpcConfigImpl::GetLongDouble(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapLongDouble.find(key); if (iter != mCfgMapLongDouble.end()) { @@ -385,6 +356,7 @@ const long double IpcConfigImpl::GetLongDouble(const IpcConfigKey &key) } void IpcConfigImpl::SetLongDouble(const IpcConfigKey &key, const long double &value) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapLongDouble.find(key); if (iter != mCfgMapLongDouble.end()) { @@ -397,6 +369,7 @@ void IpcConfigImpl::SetLongDouble(const IpcConfigKey &key, const long double &va } const bool IpcConfigImpl::GetBool(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapBoolV2.find(key); if (iter != mCfgMapBoolV2.end() && CHECK_MAP(iter->second)) { @@ -408,6 +381,7 @@ const bool IpcConfigImpl::GetBool(const IpcConfigKey &key) } void IpcConfigImpl::SetBool(const IpcConfigKey &key, const bool &value) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapBoolV2.find(key); if (iter != mCfgMapBoolV2.end() && CHECK_MAP(iter->second)) { @@ -421,6 +395,7 @@ void IpcConfigImpl::SetBool(const IpcConfigKey &key, const bool &value) } const std::string IpcConfigImpl::GetString(const IpcConfigKey &key) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapStringV2.find(key); if (iter != mCfgMapStringV2.end() && CHECK_MAP(iter->second)) { @@ -433,6 +408,7 @@ const std::string IpcConfigImpl::GetString(const IpcConfigKey &key) } void IpcConfigImpl::SetString(const IpcConfigKey &key, const std::string &string) { + std::lock_guard locker(mMutex); std::map>::iterator iter; iter = mCfgMapStringV2.find(key); if (iter != mCfgMapStringV2.end() && CHECK_MAP(iter->second)) { @@ -478,6 +454,98 @@ void IpcConfigImpl::SetLevel(const IpcConfigKey &key, const ConfigLevel &value) char config = static_cast(value); SetChar(key, config); } +void IpcConfigImpl::ReadingConfigThread(void) +{ + constexpr int DIR_PATH_LENGTH = 32; + char dirPath[DIR_PATH_LENGTH] = {0}; + strncpy(dirPath, IPC_CONFIG_FILE_PATH, DIR_PATH_LENGTH - 1); + char *lastSlash = strrchr(dirPath, '/'); + if (lastSlash == nullptr) { + strcpy(dirPath, "."); + } + else { + *lastSlash = '\0'; + } + mThreadRuning = true; + LogInfo("Reading config thread is running, dirPath = %s\n", dirPath); + while (mThreadRuning) { + if (CheckConfigPathMounted() == true) { + memset(&mAllData, 0, sizeof(Config_s)); + mCfg = OpenConfigFile(IPC_CONFIG_FILE_PATH); + if (nullptr == mCfg) { + LogError("Open config file failed.\n"); + continue; + } + std::lock_guard locker(mMutex); + InitConfigMap(); + ReadAllConfigParameters(); + LogInfo("Read config file success.\n"); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + mThreadRuning = false; +} +void IpcConfigImpl::InitConfigMap(void) +{ + { + std::map config; + StringConfigPack pack = {WIFI_SSID_BUFF_SIZE, mAllData.mWifiSsid}; + config.insert(std::make_pair(CONFIG_WIFI_SSID, pack)); + mCfgMapStringV2.insert(std::make_pair(IpcConfigKey::WIFI_SSID, config)); + } + { + std::map config; + StringConfigPack pack = {WIFI_PASSWORD_BUFF_SIZE, mAllData.mWifiPassword}; + config.insert(std::make_pair(CONFIG_WIFI_PASSWORD, pack)); + mCfgMapStringV2.insert(std::make_pair(IpcConfigKey::WIFI_PASSWORD, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_WORK_MODE, &mAllData.mWorkMode)); + mCfgMapCharV2.insert(std::make_pair(IpcConfigKey::WORK_MODE, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_INFRARED_POWER, &mAllData.mInfraredPower)); + mCfgMapCharV2.insert(std::make_pair(IpcConfigKey::INFRARED_POWER, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_CONTINUE_SHOT, &mAllData.mContinuousShot)); + mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::CONTINUOUS_SHOT, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_BURST_PHOTO_INTERVAL, &mAllData.mBurstPhotoInterval)); + mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::BURST_PHOTO_INTERVAL, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_IMAGE_SIZE, &mAllData.mImageSize)); + mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::IMGAE_SIZE, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_VIDEO_SIZE, &mAllData.mVideoLength)); + mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::VIDEO_LENGTH, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_PIR_DELAYED, &mAllData.mPirDelayed)); + mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::PIR_DELAYED, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_PIR_SENSITIVITY, &mAllData.mPirSensitivity)); + mCfgMapIntV2.insert(std::make_pair(IpcConfigKey::PIR_SENSITIVITY, config)); + } + { + std::map config; + config.insert(std::make_pair(CONFIG_STORAGE_LOOP, &mAllData.mStorageLoopSwitch)); + mCfgMapBoolV2.insert(std::make_pair(IpcConfigKey::STORAGE_LOOP_SWITCH, config)); + } +} void IpcConfigImpl::ReadAllConfigParameters(void) { { @@ -805,9 +873,34 @@ void IpcConfigImpl::ReadAllConfigParameters(void) // ConfigSetFloat(mCfg, "test_float", mAllData.testFloat); // } - // if (CONFIG_HAS_CHANGED == mCfgChanged) { - // LogInfo("Save the config file.\n"); - // mCfgChanged = CONFIG_HAS_NOT_CHANGED; - // ConfigSaveFile(mCfg); - // } + if (CONFIG_HAS_CHANGED == mCfgChanged) { + LogInfo("Save the config file.\n"); + mCfgChanged = CONFIG_HAS_NOT_CHANGED; + ConfigSaveFile(mCfg); + } +} +const char *SYSTEM_MOUNTED_FILE = "/proc/mounts"; +bool IpcConfigImpl::CheckConfigPathMounted(void) +{ + FILE *fp = nullptr; + char line[1024]; + char mount_point[1024] = {0}; + + fp = fx_fopen(SYSTEM_MOUNTED_FILE, "r"); + if (fp == nullptr) { + perror("Error opening /proc/mounts"); + return false; + } + + while (fgets(line, sizeof(line), fp) != nullptr) { + if (sscanf(line, "%*s %1023s %*s %*s %*d %*d\n", mount_point) == 1) { + // LogInfo("mount_point: %s\n", mount_point); + if (strcmp(USERDATA_MOUNT_PATH, mount_point) == 0) { + fclose(fp); + return true; // mounted + } + } + } + fclose(fp); + return false; // unmounted } diff --git a/middleware/IpcConfig/src/IpcConfigImpl.h b/middleware/IpcConfig/src/IpcConfigImpl.h index 0f82ba6..6c44334 100644 --- a/middleware/IpcConfig/src/IpcConfigImpl.h +++ b/middleware/IpcConfig/src/IpcConfigImpl.h @@ -19,6 +19,8 @@ #include "StatusCode.h" #include #include +#include +#include constexpr bool CONFIG_HAS_CHANGED = true; constexpr bool CONFIG_HAS_NOT_CHANGED = false; constexpr unsigned int WIFI_SSID_BUFF_SIZE = 64; @@ -71,7 +73,7 @@ public: MapInt() = default; ~MapInt() = default; }; -class IpcConfigImpl : public IIpcConfig +class IpcConfigImpl : public IIpcConfig, public std::enable_shared_from_this { public: IpcConfigImpl(); @@ -107,11 +109,17 @@ public: void SetLevel(const IpcConfigKey &key, const ConfigLevel &value) override; private: + void ReadingConfigThread(void); + void InitConfigMap(void); void ReadAllConfigParameters(void); + virtual bool CheckConfigPathMounted(void); private: + std::mutex mMutex; + bool mThreadRuning = false; + std::thread mInitThread; bool mCfgChanged; - void *mCfg; + void *mCfg = nullptr; Config_s mAllData; std::map>> mCfgMapInt; std::map> mCfgMapIntV2; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3967676..cbd8e4c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,6 +27,7 @@ if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_write" CACHE STRING INTERNAL FORCE) set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_read" CACHE STRING INTERNAL FORCE) set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_access" CACHE STRING INTERNAL FORCE) + set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_fopen" CACHE STRING INTERNAL FORCE) endif() # Mock Linux api. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}") diff --git a/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp b/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp index 830bcea..8d0ad3c 100644 --- a/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp +++ b/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp @@ -123,7 +123,7 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_AUTO_GetParamValue) MainThread::GetInstance()->Init(); TestManager::ResetTimeOut(1000 * 3); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - MockGetParamValue(); + MockGetParamValue("all"); MainThread::GetInstance()->Runing(); } // ../output_files/test/bin/HuntingCameraTest diff --git a/test/middleware/AppManager/src/AppManager_Test.cpp b/test/middleware/AppManager/src/AppManager_Test.cpp index ffb1b75..f65bc77 100644 --- a/test/middleware/AppManager/src/AppManager_Test.cpp +++ b/test/middleware/AppManager/src/AppManager_Test.cpp @@ -173,7 +173,43 @@ TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamValue) IAppManager::GetInstance()->Init(mAppParam); IAppManager::GetInstance()->SetAppMonitor(monitor); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - AppManagerTestTool::MockGetParamValue(); + AppManagerTestTool::MockGetParamValue("all"); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + IAppManager::GetInstance()->UnInit(); +} +// ../output_files/test/bin/AppManagerTest +// --gtest_filter=AppManagerTest.INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamValue2 +TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamValue2) +{ + std::shared_ptr monitor = AppManagerTestTool::MakeMonitorMock(); + IAppManager::GetInstance()->Init(mAppParam); + IAppManager::GetInstance()->SetAppMonitor(monitor); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + AppManagerTestTool::MockGetParamValue("rec"); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + IAppManager::GetInstance()->UnInit(); +} +// ../output_files/test/bin/AppManagerTest +// --gtest_filter=AppManagerTest.INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamItems +TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamItems) +{ + std::shared_ptr monitor = AppManagerTestTool::MakeMonitorMock(); + IAppManager::GetInstance()->Init(mAppParam); + IAppManager::GetInstance()->SetAppMonitor(monitor); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + AppManagerTestTool::MockGetParamItems("all"); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + IAppManager::GetInstance()->UnInit(); +} +// ../output_files/test/bin/AppManagerTest +// --gtest_filter=AppManagerTest.INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamItems2 +TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_AUTO_GetParamItems2) +{ + std::shared_ptr monitor = AppManagerTestTool::MakeMonitorMock(); + IAppManager::GetInstance()->Init(mAppParam); + IAppManager::GetInstance()->SetAppMonitor(monitor); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + AppManagerTestTool::MockGetParamItems("mic"); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); IAppManager::GetInstance()->UnInit(); } diff --git a/test/middleware/AppManager/tool/include/AppManagerTestTool.h b/test/middleware/AppManager/tool/include/AppManagerTestTool.h index 3889ecf..7031bc0 100644 --- a/test/middleware/AppManager/tool/include/AppManagerTestTool.h +++ b/test/middleware/AppManager/tool/include/AppManagerTestTool.h @@ -34,7 +34,8 @@ protected: // About http void MockSetDateTime(void); void MockSetTimeZone(void); void MockUploadFiles(void); - void MockGetParamValue(void); + void MockGetParamValue(const std::string ¶mName); + void MockGetParamItems(const std::string ¶mName); void MockGetCapability(void); void MockGetLockVideoStatus(void); void MockGetStorageInfo(void); diff --git a/test/middleware/AppManager/tool/src/AppManagerTestTool.cpp b/test/middleware/AppManager/tool/src/AppManagerTestTool.cpp index bbc9d65..fda61f5 100644 --- a/test/middleware/AppManager/tool/src/AppManagerTestTool.cpp +++ b/test/middleware/AppManager/tool/src/AppManagerTestTool.cpp @@ -122,7 +122,7 @@ void AppManagerTestTool::MockUploadFiles(void) } ServersMock::GetInstance()->MockUploadFiles(); } -void AppManagerTestTool::MockGetParamValue(void) +void AppManagerTestTool::MockGetParamValue(const std::string ¶mName) { std::shared_ptr mock = std::dynamic_pointer_cast(mAppMonitorMock); if (mock) { @@ -130,7 +130,17 @@ void AppManagerTestTool::MockGetParamValue(void) .Times(ONLY_BE_CALLED_ONCE) .WillOnce(DoAll(Return(CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION)))); } - ServersMock::GetInstance()->MockGetParamValue(); + ServersMock::GetInstance()->MockGetParamValue(paramName); +} +void AppManagerTestTool::MockGetParamItems(const std::string ¶mName) +{ + // std::shared_ptr mock = std::dynamic_pointer_cast(mAppMonitorMock); + // if (mock) { + // EXPECT_CALL(*mock.get(), GetParamValueTrace(_)) // TODO: + // .Times(ONLY_BE_CALLED_ONCE) + // .WillOnce(DoAll(Return(CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION)))); + // } + ServersMock::GetInstance()->MockGetParamItems(paramName); } void AppManagerTestTool::MockGetCapability(void) { diff --git a/test/middleware/AppManager/tool/src/ServersMock.cpp b/test/middleware/AppManager/tool/src/ServersMock.cpp index 2d2bd71..d703e15 100644 --- a/test/middleware/AppManager/tool/src/ServersMock.cpp +++ b/test/middleware/AppManager/tool/src/ServersMock.cpp @@ -22,6 +22,7 @@ extern const char *APP_GET_MEDIA_INFO; extern const char *APP_GET_SD_CARD_INFO; extern const char *APP_GET_BATTERY_INFO; extern const char *APP_GET_PARAM_VALUE; +extern const char *APP_GET_PARAM_ITEMS; extern const char *APP_GET_CAPABILITY; extern const char *APP_GET_LOCK_VIDEO_STATUS; extern const char *APP_GET_STORAGE_INFO; @@ -65,256 +66,97 @@ void ServersMock::MockGetProductInfo(void) { LogInfo("APP_GET_PRODUCT_INFO test start.\n"); std::string mockRequest = mServerUrl + APP_GET_PRODUCT_INFO; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetDeviceAttr(void) { LogInfo("APP_GET_DEVICE_ATTR test start.\n"); std::string mockRequest = mServerUrl + APP_GET_DEVICE_ATTR; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetMediaInfo(void) { LogInfo("APP_GET_MEDIA_INFO test start.\n"); std::string mockRequest = mServerUrl + APP_GET_MEDIA_INFO; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetSdCardInfo(void) { LogInfo("APP_GET_SD_CARD_INFO test start.\n"); std::string mockRequest = mServerUrl + APP_GET_SD_CARD_INFO; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetBatteryInfo(void) { LogInfo("APP_GET_BATTERY_INFO test start.\n"); std::string mockRequest = mServerUrl + APP_GET_BATTERY_INFO; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } -void ServersMock::MockGetParamValue(void) +void ServersMock::MockGetParamValue(const std::string ¶mName) { LogInfo("APP_GET_PARAM_VALUE test start.\n"); - std::string mockRequest = mServerUrl + APP_GET_PARAM_VALUE; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + std::string mockRequest = mServerUrl + APP_GET_PARAM_VALUE + "?param=" + paramName; + MockHttpGet(mockRequest); +} +void ServersMock::MockGetParamItems(const std::string ¶mName) +{ + LogInfo("APP_GET_PARAM_ITEMS test start.\n"); + std::string mockRequest = mServerUrl + APP_GET_PARAM_ITEMS + "?param=" + paramName; + MockHttpGet(mockRequest); } void ServersMock::MockGetCapability(void) { LogInfo("APP_GET_CAPABILITY test start.\n"); std::string mockRequest = mServerUrl + APP_GET_CAPABILITY; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetLockVideoStatus(void) { LogInfo("APP_GET_LOCK_VIDEO_STATUS test start.\n"); std::string mockRequest = mServerUrl + APP_GET_LOCK_VIDEO_STATUS; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetStorageInfo(void) { LogInfo("APP_GET_STORAGE_INFO test start.\n"); std::string mockRequest = mServerUrl + APP_GET_STORAGE_INFO; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockGetStorageFileList(void) { LogInfo("APP_GET_FILE_LIST test start.\n"); std::string mockRequest = mServerUrl + APP_GET_FILE_LIST + "?folder=loop&start=0&end=99"; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockSetDateTime(void) { LogInfo("APP_SET_DATE_TIME test start.\n"); std::string mockRequest = mServerUrl + APP_SET_DATE_TIME + "?date=20240101010101"; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockSetTimeZone(void) { LogInfo("APP_SET_TIME_ZONE test start.\n"); std::string mockRequest = mServerUrl + APP_SET_TIME_ZONE + "?timezone=8"; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockSetParamValue(void) { LogInfo("APP_SET_PARAM_VALUE test start.\n"); std::string mockRequest = mServerUrl + APP_SET_PARAM_VALUE + "?param=switchcam&value=1"; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockEnterRecorder(void) { LogInfo("APP_ENTER_RECORDER test start.\n"); std::string mockRequest = mServerUrl + APP_ENTER_RECORDER + "?timezone=8"; // TODO: - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } void ServersMock::MockAppPlayback(void) { LogInfo("APP_PLAYBACK test start.\n"); std::string mockRequest = mServerUrl + APP_PLAYBACK + "?param=enter"; - ServerHttp *http = NewServersHttp(mockRequest.c_str()); - if (http) { - HttpGet(http); - if (http->reply) { - char *replyStr = (char *)malloc(http->replyLength + 1); - memset(replyStr, 0, http->replyLength + 1); - memcpy(replyStr, http->reply, http->replyLength); - LogInfo("HttpGet response :\n%s\n", replyStr); - free(replyStr); - } - DeleteServersHttp(http); - } + MockHttpGet(mockRequest); } #ifndef PLATFORM_PATH #error Add the code in your linux.toolchain.cmake : add_definitions(-DPLATFORM_PATH="${PLATFORM_PATH}") @@ -337,4 +179,22 @@ void ServersMock::MockUploadFiles(void) } DeleteServersHttp(http); } +} +void ServersMock::MockHttpGet(const std::string &mockRequest) +{ + ServerHttp *http = NewServersHttp(mockRequest.c_str()); + if (http) { + HttpGet(http); + if (http->reply) { + char *replyStr = (char *)malloc(http->replyLength + 1); + memset(replyStr, 0, http->replyLength + 1); + memcpy(replyStr, http->reply, http->replyLength); + LogInfo("HttpGet response :\n%s\n", replyStr); + free(replyStr); + } + DeleteServersHttp(http); + } + else { + LogWarning("http is null.\n"); + } } \ No newline at end of file diff --git a/test/middleware/AppManager/tool/src/ServersMock.h b/test/middleware/AppManager/tool/src/ServersMock.h index 14963ec..112a3fa 100644 --- a/test/middleware/AppManager/tool/src/ServersMock.h +++ b/test/middleware/AppManager/tool/src/ServersMock.h @@ -14,6 +14,7 @@ */ #ifndef SERVERS_MOCK_H #define SERVERS_MOCK_H +#include "servers.h" #include class ServersMock { @@ -28,7 +29,8 @@ public: virtual void MockGetMediaInfo(void); virtual void MockGetSdCardInfo(void); virtual void MockGetBatteryInfo(void); - virtual void MockGetParamValue(void); + virtual void MockGetParamValue(const std::string ¶mName); + virtual void MockGetParamItems(const std::string ¶mName); virtual void MockGetCapability(void); virtual void MockGetLockVideoStatus(void); virtual void MockGetStorageInfo(void); @@ -40,6 +42,9 @@ public: virtual void MockAppPlayback(void); virtual void MockUploadFiles(void); +private: + void MockHttpGet(const std::string &mockRequest); + private: std::string mServerUrl; }; diff --git a/test/middleware/IpcConfig/CMakeLists.txt b/test/middleware/IpcConfig/CMakeLists.txt index 36b234e..95b6640 100644 --- a/test/middleware/IpcConfig/CMakeLists.txt +++ b/test/middleware/IpcConfig/CMakeLists.txt @@ -13,6 +13,9 @@ include_directories( ${UTILS_SOURCE_PATH}/ConfigBase/include ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/include ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/src + ${TEST_SOURCE_PATH} + ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool/include + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include ) @@ -24,10 +27,13 @@ link_directories( aux_source_directory(. SRC_FILES_MAIN) aux_source_directory(./src SRC_FILES) +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + aux_source_directory(./src_mock SRC_FILES) +endif() set(TARGET_NAME IpcConfigTest) add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} IpcConfig LinuxApi gtest gmock pthread) +target_link_libraries(${TARGET_NAME} IpcConfigTestTool LinuxApi gtest gmock pthread) if(${TEST_COVERAGE} MATCHES "true") target_link_libraries(${TARGET_NAME} gcov) endif() @@ -69,4 +75,8 @@ add_custom_command( ) endif() -define_file_name(${TARGET_NAME}) \ No newline at end of file +define_file_name(${TARGET_NAME}) + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tool/CMakeLists.txt") + add_subdirectory(tool) +endif() \ No newline at end of file diff --git a/test/middleware/IpcConfig/src/IpcConfig_Test.cpp b/test/middleware/IpcConfig/src/IpcConfig_Test.cpp index f26140e..9831828 100644 --- a/test/middleware/IpcConfig/src/IpcConfig_Test.cpp +++ b/test/middleware/IpcConfig/src/IpcConfig_Test.cpp @@ -1,11 +1,23 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "IIpcConfig.h" #include "ILog.h" #include "IpcConfigImpl.h" #include "LinuxApi.h" // #include #include -extern const char *CONFIG_WIFI_SSID_DEFAULT; -extern const char *CONFIG_WIFI_PASSWORD_DEFAULT; namespace IpcConfigTest { // ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigDemo.Demo @@ -15,6 +27,7 @@ TEST(IpcConfigDemo, Demo) CreateIpcConfigModule(); ILogInit(LOG_INSTANCE_TYPE_END); IIpcConfig::GetInstance()->Init(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); const int workMode = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::WORK_MODE); LogInfo("Get workMode = %d\n", workMode); @@ -109,187 +122,7 @@ TEST(IpcConfigDemo, Demo) IIpcConfig::GetInstance()->ConfigFileSave(); IIpcConfig::GetInstance()->UnInit(); ILogUnInit(); + DestroyIpcConfigModule(); DestroyLogModule(); } -class IpcConfigTest : public testing::Test -{ -public: - IpcConfigTest() - { - } - virtual ~IpcConfigTest() - { - } - static void SetUpTestCase() - { - ILogInit(LOG_INSTANCE_TYPE_END); - CreateLogModule(); - } - static void TearDownTestCase() - { - ILogUnInit(); - DestroyLogModule(); - } - virtual void SetUp() - { - CreateIpcConfigModule(); - IIpcConfig::GetInstance()->Init(); - } - virtual void TearDown() - { - IIpcConfig::GetInstance()->UnInit(); - DestroyIpcConfigModule(); - RemoveConfigFile(); - } - -private: - void RemoveConfigFile(void) - { - constexpr int FIEL_EXIST = 0; - if (FIEL_EXIST == access(IPC_CONFIG_FILE_PATH, F_OK)) { - constexpr int BUFF_SIZE = 128; - char cmd[BUFF_SIZE] = {0}; - snprintf(cmd, BUFF_SIZE, "rm -f %s", IPC_CONFIG_FILE_PATH); - fx_system(cmd); - } - } -}; -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiSsid -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiSsid) -{ - const char *MODIFIED_STRING = "modified_string"; - const char *MODIFIED_STRING_SHORTER = "modified"; - const char *LONG_STRING = - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; - std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - LogInfo("Get wifi ssid = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), CONFIG_WIFI_SSID_DEFAULT); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - LogInfo("Get wifiSsid = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, LONG_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, ""); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), ""); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING_SHORTER); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiPassword -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiPassword) -{ - const char *MODIFIED_STRING = "99999999"; - const char *MODIFIED_STRING_SHORTER = "999"; - const char *LONG_STRING = - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; - std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - LogInfo("Get wifi password = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), CONFIG_WIFI_PASSWORD_DEFAULT); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - LogInfo("Get wifi password = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, LONG_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, ""); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), ""); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING_SHORTER); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WorkMode -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WorkMode) -{ - WorkMode config = IIpcConfig::GetInstance()->GetWorkMode(); - EXPECT_EQ(static_cast(config), static_cast(CONFIG_WORK_MODE_DEFAULT)); - IIpcConfig::GetInstance()->SetWorkMode(WorkMode::MODE_PIC_VIDEO); - config = IIpcConfig::GetInstance()->GetWorkMode(); - EXPECT_EQ(static_cast(config), static_cast(WorkMode::MODE_PIC_VIDEO)); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ContinueShot -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ContinueShot) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); - EXPECT_EQ(config, CONFIG_CONTINUE_SHOT_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::CONTINUOUS_SHOT, 2); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); - EXPECT_EQ(config, 2); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); - EXPECT_EQ(config, CONFIG_BURST_PHOTO_INTERVAL_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::BURST_PHOTO_INTERVAL, 10); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); - EXPECT_EQ(config, 10); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ImageSize -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ImageSize) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); - EXPECT_EQ(config, CONFIG_IMAGE_SIZE_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::IMGAE_SIZE, 16); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); - EXPECT_EQ(config, 16); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_VideoLength -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_VideoLength) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); - EXPECT_EQ(config, CONFIG_VIDEO_SIZE_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::VIDEO_LENGTH, 15); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); - EXPECT_EQ(config, 15); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirDelayed -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirDelayed) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); - EXPECT_EQ(config, CONFIG_PIR_DELAYED_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_DELAYED, 15); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); - EXPECT_EQ(config, 15); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_StorageLoop -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_StorageLoop) -{ - ConfigSwitch config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); - EXPECT_EQ(static_cast(config), - static_cast(CONFIG_STORAGE_LOOP_DEFAULT == true ? ConfigSwitch::ON : ConfigSwitch::OFF)); - IIpcConfig::GetInstance()->SetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH, ConfigSwitch::OFF); - config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); - EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_InfraredPower -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_InfraredPower) -{ - ConfigLevel config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); - EXPECT_EQ(static_cast(config), static_cast(CONFIG_INFRARED_POWER_DEFAULT)); - IIpcConfig::GetInstance()->SetLevel(IpcConfigKey::INFRARED_POWER, ConfigLevel::HIGHT); - config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); - EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); - EXPECT_EQ(config, CONFIG_PIR_SENSITIVITY_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_SENSITIVITY, 0); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); - EXPECT_EQ(config, 0); -} } // namespace IpcConfigTest \ No newline at end of file diff --git a/test/middleware/IpcConfig/src_mock/IpcConfigTest.cpp b/test/middleware/IpcConfig/src_mock/IpcConfigTest.cpp new file mode 100644 index 0000000..cf4b85e --- /dev/null +++ b/test/middleware/IpcConfig/src_mock/IpcConfigTest.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IpcConfigTest.h" +#include "IIpcConfig.h" +#include "ILog.h" +#include "LinuxApi.h" +#include +IpcConfigTest::IpcConfigTest() +{ +} +IpcConfigTest::~IpcConfigTest() +{ +} +void IpcConfigTest::SetUpTestCase() +{ + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); +} +void IpcConfigTest::TearDownTestCase() +{ + ILogUnInit(); + DestroyLogModule(); +} +void IpcConfigTest::SetUp() +{ + mLinuxTest = LinuxTest::CreateLinuxTest(); + std::shared_ptr test = mLinuxTest; + LinuxApiMock::GetInstance(&test); + IpcConfigTestTool::Init(mLinuxTest); + CreateIpcConfigModule(); + IIpcConfig::GetInstance()->Init(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); +} +void IpcConfigTest::TearDown() +{ + IIpcConfig::GetInstance()->UnInit(); + DestroyIpcConfigModule(); + RemoveConfigFile(); + IpcConfigTestTool::UnInit(); + mLinuxTest = std::make_shared(); + std::shared_ptr test = std::make_shared(); + LinuxApiMock::GetInstance(&test); +} +void IpcConfigTest::RemoveConfigFile(void) +{ + constexpr int FIEL_EXIST = 0; + if (FIEL_EXIST == access(IPC_CONFIG_FILE_PATH, F_OK)) { + constexpr int BUFF_SIZE = 128; + char cmd[BUFF_SIZE] = {0}; + snprintf(cmd, BUFF_SIZE, "rm -f %s", IPC_CONFIG_FILE_PATH); + fx_system(cmd); + } +} \ No newline at end of file diff --git a/test/middleware/IpcConfig/src_mock/IpcConfigTest.h b/test/middleware/IpcConfig/src_mock/IpcConfigTest.h new file mode 100644 index 0000000..6a050d8 --- /dev/null +++ b/test/middleware/IpcConfig/src_mock/IpcConfigTest.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IPC_CONFIG_TEST_H +#define IPC_CONFIG_TEST_H +#include "GtestUsing.h" +#include "IpcConfigTestTool.h" +class IpcConfigTest : public testing::Test, public IpcConfigTestTool +{ +public: + IpcConfigTest(); + virtual ~IpcConfigTest(); + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp(); + virtual void TearDown(); + +private: + void RemoveConfigFile(void); + +public: + std::shared_ptr mLinuxTest; +}; +#endif \ No newline at end of file diff --git a/test/middleware/IpcConfig/src_mock/IpcConfig_Mock_Test.cpp b/test/middleware/IpcConfig/src_mock/IpcConfig_Mock_Test.cpp new file mode 100644 index 0000000..ef0b2ba --- /dev/null +++ b/test/middleware/IpcConfig/src_mock/IpcConfig_Mock_Test.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IpcConfigTest.h" +#include "IIpcConfig.h" +#include "ILog.h" +#include "IpcConfigImpl.h" +extern const char *CONFIG_WIFI_SSID_DEFAULT; +extern const char *CONFIG_WIFI_PASSWORD_DEFAULT; +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiSsid +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiSsid) +{ + const char *MODIFIED_STRING = "modified_string"; + const char *MODIFIED_STRING_SHORTER = "modified"; + const char *LONG_STRING = + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; + std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + LogInfo("Get wifi ssid = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), CONFIG_WIFI_SSID_DEFAULT); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + LogInfo("Get wifiSsid = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, LONG_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, ""); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), ""); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING_SHORTER); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiPassword +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiPassword) +{ + const char *MODIFIED_STRING = "99999999"; + const char *MODIFIED_STRING_SHORTER = "999"; + const char *LONG_STRING = + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; + std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + LogInfo("Get wifi password = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), CONFIG_WIFI_PASSWORD_DEFAULT); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + LogInfo("Get wifi password = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, LONG_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, ""); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), ""); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING_SHORTER); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WorkMode +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WorkMode) +{ + WorkMode config = IIpcConfig::GetInstance()->GetWorkMode(); + EXPECT_EQ(static_cast(config), static_cast(CONFIG_WORK_MODE_DEFAULT)); + IIpcConfig::GetInstance()->SetWorkMode(WorkMode::MODE_PIC_VIDEO); + config = IIpcConfig::GetInstance()->GetWorkMode(); + EXPECT_EQ(static_cast(config), static_cast(WorkMode::MODE_PIC_VIDEO)); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ContinueShot +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ContinueShot) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); + EXPECT_EQ(config, CONFIG_CONTINUE_SHOT_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::CONTINUOUS_SHOT, 2); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); + EXPECT_EQ(config, 2); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); + EXPECT_EQ(config, CONFIG_BURST_PHOTO_INTERVAL_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::BURST_PHOTO_INTERVAL, 10); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); + EXPECT_EQ(config, 10); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ImageSize +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ImageSize) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); + EXPECT_EQ(config, CONFIG_IMAGE_SIZE_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::IMGAE_SIZE, 16); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); + EXPECT_EQ(config, 16); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_VideoLength +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_VideoLength) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); + EXPECT_EQ(config, CONFIG_VIDEO_SIZE_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::VIDEO_LENGTH, 15); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); + EXPECT_EQ(config, 15); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirDelayed +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirDelayed) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); + EXPECT_EQ(config, CONFIG_PIR_DELAYED_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_DELAYED, 15); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); + EXPECT_EQ(config, 15); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_StorageLoop +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_StorageLoop) +{ + ConfigSwitch config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); + EXPECT_EQ(static_cast(config), + static_cast(CONFIG_STORAGE_LOOP_DEFAULT == true ? ConfigSwitch::ON : ConfigSwitch::OFF)); + IIpcConfig::GetInstance()->SetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH, ConfigSwitch::OFF); + config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); + EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_InfraredPower +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_InfraredPower) +{ + ConfigLevel config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); + EXPECT_EQ(static_cast(config), static_cast(CONFIG_INFRARED_POWER_DEFAULT)); + IIpcConfig::GetInstance()->SetLevel(IpcConfigKey::INFRARED_POWER, ConfigLevel::HIGHT); + config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); + EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); + EXPECT_EQ(config, CONFIG_PIR_SENSITIVITY_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_SENSITIVITY, 0); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); + EXPECT_EQ(config, 0); +} \ No newline at end of file diff --git a/test/middleware/IpcConfig/tool/CMakeLists.txt b/test/middleware/IpcConfig/tool/CMakeLists.txt new file mode 100644 index 0000000..eb3d4b1 --- /dev/null +++ b/test/middleware/IpcConfig/tool/CMakeLists.txt @@ -0,0 +1,54 @@ +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +include(${MIDDLEWARE_SOURCE_PATH}/IpcConfig/build/ipc_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./src + ./include + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/Log/include + ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/src + ${TEST_SOURCE_PATH} + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include + ${TEST_SOURCE_PATH}/utils/McuProtocol/tool/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +aux_source_directory(./src TEST_TOOL_SRC_FILES) +set(TEST_TOOL_TARGET IpcConfigTestTool) +add_library(${TEST_TOOL_TARGET} STATIC ${TEST_TOOL_SRC_FILES}) +target_link_libraries(${TEST_TOOL_TARGET} IpcConfig LinuxApiMock Log) + +if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") +add_custom_target( + IpcConfigTestTool_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${TEST_TOOL_SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + IpcConfigTestTool_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${TEST_TOOL_SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool +) +add_custom_command( + TARGET ${TEST_TOOL_TARGET} + PRE_BUILD + COMMAND make IpcConfigTestTool_code_check + COMMAND make IpcConfigTestTool_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TEST_TOOL_TARGET}) \ No newline at end of file diff --git a/test/middleware/IpcConfig/tool/include/IpcConfigTestTool.h b/test/middleware/IpcConfig/tool/include/IpcConfigTestTool.h new file mode 100644 index 0000000..50af013 --- /dev/null +++ b/test/middleware/IpcConfig/tool/include/IpcConfigTestTool.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IPC_CONFIG_TEST_TOOL_H +#define IPC_CONFIG_TEST_TOOL_H +#include "GtestUsing.h" +#include "LinuxApiMock.h" +class IpcConfigTestTool +{ +public: + IpcConfigTestTool() = default; + virtual ~IpcConfigTestTool() = default; + void Init(std::shared_ptr &mock); + void UnInit(void); + +private: + void MockMountedFile(void); + FILE *OpenMockMountedFile(const char *mode); + +private: + std::shared_ptr mLinuxTest; + FILE *mFile = nullptr; +}; +#endif \ No newline at end of file diff --git a/test/middleware/IpcConfig/tool/src/IpcConfigTestTool.cpp b/test/middleware/IpcConfig/tool/src/IpcConfigTestTool.cpp new file mode 100644 index 0000000..d12906e --- /dev/null +++ b/test/middleware/IpcConfig/tool/src/IpcConfigTestTool.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IpcConfigTestTool.h" +#include "ILog.h" +#include "LinuxApi.h" +#include +#include +const char *MOUNTED_FILE = "./mount_info.txt"; +extern const char *SYSTEM_MOUNTED_FILE; +void IpcConfigTestTool::Init(std::shared_ptr &mock) +{ + MockMountedFile(); + auto api_fopen = [=](const char *pathname, const char *mode) { + LogInfo("Open mock mounted file.\n"); + mFile = OpenMockMountedFile(mode); + }; + EXPECT_CALL(*mock.get(), fx_fopen(SYSTEM_MOUNTED_FILE, _)) + .WillRepeatedly(DoAll(WithArgs<0, 1>(Invoke(api_fopen)), (ReturnPointee(&mFile)))); +} +void IpcConfigTestTool::UnInit(void) +{ + constexpr int BUF_LENGTH = 256; + char cmd[BUF_LENGTH] = {0}; + sprintf(cmd, "rm -rf %s", MOUNTED_FILE); + fx_system(cmd); +} +void IpcConfigTestTool::MockMountedFile(void) +{ + FILE *file; + file = fopen(MOUNTED_FILE, "w"); + if (file == NULL) { + perror("Error opening file"); + return; + } + + fprintf(file, "devtmpfs /dev devtmpfs rw,relatime,size=10176k,nr_inodes=2544,mode=755 0 0\n"); + fprintf(file, "proc /proc proc rw,relatime 0 0\n"); + fprintf(file, "tmpfs /tmp tmpfs rw,relatime,size=14464k,nr_inodes=3616 0 0\n"); + fprintf(file, "tmpfs /run tmpfs rw,nosuid,nodev,relatime,size=14464k,nr_inodes=3616,mode=755 0 0\n"); + fprintf(file, "sysfs /sys sysfs rw,relatime 0 0\n"); + fprintf(file, "/dev/block/by-name" USERDATA_MOUNT_PATH " " USERDATA_MOUNT_PATH " jffs2 rw,relatime 0 0\n"); + fprintf( + file, + "/dev/mmcblk1p1 /mnt/sdcard vfat " + "rw,relatime,fmask=0022,dmask=0022,codepage=936,iocharset=cp936,shortname=mixed,utf8,errors=remount-ro 0 0\n"); + + fclose(file); + fx_system("sync"); + LogInfo("File written successfully.\n"); +} +FILE *IpcConfigTestTool::OpenMockMountedFile(const char *mode) +{ + FILE *fp = nullptr; + fp = fopen(MOUNTED_FILE, mode); + return fp; +} \ No newline at end of file diff --git a/test/utils/LinuxApiMock/include/LinuxApiMock.h b/test/utils/LinuxApiMock/include/LinuxApiMock.h index 60ade21..f1d6eae 100644 --- a/test/utils/LinuxApiMock/include/LinuxApiMock.h +++ b/test/utils/LinuxApiMock/include/LinuxApiMock.h @@ -34,6 +34,7 @@ public: virtual int fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); virtual int fx_fstat(int fd, struct stat *statbuf); virtual int fx_access(const char *pathname, int mode); + virtual FILE *fx_fopen(const char *pathname, const char *mode); }; /** * A simulation interface class used for automated testing in Ubuntu systems, implementing the function of piling on @@ -52,6 +53,7 @@ public: MOCK_METHOD5(fx_select, int(int, fd_set *, fd_set *, fd_set *, struct timeval *)); MOCK_METHOD2(fx_fstat, int(int, struct stat *)); MOCK_METHOD2(fx_access, int(const char *, int)); + MOCK_METHOD2(fx_fopen, FILE *(const char *, const char *)); public: /** diff --git a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp index 42371d4..3af63f0 100644 --- a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp +++ b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp @@ -68,6 +68,10 @@ int LinuxApiMock::fx_access(const char *pathname, int mode) { return __real_fx_access(pathname, mode); } +FILE *LinuxApiMock::fx_fopen(const char *pathname, const char *mode) +{ + return __real_fx_fopen(pathname, mode); +} std::shared_ptr LinuxTest::CreateLinuxTest(void) { std::shared_ptr test = std::make_shared(); diff --git a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp index d062ba1..39d1966 100644 --- a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp +++ b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp @@ -114,6 +114,16 @@ void LinuxTestImpl::ApiInit(std::shared_ptr &mock) WithArgs<0, 1>(Invoke(api_access)), Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiUnlockThread), ReturnPointee(&accessResult))); + static FILE *fopenResult = nullptr; + auto api_fopen = [=](const char *pathname, const char *mode) { + fopenResult = __real_fx_fopen(pathname, mode); + }; + EXPECT_CALL(*mock.get(), fx_fopen(_, _)) + .WillRepeatedly( + DoAll(Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiLock), + WithArgs<0, 1>(Invoke(api_fopen)), + Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiUnlockThread), + ReturnPointee(&fopenResult))); } void LinuxTestImpl::Init() { @@ -126,13 +136,18 @@ void LinuxTestImpl::UnInit() } void LinuxTestImpl::ApiLock(void) { - mApiMutex.lock(); - LogInfo("lock api.\n"); + /** + * @brief This has been optimized and does not require locking; Place the lock position in the WrapApi file, and + * lock the Mock function to ensure that it returns the value of the global variable before it can return, to avoid + * the problem of obtaining incorrect return values due to multithreading timing errors. + */ + // mApiMutex.lock(); + // LogInfo("lock api.\n"); } void LinuxTestImpl::ApiUnlock(void) { - mApiMutex.unlock(); - LogInfo("unlock api.\n"); + // mApiMutex.unlock(); + // LogInfo("unlock api.\n"); } void LinuxTestImpl::ApiUnlockThread(void) { diff --git a/test/utils/LinuxApiMock/src/WrapApi.cpp b/test/utils/LinuxApiMock/src/WrapApi.cpp index 0aed79f..688eaa8 100644 --- a/test/utils/LinuxApiMock/src/WrapApi.cpp +++ b/test/utils/LinuxApiMock/src/WrapApi.cpp @@ -14,42 +14,56 @@ */ #include "WrapApi.h" #include "LinuxApiMock.h" +#include +static std::mutex gMutex; #ifdef __cplusplus extern "C" { #endif int __wrap_fx_open(const char *pathname, int flags) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_open(pathname, flags); } int __wrap_fx_tcgetattr(int fd, struct termios *termios_p) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_tcgetattr(fd, termios_p); } int __wrap_fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_tcsetattr(fd, optional_actions, termios_p); } ssize_t __wrap_fx_write(int fd, const void *buf, size_t count) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_write(fd, buf, count); } ssize_t __wrap_fx_read(int fd, void *buf, size_t count) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_read(fd, buf, count); } int __wrap_fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_select(nfds, readfds, writefds, exceptfds, timeout); } int __wrap_fx_fstat(int fd, struct stat *statbuf) { - // TODO: 在此处加锁,优化打桩时,接口需要调用真实接口并返回真实接口的返回值返回全局变量的多线程安全问题。 + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_fstat(fd, statbuf); } int __wrap_fx_access(const char *pathname, int mode) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_access(pathname, mode); } +FILE *__wrap_fx_fopen(const char *pathname, const char *mode) +{ + std::lock_guard locker(gMutex); + return LinuxApiMock::GetInstance()->fx_fopen(pathname, mode); +} #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/WrapApi.h b/test/utils/LinuxApiMock/src/WrapApi.h index 426ef86..734729c 100644 --- a/test/utils/LinuxApiMock/src/WrapApi.h +++ b/test/utils/LinuxApiMock/src/WrapApi.h @@ -14,6 +14,7 @@ */ #ifndef WRAP_API_H #define WRAP_API_H +#include #include #include #include @@ -30,6 +31,7 @@ ssize_t __real_fx_read(int fd, void *buf, size_t count); int __real_fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int __real_fx_fstat(int fd, struct stat *statbuf); int __real_fx_access(const char *pathname, int mode); +FILE *__real_fx_fopen(const char *pathname, const char *mode); #ifdef __cplusplus } #endif diff --git a/utils/ConfigBase/src/ConfigBase.cpp b/utils/ConfigBase/src/ConfigBase.cpp index b15ec75..4c1e54a 100644 --- a/utils/ConfigBase/src/ConfigBase.cpp +++ b/utils/ConfigBase/src/ConfigBase.cpp @@ -31,7 +31,9 @@ void *OpenConfigFile(const char *fileName) { std::shared_ptr *configObject = NewConfigBase(fileName); if (nullptr != configObject) { - (*configObject)->OpenConfigFile(); + if ((*configObject)->OpenConfigFile() == false) { + return nullptr; + } } return configObject; } diff --git a/utils/ConfigBase/src/ConfigBaseImpl.cpp b/utils/ConfigBase/src/ConfigBaseImpl.cpp index af322a0..4fe9e29 100644 --- a/utils/ConfigBase/src/ConfigBaseImpl.cpp +++ b/utils/ConfigBase/src/ConfigBaseImpl.cpp @@ -28,37 +28,38 @@ constexpr int INVALID_RESULT = -1; ConfigBaseImpl::ConfigBaseImpl(const std::string &fileName) : mFileName(fileName) { } -void ConfigBaseImpl::OpenConfigFile(void) +bool ConfigBaseImpl::OpenConfigFile(void) { - config_init(&cfg); - config_set_options(&cfg, + config_init(&mCfg); + config_set_options(&mCfg, (CONFIG_OPTION_FSYNC | CONFIG_OPTION_SEMICOLON_SEPARATORS | CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS | CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE)); constexpr int FIEL_EXIST = 0; if (FIEL_EXIST == access(mFileName.c_str(), F_OK)) { - if (!config_read_file(&cfg, mFileName.c_str())) { + if (!config_read_file(&mCfg, mFileName.c_str())) { LogError("Read file failed[%s].\n", mFileName.c_str()); - fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); - return; + fprintf(stderr, "%s:%d - %s\n", config_error_file(&mCfg), config_error_line(&mCfg), config_error_text(&mCfg)); + return false; } } else { LogInfo("Config file doesn't exist.mFileName = %s\n", mFileName.c_str()); /* Write out the new configuration. */ - if (!config_write_file(&cfg, mFileName.c_str())) { + if (!config_write_file(&mCfg, mFileName.c_str())) { fprintf(stderr, "Error while writing file.\n"); - return; + return false; } } + return true; } void ConfigBaseImpl::CloseConfigFile(void) { - config_destroy(&cfg); + config_destroy(&mCfg); } StatusCode ConfigBaseImpl::ConfigSaveFile(void) { LogInfo("Save file[%s].\n", mFileName.c_str()); - if (!config_write_file(&cfg, mFileName.c_str())) { + if (!config_write_file(&mCfg, mFileName.c_str())) { LogError("Save config failed.\n"); return CreateStatusCode(STATUS_CODE_NOT_OK); } @@ -67,7 +68,7 @@ StatusCode ConfigBaseImpl::ConfigSaveFile(void) StatusCode ConfigBaseImpl::ConfigGetInt(const char *name, int *value) { int result = INVALID_RESULT; - result = config_lookup_int(&cfg, name, value); + result = config_lookup_int(&mCfg, name, value); if (CONFIG_FALSE == result) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -77,7 +78,7 @@ StatusCode ConfigBaseImpl::ConfigSetInt(const char *name, const int value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -97,7 +98,7 @@ StatusCode ConfigBaseImpl::ConfigGetShort(const char *name, short *value) { int intValue = 0; int result = 0; - result = config_lookup_int(&cfg, name, &intValue); + result = config_lookup_int(&mCfg, name, &intValue); if (CONFIG_FALSE == result || CHECK_SHORT_LIMIT(intValue)) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -108,7 +109,7 @@ StatusCode ConfigBaseImpl::ConfigSetShort(const char *name, const short value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -129,7 +130,7 @@ StatusCode ConfigBaseImpl::ConfigGetLong(const char *name, long *value) { long long llongValue = 0; int result = 0; - result = config_lookup_int64(&cfg, name, &llongValue); + result = config_lookup_int64(&mCfg, name, &llongValue); if (CONFIG_FALSE == result || CHECK_LONG_LIMIT(llongValue)) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -140,7 +141,7 @@ StatusCode ConfigBaseImpl::ConfigSetLong(const char *name, const long value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -160,7 +161,7 @@ StatusCode ConfigBaseImpl::ConfigSetLong(const char *name, const long value) StatusCode ConfigBaseImpl::ConfigGetLLong(const char *name, long long *value) { int result = 0; - result = config_lookup_int64(&cfg, name, value); + result = config_lookup_int64(&mCfg, name, value); if (CONFIG_FALSE == result) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -170,7 +171,7 @@ StatusCode ConfigBaseImpl::ConfigSetLLong(const char *name, const long long valu { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -190,7 +191,7 @@ StatusCode ConfigBaseImpl::ConfigGetChar(const char *name, char *value) { int charValue = 0; int result = 0; - result = config_lookup_int(&cfg, name, &charValue); + result = config_lookup_int(&mCfg, name, &charValue); if (CONFIG_FALSE == result && CHECK_CHAR_LIMIT(charValue)) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -201,7 +202,7 @@ StatusCode ConfigBaseImpl::ConfigSetChar(const char *name, const char value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -221,7 +222,7 @@ StatusCode ConfigBaseImpl::ConfigSetChar(const char *name, const char value) StatusCode ConfigBaseImpl::ConfigGetBool(const char *name, bool *value) { int result = 0; - result = config_lookup_bool(&cfg, name, (int *)value); + result = config_lookup_bool(&mCfg, name, (int *)value); if (CONFIG_FALSE == result) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -231,7 +232,7 @@ StatusCode ConfigBaseImpl::ConfigSetBool(const char *name, const bool value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -251,7 +252,7 @@ StatusCode ConfigBaseImpl::ConfigGetFloat(const char *name, float *value) { double dValue = 0; int result = 0; - result = config_lookup_float(&cfg, name, &dValue); + result = config_lookup_float(&mCfg, name, &dValue); if (CONFIG_FALSE == result || CHECK_FLOAT_LIMIT(dValue)) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -262,7 +263,7 @@ StatusCode ConfigBaseImpl::ConfigSetFloat(const char *name, const float value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -282,7 +283,7 @@ StatusCode ConfigBaseImpl::ConfigSetFloat(const char *name, const float value) StatusCode ConfigBaseImpl::ConfigGetDouble(const char *name, double *value) { int result = 0; - result = config_lookup_float(&cfg, name, value); + result = config_lookup_float(&mCfg, name, value); if (CONFIG_FALSE == result) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -292,7 +293,7 @@ StatusCode ConfigBaseImpl::ConfigSetDouble(const char *name, const double value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); @@ -311,7 +312,7 @@ StatusCode ConfigBaseImpl::ConfigSetDouble(const char *name, const double value) StatusCode ConfigBaseImpl::ConfigGetString(const char *name, const char **value) { int result = 0; - result = config_lookup_string(&cfg, name, value); + result = config_lookup_string(&mCfg, name, value); if (CONFIG_FALSE == result) { return CreateConfigCode(CONFIG_CODE_PARAM_NOT_EXIST); } @@ -321,7 +322,7 @@ StatusCode ConfigBaseImpl::ConfigSetString(const char *name, const char *value) { config_setting_t *root = nullptr; config_setting_t *setting = nullptr; - root = config_root_setting(&cfg); + root = config_root_setting(&mCfg); if (nullptr == root) { LogError("Config function failed.\n"); return CreateConfigCode(STATUS_CODE_NOT_OK); diff --git a/utils/ConfigBase/src/ConfigBaseImpl.h b/utils/ConfigBase/src/ConfigBaseImpl.h index de3c9a2..56979ac 100644 --- a/utils/ConfigBase/src/ConfigBaseImpl.h +++ b/utils/ConfigBase/src/ConfigBaseImpl.h @@ -21,7 +21,7 @@ class ConfigBaseImpl : public IConfigBase public: ConfigBaseImpl(const std::string &fileName); virtual ~ConfigBaseImpl() = default; - void OpenConfigFile(void) override; + bool OpenConfigFile(void) override; void CloseConfigFile(void) override; StatusCode ConfigSaveFile(void) override; StatusCode ConfigGetInt(const char *name, int *value) override; @@ -45,6 +45,6 @@ public: private: const std::string mFileName; - config_t cfg; + config_t mCfg; }; #endif \ No newline at end of file diff --git a/utils/ConfigBase/src/IConfigBase.cpp b/utils/ConfigBase/src/IConfigBase.cpp index 2144913..55086fb 100644 --- a/utils/ConfigBase/src/IConfigBase.cpp +++ b/utils/ConfigBase/src/IConfigBase.cpp @@ -16,8 +16,9 @@ #include "ConfigBaseImpl.h" #include "ILog.h" #include -void IConfigBase::OpenConfigFile(void) +bool IConfigBase::OpenConfigFile(void) { + return false; } void IConfigBase::CloseConfigFile(void) { diff --git a/utils/ConfigBase/src/IConfigBase.h b/utils/ConfigBase/src/IConfigBase.h index 8a98c18..0fec945 100644 --- a/utils/ConfigBase/src/IConfigBase.h +++ b/utils/ConfigBase/src/IConfigBase.h @@ -21,7 +21,7 @@ class IConfigBase public: IConfigBase() = default; virtual ~IConfigBase() = default; - virtual void OpenConfigFile(void); + virtual bool OpenConfigFile(void); virtual void CloseConfigFile(void); virtual StatusCode ConfigSaveFile(void); virtual StatusCode ConfigGetInt(const char *name, int *value); diff --git a/utils/LinuxApi/include/LinuxApi.h b/utils/LinuxApi/include/LinuxApi.h index ce9a5ca..96f4568 100644 --- a/utils/LinuxApi/include/LinuxApi.h +++ b/utils/LinuxApi/include/LinuxApi.h @@ -15,6 +15,7 @@ #ifndef LINUX_API_H #define LINUX_API_H #include +#include #include #include #include @@ -33,6 +34,7 @@ ssize_t fx_read(int fd, void *buf, size_t count); int fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int fx_fstat(int fd, struct stat *statbuf); int fx_access(const char *pathname, int mode); +FILE *fx_fopen(const char *pathname, const char *mode); #ifdef __cplusplus } #endif diff --git a/utils/LinuxApi/src/LinuxApi.c b/utils/LinuxApi/src/LinuxApi.c index 42e161a..754cf9c 100644 --- a/utils/LinuxApi/src/LinuxApi.c +++ b/utils/LinuxApi/src/LinuxApi.c @@ -57,4 +57,8 @@ int fx_fstat(int fd, struct stat *statbuf) int fx_access(const char *pathname, int mode) { return access(pathname, mode); +} +FILE *fx_fopen(const char *pathname, const char *mode) +{ + return fopen(pathname, mode); } \ No newline at end of file diff --git a/utils/Log/abstract/ILog.cpp b/utils/Log/abstract/ILog.cpp index d0917f4..fb92851 100644 --- a/utils/Log/abstract/ILog.cpp +++ b/utils/Log/abstract/ILog.cpp @@ -3,9 +3,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,7 +22,8 @@ static void ILogInitCallBack(ILog *object, const enum LogInstance log) static void ILogFree(ILog *object) { } -static int ILogPrintf(ILog *object, const char *function, const int line, const enum LogType type, const char *format, ...) +static int ILogPrintf(ILog *object, const char *function, const int line, const enum LogType type, const char *format, + ...) { return 0; } @@ -43,8 +44,7 @@ ILog *GetLogIntance(void) } void NewILog(ILog **object) { - if (!object || !(*object)) - { + if (!object || !(*object)) { return; } memcpy(*object, &default_log, sizeof(ILog)); @@ -52,6 +52,6 @@ void NewILog(ILog **object) } void ResetLogImpl(ILog *impl) { - log_instance->free(log_instance); + // log_instance->free(log_instance); log_instance = impl; } \ No newline at end of file diff --git a/utils/McuProtocol/include/McuProtocol.h b/utils/McuProtocol/include/McuProtocol.h index d986796..74302c6 100644 --- a/utils/McuProtocol/include/McuProtocol.h +++ b/utils/McuProtocol/include/McuProtocol.h @@ -155,8 +155,8 @@ private: private: std::mutex mMutex; sem_t mSem; - std::thread mDataHandleThread; bool mThreadRuning; + std::thread mDataHandleThread; std::list mMcuDataList; }; #endif \ No newline at end of file