diff --git a/README.md b/README.md index 57dbc3d9..7440f118 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,33 @@ * SDK工程所有开发文档均使用markdown语法编写,需要使用markdown语法解析器进行解析,方便阅读,如:Typora;开发工程师建议使用vscode安装markdownlint插件进行阅读; * SDK工程所有文档描述路径时,"//"双斜杠表示工程根目录; -## 1.2. 编译 +## 1.2. 开发环境准备 + +  工程的开发,需要预安装一些开发工具。例如:cmake的特定版本,llvm工具等。 + +### 1.2.1. cmake安装 + +  cmake是一个跨平台的安装(编译)工具,它是由Kitware公司开发的一个开源软件,可以用来配置、构建、编译一个工程。 + +```code +# 项目根目录执行: +$ make install-cmake +``` + +### 1.2.2. llvm工具安装 + +  LLVM是一个编译器工具链,包含clang编译器、llvm核心库等。此处只用了clang-tidy和clang-format工具,一个负责编码规范,一个负责代码格式化。 + +```code +# 项目根目录执行: +$ make compile_llvm +``` + +## 1.3. 编译   架构设计上支持去平台编译和运行,本仓库源码可仿真运行在ubuntu系统。 -### 1.2.1. Ubuntu系统 +### 1.3.1. Ubuntu系统 在项目根目录下执行命令: @@ -24,7 +46,7 @@ cd cmake-shell/ // 在中间文件目录进行编译,把所有中间文件 make // 编译全部输出构建文件 ``` -### 1.2.2. 交叉编译 +### 1.3.2. 交叉编译 参考: @@ -37,9 +59,9 @@ make // 编译全部输出构建文件   交叉编译请参考基于IPC SDK作为子仓库的工程配置,此处忽略。 -### 1.2.3. 小技巧 +### 1.3.3. 小技巧 -#### 1.2.3.1. 代码阅读辅助工具(基于vscode) +#### 1.3.3.1. 代码阅读辅助工具(基于vscode)   为了方便代码跳转阅读,除了安装基本的c++插件外,结合cmake构建工具生成的compile_commands.json文件可实现代码之间的精准跳转。 diff --git a/application/HuntingCamera/CMakeLists.txt b/application/HuntingCamera/CMakeLists.txt index 5e922eda..504305b2 100644 --- a/application/HuntingCamera/CMakeLists.txt +++ b/application/HuntingCamera/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( link_directories( ${LIBS_OUTPUT_PATH} ${EXTERNAL_LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib ) aux_source_directory(. SRC_FILES) diff --git a/application/MissionManager/src/AppMonitor.cpp b/application/MissionManager/src/AppMonitor.cpp index 1ec20014..873a0d50 100644 --- a/application/MissionManager/src/AppMonitor.cpp +++ b/application/MissionManager/src/AppMonitor.cpp @@ -13,8 +13,14 @@ * limitations under the License. */ #include "AppMonitor.h" +#include "IAppManager.h" #include "ILog.h" +#include "IStorageManager.h" +#include "StatusCode.h" #include +AppMonitor::AppMonitor() : mMicStatus(SwitchStatus::END) +{ +} StatusCode AppMonitor::GetProductInfo(AppGetProductInfo ¶m) { LogInfo("AppMonitor::GetProductInfo.\n"); @@ -65,7 +71,7 @@ StatusCode AppMonitor::GetBatteryInfo(AppGetBatteryInfo ¶m) } StatusCode AppMonitor::GetParamValue(AppParamValue ¶m) { - param.mMicStatus = SwitchStatus::ON; + param.mMicStatus = mMicStatus; param.mRec = SwitchStatus::OFF; return CreateStatusCode(STATUS_CODE_OK); } @@ -114,16 +120,18 @@ StatusCode AppMonitor::GetStorageFileList(const AppGetFileInfo &fileInfo, std::v } StatusCode AppMonitor::SetDateTime(const AppSetDateTime ¶m) { - // return CreateStatusCode(STATUS_CODE_OK); } StatusCode AppMonitor::SetTimeZone(const unsigned int &zone) { - // return CreateStatusCode(STATUS_CODE_OK); } StatusCode AppMonitor::SetParamValue(const AppSetParamValue ¶m) { + LogInfo("SetParamValue: param = %s.\n", param.mName.c_str()); + if (param.mName == "mic") { + mMicStatus = static_cast(param.mValue); + } return CreateStatusCode(STATUS_CODE_OK); } StatusCode AppMonitor::EnterRecorder(void) @@ -136,7 +144,6 @@ StatusCode AppMonitor::AppPlayback(const PlayBackEvent &event) } StatusCode AppMonitor::UploadFile(AppUploadFile ¶m) { - // return CreateStatusCode(STATUS_CODE_OK); } StatusCode AppMonitor::GetThumbnail(AppGetThumbnail ¶m) diff --git a/application/MissionManager/src/AppMonitor.h b/application/MissionManager/src/AppMonitor.h index adb16723..c4e48e98 100644 --- a/application/MissionManager/src/AppMonitor.h +++ b/application/MissionManager/src/AppMonitor.h @@ -19,7 +19,7 @@ class AppMonitor : public VAppMonitor { public: - AppMonitor() = default; + AppMonitor(); virtual ~AppMonitor() = default; StatusCode GetProductInfo(AppGetProductInfo ¶m) override; StatusCode GetDeviceAttr(AppGetDeviceAttr ¶m) override; @@ -41,5 +41,8 @@ public: private: SdCardStatus SdCardStatusConvert(const StorageEvent &event); + +private: + SwitchStatus mMicStatus; // TODO: improve delete. }; #endif \ No newline at end of file diff --git a/application/MissionManager/src/DataProcessing.cpp b/application/MissionManager/src/DataProcessing.cpp index 138d3457..768e0c1b 100644 --- a/application/MissionManager/src/DataProcessing.cpp +++ b/application/MissionManager/src/DataProcessing.cpp @@ -14,6 +14,13 @@ */ #include "DataProcessing.h" #include "ILog.h" +#include "IMissionManager.h" +#include "IStateMachine.h" +#include "KeyControl.h" +#include +#include +#include +#include const bool NOT_EXECUTED = false; const bool EXECUTED = true; key_event_data::key_event_data(const std::string &keyName, const KeyEvent &keyEvent, const unsigned int &holdTime) diff --git a/application/MissionManager/src/IMissionManager.cpp b/application/MissionManager/src/IMissionManager.cpp index 51af08f9..e2c5fb24 100644 --- a/application/MissionManager/src/IMissionManager.cpp +++ b/application/MissionManager/src/IMissionManager.cpp @@ -14,6 +14,8 @@ */ #include "IMissionManager.h" #include "ILog.h" +#include "StatusCode.h" +#include std::shared_ptr &IMissionManager::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/application/MissionManager/src/IdleState.cpp b/application/MissionManager/src/IdleState.cpp index f0a2d6ee..e4269bb5 100644 --- a/application/MissionManager/src/IdleState.cpp +++ b/application/MissionManager/src/IdleState.cpp @@ -13,10 +13,9 @@ * limitations under the License. */ #include "IdleState.h" -#include "IFilesManager.h" +#include "DataProcessing.h" #include "ILog.h" -#include "IMediaManager.h" -#include "MissionStateMachine.h" +#include "IStateMachine.h" IdleState::IdleState() : State("IdleState") { // mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&IdleState::MediaReportHandle, this, _1); diff --git a/application/MissionManager/src/LedsHandle.cpp b/application/MissionManager/src/LedsHandle.cpp index 57fab914..3f9eb0f4 100644 --- a/application/MissionManager/src/LedsHandle.cpp +++ b/application/MissionManager/src/LedsHandle.cpp @@ -14,6 +14,8 @@ */ #include "LedsHandle.h" #include "ILog.h" +#include "LedControl.h" +#include "SetLedState.h" void LedsHandle::ControlDeviceStatusLed(const DeviceStatus &status, const long int &keepAliveTime, const unsigned int &blinkPeriod) { diff --git a/application/MissionManager/src/McuMonitor.cpp b/application/MissionManager/src/McuMonitor.cpp index 49d7ec10..bb8df32f 100644 --- a/application/MissionManager/src/McuMonitor.cpp +++ b/application/MissionManager/src/McuMonitor.cpp @@ -15,6 +15,7 @@ #include "McuMonitor.h" #include "ILog.h" #include "IMcuManager.h" +#include void McuMonitor::Init(std::shared_ptr &monitor) { IMcuManager::GetInstance()->SetMcuMonitor(monitor); diff --git a/application/MissionManager/src/MediaHandleState.cpp b/application/MissionManager/src/MediaHandleState.cpp index f6b29f66..307bb34e 100644 --- a/application/MissionManager/src/MediaHandleState.cpp +++ b/application/MissionManager/src/MediaHandleState.cpp @@ -13,10 +13,15 @@ * limitations under the License. */ #include "MediaHandleState.h" -#include "IFilesManager.h" +#include "DataProcessing.h" #include "ILog.h" #include "IMediaManager.h" +#include "IStateMachine.h" +#include "MediaTaskHandle.h" #include "MissionStateMachine.h" +#include +#include +#include MediaHandleState::MediaHandleState() : State("MediaHandleState") { mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] = diff --git a/application/MissionManager/src/MediaTask.cpp b/application/MissionManager/src/MediaTask.cpp index 20d0c6c2..24071faf 100644 --- a/application/MissionManager/src/MediaTask.cpp +++ b/application/MissionManager/src/MediaTask.cpp @@ -13,6 +13,9 @@ * limitations under the License. */ #include "MediaTask.h" +#include "DataProcessing.h" +#include "IMediaManager.h" +#include MediaTask::MediaTask(const MediaTaskType &type, const InternalStateEvent &bindEvent, const std::weak_ptr &iniator) : mType(type), mBindEvent(bindEvent), mIniator(iniator) diff --git a/application/MissionManager/src/MediaTaskHandle.cpp b/application/MissionManager/src/MediaTaskHandle.cpp index 37661004..1658490a 100644 --- a/application/MissionManager/src/MediaTaskHandle.cpp +++ b/application/MissionManager/src/MediaTaskHandle.cpp @@ -13,8 +13,14 @@ * limitations under the License. */ #include "MediaTaskHandle.h" +#include "DataProcessing.h" #include "ILog.h" +#include "IMediaManager.h" +#include "IMissionManager.h" +#include "MediaTask.h" #include "MissionStateMachine.h" +#include "StatusCode.h" +#include MediaTaskHandle::MediaTaskHandle() { mMediaHandle.reset(); diff --git a/application/MissionManager/src/MissionManager.cpp b/application/MissionManager/src/MissionManager.cpp index f4a786a3..67b81784 100644 --- a/application/MissionManager/src/MissionManager.cpp +++ b/application/MissionManager/src/MissionManager.cpp @@ -15,6 +15,7 @@ #include "MissionManager.h" #include "IAppManager.h" #include "MissionStateMachine.h" +#include "StatusCode.h" const StatusCode MissionManager::Init(void) { MissionStateMachine::GetInstance()->Init(); diff --git a/application/MissionManager/src/MissionManagerMakePtr.cpp b/application/MissionManager/src/MissionManagerMakePtr.cpp index f478ecd5..13a53e01 100644 --- a/application/MissionManager/src/MissionManagerMakePtr.cpp +++ b/application/MissionManager/src/MissionManagerMakePtr.cpp @@ -14,16 +14,21 @@ */ #include "MissionManagerMakePtr.h" #include "ILog.h" +#include "IMcuManager.h" +#include "IMissionManager.h" +#include "IStateMachine.h" #include "IdleState.h" #include "MediaHandleState.h" #include "MissionManager.h" #include "OnMissionState.h" #include "PirTriggeredMissionState.h" #include "SdCardHandleState.h" +#include "StatusCode.h" #include "StorageHandleState.h" #include "TestMissionState.h" #include "TopState.h" #include "UpgradeState.h" +#include bool CreateMissionManagerModule(void) { auto instance = std::make_shared(); diff --git a/application/MissionManager/src/MissionState.cpp b/application/MissionManager/src/MissionState.cpp index 04b3608e..cfe1e237 100644 --- a/application/MissionManager/src/MissionState.cpp +++ b/application/MissionManager/src/MissionState.cpp @@ -13,9 +13,13 @@ * limitations under the License. */ #include "MissionState.h" -#include "IAppManager.h" +#include "DataProcessing.h" #include "ILog.h" +#include "IStateMachine.h" +#include "LedsHandle.h" #include "MissionStateMachine.h" +#include +#include MissionState::MissionState(const std::string &name) : State(name) { mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&MissionState::MediaReportHandle, this, _1); diff --git a/application/MissionManager/src/MissionStateMachine.cpp b/application/MissionManager/src/MissionStateMachine.cpp index d62fc283..cc3aa689 100644 --- a/application/MissionManager/src/MissionStateMachine.cpp +++ b/application/MissionManager/src/MissionStateMachine.cpp @@ -15,8 +15,13 @@ #include "MissionStateMachine.h" #include "DataProcessing.h" #include "ILog.h" +#include "IMcuManager.h" +#include "IMissionManager.h" +#include "IStateMachine.h" #include "McuAskBase.h" #include "MissionManagerMakePtr.h" +#include "StatusCode.h" +#include // #include "TopState.h" std::shared_ptr &MissionStateMachine::GetInstance(std::shared_ptr *impl) { diff --git a/application/MissionManager/src/OnMissionState.cpp b/application/MissionManager/src/OnMissionState.cpp index f84c44ee..7e497b99 100644 --- a/application/MissionManager/src/OnMissionState.cpp +++ b/application/MissionManager/src/OnMissionState.cpp @@ -14,7 +14,8 @@ */ #include "OnMissionState.h" #include "ILog.h" -#include "IStorageManager.h" +#include "IStateMachine.h" +#include "MissionState.h" #include "MissionStateMachine.h" OnMissionState::OnMissionState() : MissionState("OnMissionState") { diff --git a/application/MissionManager/src/PirTrggeredMissionState.cpp b/application/MissionManager/src/PirTrggeredMissionState.cpp index 7f2c287a..7ab21f91 100644 --- a/application/MissionManager/src/PirTrggeredMissionState.cpp +++ b/application/MissionManager/src/PirTrggeredMissionState.cpp @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "PirTriggeredMissionState.h" #include "ILog.h" -#include "IStorageManager.h" +#include "IStateMachine.h" +#include "MissionState.h" #include "MissionStateMachine.h" +#include "PirTriggeredMissionState.h" PirTriggeredMissionState::PirTriggeredMissionState() : MissionState("PirTriggeredMissionState") { // mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] = diff --git a/application/MissionManager/src/SdCardHandleState.cpp b/application/MissionManager/src/SdCardHandleState.cpp index fef26ffb..a86a24e4 100644 --- a/application/MissionManager/src/SdCardHandleState.cpp +++ b/application/MissionManager/src/SdCardHandleState.cpp @@ -13,10 +13,18 @@ * limitations under the License. */ #include "SdCardHandleState.h" +#include "DataProcessing.h" #include "IFilesManager.h" #include "ILog.h" #include "IMediaManager.h" +#include "IMissionManager.h" +#include "IStateMachine.h" +#include "IStorageManager.h" #include "MissionStateMachine.h" +#include "StatusCode.h" +#include +#include +using std::placeholders::_1; SdCardHandleState::SdCardHandleState() : State("SdCardHandleState"), mSdCardStatus(StorageEvent::END) { mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&SdCardHandleState::MediaReportHandle, this, _1); diff --git a/application/MissionManager/src/SetLedState.cpp b/application/MissionManager/src/SetLedState.cpp index d0f9b81a..365896e1 100644 --- a/application/MissionManager/src/SetLedState.cpp +++ b/application/MissionManager/src/SetLedState.cpp @@ -13,6 +13,11 @@ * limitations under the License. */ #include "SetLedState.h" +#include "IDeviceManager.h" +#include "LedControl.h" +#include "StatusCode.h" +#include +#include SetLedState::SetLedState(const LedState &state, const unsigned int &keepAliveTime, const unsigned int &blinkPeriod) : mState(state), mKeepAliveTime(keepAliveTime), mBlinkPeriod(blinkPeriod) { diff --git a/application/MissionManager/src/StorageHandleState.cpp b/application/MissionManager/src/StorageHandleState.cpp index 86b80a9a..ba67bd0d 100644 --- a/application/MissionManager/src/StorageHandleState.cpp +++ b/application/MissionManager/src/StorageHandleState.cpp @@ -13,9 +13,14 @@ * limitations under the License. */ #include "StorageHandleState.h" +#include "DataProcessing.h" #include "ILog.h" -#include "IMediaManager.h" +#include "IMissionManager.h" +#include "IStateMachine.h" +#include "IStorageManager.h" #include "MissionStateMachine.h" +#include +#include StorageHandleState::StorageHandleState() : State("StorageHandleState") { mEventHandle[InternalStateEvent::STORAGE_HANDLE_STATE_INIT] = diff --git a/application/MissionManager/src/TestMissionState.cpp b/application/MissionManager/src/TestMissionState.cpp index 7af850d7..ec17f717 100644 --- a/application/MissionManager/src/TestMissionState.cpp +++ b/application/MissionManager/src/TestMissionState.cpp @@ -13,10 +13,17 @@ * limitations under the License. */ #include "TestMissionState.h" +#include "DataProcessing.h" #include "IAppManager.h" #include "ILog.h" +#include "IMissionManager.h" +#include "IStateMachine.h" #include "IStorageManager.h" +#include "LedsHandle.h" +#include "MissionState.h" #include "MissionStateMachine.h" +#include +#include TestMissionState::TestMissionState() : MissionState("TestMissionState") { mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] = diff --git a/application/MissionManager/src/TopState.cpp b/application/MissionManager/src/TopState.cpp index 83a6fa5e..f88dbecc 100644 --- a/application/MissionManager/src/TopState.cpp +++ b/application/MissionManager/src/TopState.cpp @@ -13,10 +13,19 @@ * limitations under the License. */ #include "TopState.h" +#include "DataProcessing.h" +#include "IDeviceManager.h" #include "ILog.h" +#include "IMcuManager.h" #include "IMediaManager.h" +#include "IMissionManager.h" +#include "IStateMachine.h" #include "KeyControl.h" +#include "McuMonitor.h" #include "MissionStateMachine.h" +#include "StatusCode.h" +#include +#include TopState::TopState() : State("TopState") { mEventHandle[InternalStateEvent::STORAGE_HANDLE_STATE_INIT] = diff --git a/application/MissionManager/src/UpgradeState.cpp b/application/MissionManager/src/UpgradeState.cpp index e9c70044..5644a186 100644 --- a/application/MissionManager/src/UpgradeState.cpp +++ b/application/MissionManager/src/UpgradeState.cpp @@ -13,10 +13,12 @@ * limitations under the License. */ #include "UpgradeState.h" +#include "DataProcessing.h" #include "IHuntingUpgrade.h" #include "ILog.h" -#include "IMediaManager.h" +#include "IStateMachine.h" #include "MissionStateMachine.h" +#include UpgradeState::UpgradeState() : State("UpgradeState") { mEventHandle[InternalStateEvent::CHECK_UPGRADE_FILE] = std::bind(&UpgradeState::CheckUpgradeFileHandle, this, _1); diff --git a/build/global_config.cmake b/build/global_config.cmake index 7af18839..2cb9a11a 100755 --- a/build/global_config.cmake +++ b/build/global_config.cmake @@ -27,7 +27,7 @@ llvm-twine-local,\ misc-confusable-identifiers,\ misc-definitions-in-headers,\ misc-header-include-cycle,\ --misc-include-cleaner,\ +misc-include-cleaner,\ misc-misleading-bidirectional,\ misc-misleading-identifier,\ misc-misplaced-const,\ @@ -55,7 +55,7 @@ set(CLANG_FORMAT_FILE "LLVM ${CMAKE_SOURCE_DIR_IPCSDK}/tools/clang-format/.clang if(${LINUX_TEST} MATCHES "true") set(CLANG_TIDY_SUPPORT "true") set(CLANG_FORMAT_SUPPORT "true") - set(COMPILE_IMPROVE_SUPPORT "false") # 开启后每次编译可能会很慢 + set(COMPILE_IMPROVE_SUPPORT "true") # 开启后每次编译可能会很慢 set(LLVM_PATH "$ENV{HOME}/llvm-project") endif() # ------------ build clang-tools end ------------ # diff --git a/doc/clang-tidy_user_guide.md b/doc/clang-tidy_user_guide.md new file mode 100644 index 00000000..07d0c7c7 --- /dev/null +++ b/doc/clang-tidy_user_guide.md @@ -0,0 +1,42 @@ +# 1. clang-tidy使用指南 + +   使用clang-tidy工具进行代码规范管理。 +1. 编译时实时报错; +2. 指定自研源码检测; + +## 1.1. 环境搭建 + +1. llvm使用cmake编译,cmake版本要求 3.20以上,此处使用cmake-3.27.4 +``` +// cmake源码目录://tools/cmake/cmake-3.27.4.tar.gz +// cmake源码安装: +tar zxvf cmake-3.27.4.tar.gz +cd cmake-3.27.4/ +sudo apt-get install openssl // 如果执行./bootstrap提示缺少ssl相关资源,执行此安装命令 +./bootstrap +make +sudo make install +``` +2. 安装llvm +``` +// 下载源码 +git clone https://github.com/llvm/llvm-project.git +cd llvm-project/ +mkdir build +cd build +cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ../llvm +make -j8 +find ./ -name clang-tidy // 确认编译完成 +``` + +## 1.2. clang-tidy使用 +修改配置:< IPC-SDK >/build/global_config.cmake +``` +# ------------ build clang-tools ------------ # +if(${LINUX_TEST} MATCHES "true") + set(CLANG_TIDY_SUPPORT "true") // 使能工具 + set(CLANG_FORMAT_SUPPORT "true") + set(LLVM_PATH "/home/xiaojiazhu/project/tmp/llvm-project") // llvm安装目录 +endif() +# ------------ build clang-tools end ------------ # +``` \ No newline at end of file diff --git a/doc/cmake_exploitReport.md b/doc/cmake_exploitReport.md new file mode 100644 index 00000000..61a54da6 --- /dev/null +++ b/doc/cmake_exploitReport.md @@ -0,0 +1,54 @@ +# 1.cmake开发报告 + +## 1.1 前言 +该篇md用于ipc项目下log功能的cmakelist的开发报告,以阐述其功能和组成。 + +## 1.2 功能介绍 +* 设置库文件输出路径:`set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})`. +该语句用于设置该功能的静态库的生成路径,其中`${LIBS_OUTPUT_PATH}`在/build/cmake/global_config.cmake被定义在项目根目录的/output_files/libs/。 + +* 添加实现功能的文件目录:`include_directories(./)`. +该语句旨在向编译器告知该功能的实现文件和头文件的所在位置。 + +* 添加功能目录到搜索路径:`set(CMAKE_AUTOMOC ON);set(CMAKE_INCLUDE_CURRENT_DIR ON)` +这些 CMake 命令支持自动处理 Qt moc(元对象编译器),并将当前目录设置为包含在包含文件的搜索路径中;在构建过程中自动运行Qt moc编译器,用于包含Q_OBJECT宏的任何源文件。这对于为信号和插槽生成必要的C++代码是必需的;该选项将当前源目录添加到包含文件的搜索路径中。这允许构建系统查找与正在编译的源文件位于同一目录中的头文件。 + +* 收集、生成头文件列表:`file(GLOB_RECURSE HEADER_FILES "*.h")` +该语句的功能是搜索当前目录及其子目录中扩展名为 .h 的所有文件。生成的文件列表存储在 HEADER_FILES 变量中。 + +* 收集源文件列表:`aux_source_directory(. SRC_FILES)` +在本语句中,aux_source_directory(.SRC_FILES) 从当前目录(由 .) 及其子目录中收集所有源文件(例如,.cpp 个文件),生成的文件列表存储在 SRC_FILES 变量中。 + +* 添加编译器标志和定义到当前目录及其子目录:`add_definitions("-fexceptions")` +添加编译器标志`-fexceptions`以在代码中启用异常处理。此标志告诉编译器生成支持捕获和引发异常的代码。通过使用 add_definitions(),可以将特定的编译器标志或定义全局应用于项目或特定源文件。 + +* 创建静态库目标:`add_library(xlog STATIC ${SRC_FILES} ${HEADER_FILES})` +在这种情况下,本语句使用提供的源文件和头文件列表创建一个名为“xlog”的静态库目标;`STATIC`关键字指定库将构建为静态库,这意味着库代码将在编译时直接链接到最终可执行文件中;`${SRC_FILES}`变量包含应编译并链接到库中的源文件(通常.cpp文件)的列表。${HEADER_FILES} 变量包含头文件(通常为 .h 文件)的列表,这些文件定义库使用的接口和声明。 + +## 1.3 总结 +该篇cmakelists.txt的主要用途是对ipc项目下xlog功能的显现文件的编译和汇总。 + +## 2.1 返回码管理库概述 +提供整个应用程序的返回码管理功能,例如:打印返回码的字符串含义。提供C语言接口,内部实现不限于C或者C++,形成项目内部唯一返回码标准。 + +## 2.2 功能介绍 +* 设置可执行文件的输出路径:`set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})`;`set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})` + +* 引入头文件目录:`include_directories`。`include_directories`表示引入头文件搜索路径,当工程要用到某个头文件的时候,就会去该路径下搜索。 + +* 开启自动编译:`set(CMAKE_AUTOMOC ON)` `set(CMAKE_INCLUDE_CURRENT_DIR ON)`. 这段代码开启了 CMake 的元对象编译器、界面编译器和资源编译器自动编译,这样当项目使用了包含元对象的文件、界面文件和资源文件时 CMake 可以自动检测并编译。 + +* 查找在./src路径下的所有源文件:`aux_source_directory(./src SRC_FILES)` 。 + +* 设置ReturnCode地址:`set(TARGET_NAME ReturnCode)`。根据提供的源文件创建一个叫ReturnCode的静态库。然后将目标文件与库文件进行链接:`target_link_libraries(${TARGET_NAME} Log)`。 + +## 2.3 返回码test +* 添加test文件到目录,本目录为测试代码目录,目录结构保持与源码目录结构一致。 + +* 在test各个文件夹里添加相对应的CMakeLists.txt文件,通过`add_subdirectory(utils)`添加与源码目录结构相对应的子文件夹。 + +* 在src文件夹下创建ReturnCodeTest.cpp,调用返回码管理接口。在根目录添加第三方库文件,存放需要用到的第三方库。 + +## 2.4 总结 +Cmake的语句都在CMakeLists.txt的文件中,Cmake运行之后就会产生想要的makefile文件,然后再直接make就可以编译出可执行程序。 + diff --git a/doc/cmake_guide.md b/doc/cmake_guide.md new file mode 100644 index 00000000..3de9df57 --- /dev/null +++ b/doc/cmake_guide.md @@ -0,0 +1,299 @@ +# 1. CMake构建工具使用 + +  SDK使用CMake工具构建。 + +## 1.1. 安装 + +```code +详见://tools/cmake/Makefile +$ cd tools/cmake +$ make +$ cmake --version +cmake version 3.27.4 +``` + +## 1.2. SDK构建配置脚本 + +* build目录下是基本的配置脚本。 + +```code +build/ +├── cmake +│   ├── Makefile // 调用cmake命令生成Makefile文件; +│   └── toolchain +│   └── linux.toolchain.cmake // 工具链配置文件已经一些全局变量; +├── global_config.cmake // 配置文件 +└── sdk_config.cmake // 配置文件 +``` + +### 1.2.1. //build/cmake/Makefile + +  调用cmake命令生成Makefile文件。 + +```code +all: + @mkdir -p ../../cmake-shell;\ // 创建cmake输出目录,这一步很关键,所有cmake的中间文件都将会存放在此目录。 + cd ../../cmake-shell;\ + pwd;\ + # 调用cmake命令,并指定工具链配置文件,生成Makefile文件。 + cmake -DCMAKE_TOOLCHAIN_FILE="./build/cmake/toolchain/linux.toolchain.cmake" ..;\ + cd .. +clean: + rm -rf ../../cmake-shell +``` + +在根目录执行:make cmake 的时候,即是调用上述Makefile生成Makefile文件。 + +### 1.2.2. //build/cmake/toolchain/linux.toolchain.cmake + +  工具链配置文件或者一些跨平台差异化的配置文件。该文件在//build/cmake/Makefile中被指定,当需要交叉编译时,此文件的变量需要被重新配置。 + +```code + +INCLUDE(CMakeForceCompiler) + +set(LINUX_TEST "true") +set(CROSS_COMPILE_PREFIX "") // 工具链前缀 +set(CMAKE_C_COMPILER "${CROSS_COMPILE_PREFIX}gcc") // 配置工具链 +set(CMAKE_CXX_COMPILER "${CROSS_COMPILE_PREFIX}g++") // 配置工具链 + +# path to compiler and utilities +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Name of the target platform +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) + +# Version of the system +set(CMAKE_SYSTEM_VERSION 1) +cmake_policy(SET CMP0011 NEW) +cmake_policy(SET CMP0005 NEW) + +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") // 编译系统平台,Linux表示在PC的ubuntu系统上编译 +set(SUBMODULE_PATH_OF_IPC_SDK "") // 子仓库路面,此处为空,交叉编译时设置 +set(PLATFORM_PATH "${CMAKE_CURRENT_SOURCE_DIR}") // 平台路径 +set(TEST_COVERAGE "true") // 覆盖率报告开关 +add_definitions(-DPLATFORM_PATH=\"${PLATFORM_PATH}\") // 定义一个宏 +set(PROJECT_OUTPUT_FOLDER "output_files") // 编译的目标文件输出目录 +set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_OUTPUT_FOLDER}") + +... // 此处省略不同模块的配置参数,一般是一些宏定义; +``` + +### 1.2.3. //CMakeLists.txt + +  SDK跟目录下的第一个CMakeLists.txt文件,cmake命令执行的时候会指定根目录,到此目录下寻找CMakeLists.txt文件作为整个项目的构建起点。 + +## 1.3. 重要的配置 + +### 1.3.1. 目录设置 + +  目录结构都是通过.cmake脚本来配置的。 + +#### 1.3.1.1. 源码目录结构配置 + +详见://build/global_config.cmake + +```code +set(EXEC_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/bin") +set(LIBS_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/libs") +set(TEST_TOOLS_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/libs/test_tools") +set(EXTERNAL_LIBS_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/libs/external") +set(TEST_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/test") + +set(PROJECT_ROOT_PATH "${PLATFORM_PATH}") +set(APPLICATION_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/application") # 应用层目录 +set(MIDDLEWARE_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/middleware") # 中间件层目录 +set(UTILS_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/utils") # 工具层目录 +set(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal") # 硬件抽象层目录 +set(TEST_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/test") # 自动化测试代码/example目录 +set(EXTERNAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/external") # 外部依赖库目录 +``` + +## 1.4. CMakeLists.txt基本语法 + +### 1.4.1. 概述 + +  概括性描述就是,只需要告诉CMakeLists.txt文件,构建时包含哪些配置文件,依赖的头文件目录,需要编译的源码文件,依赖的目标目录(如有),输出的目标,依赖的目标(一般是库),CMakeLists.txt即可生成一个Makefile代码来构建这个目标。 + +  整个SDK由很多的CMakeLists.txt文件组成,绝大多数的CMakeLists.txt文件负责把该目录的源码编译成一个库,SDK通过链接不同功能的库来构建不同的应用程序。 + +```code +./application/CMakeLists.txt +./application/HuntingCamera/CMakeLists.txt +./CMakeLists.txt +./hal/CMakeLists.txt +./middleware/AppManager/CMakeLists.txt +./middleware/CMakeLists.txt +./test/all/CMakeLists.txt +./test/application/CMakeLists.txt +./test/application/HuntingCamera/CMakeLists.txt +./test/application/MissionManager/CMakeLists.txt +./test/application/MissionManager/tool/CMakeLists.txt +./test/application/VersionReleaseTool/CMakeLists.txt +./test/CMakeLists.txt +./test/hal/CMakeLists.txt +./test/hal/tool/CMakeLists.txt +./test/middleware/AppManager/CMakeLists.txt +./tools/clang-tidy/CMakeLists.txt +./utils/CMakeLists.txt +./utils/Config/CMakeLists.txt +./utils/ConfigBase/CMakeLists.txt +``` + +### 1.4.2. 一个CMakeLists.txt示例 + +  CMakeLists.txt可以通过调用一些shell脚本来完成除编译之外的其它工具,例如:格式化代码。 + +```code + +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_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 +) + +#do not rely on any other library +#link_directories( // 该目标需要链接依赖的库的目录,因为是目标是库,无需链接,此设置无 +#) + +aux_source_directory(./src SRC_FILES) // 需要编译的源码文件,此处是src目录下的所有文件 + +set(TARGET_NAME StatusCode) // 设置输出目标名称 +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} Log) // 该目标需要依赖的库,这一步很关键,cmake将会根据依赖关系自动去编译需要的依赖库; + +if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") +add_custom_target( // 静态检测代码 + StatusCode_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/StatusCode +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( // 格式化代码 + StatusCode_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/StatusCode +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make StatusCode_code_check + COMMAND make StatusCode_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) // 该函数实现log库打印时,可打印文件名 + +file(GLOB_RECURSE INSTALL_HEADER_FILES include/*.h) +install(FILES ${INSTALL_HEADER_FILES} DESTINATION include) // 拷贝头文件到安装目录 +``` + +### 1.4.3. 通过CMakeLists.txt构建开源库 + +  通过CMakeLists.txt构建开源库,可以自动关联第三方的依赖库,编译的时候自动按需编译对应的开源库。 + +```code + +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +include(build/config_base.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 + ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +aux_source_directory(./src SRC_FILES) + +set(TARGET_NAME ConfigBase) +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} StatusCode Log libconfig.a) + +if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") +add_custom_target( + ConfigBase_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/ConfigBase +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make ConfigBase_code_check + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + ConfigBase_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/ConfigBase +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make ConfigBase_code_check + COMMAND make ConfigBase_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +# build libconfig before make libConfigBase.a +add_custom_command( + # OUTPUT ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a + OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a // 创建这个开源库输出文件的生成方法 + COMMAND echo "Build libconfig-1.7.3. COMPILE_HOST = ${COMPILE_HOST}" + # COMMAND tar zxvf libconfig-1.7.3.tar.gz + COMMAND sh build_libconfig.sh ${TARGET_PLATFORM} ${COMPILE_HOST} + # 把生成的开源库拷贝到输出目录 + COMMAND mv ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/ +) +add_custom_target( + libconfig.a // 创建一个库目标 + # DEPENDS ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a + DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a // 这个目标依赖开源库的编译输出文件 +) + +define_file_name(${TARGET_NAME}) +config_owner(${TARGET_NAME}) + +file(GLOB_RECURSE INSTALL_HEADER_FILES include/*.h) +install(FILES ${INSTALL_HEADER_FILES} DESTINATION include) +``` diff --git a/doc/design.md b/doc/design.md new file mode 100644 index 00000000..b9e60e30 --- /dev/null +++ b/doc/design.md @@ -0,0 +1,1103 @@ +# 1. 设计文档 + +## 1.1. 产品概述 + +  一款低功耗的IPC产品设计方案。 + +### 1.1.1. 名词说明: +MCU:外接的单片机; +小核:rk1106内置的单片机 +大核:rk1106 linux部分业务 + +## 1.2. 结构设计 +1. 迷彩外观; +2. 抽屉式电池箱组; +3. 捆绑/相机支架安装方式; +4. 可拓展4G模块; +5. 户外防水等级? + +### 1.2.1. 结构 + +| 物料 | 备注 | +|----|----| +| 喇叭 | - | +| 麦克风 | - | +| 按键 | 恢复出厂
SD卡格式化
TEST拨键
硬件电源开关 | +| 指示灯 | RGB三色灯 | +| 红外灯 | 940nm | +| usb | TYPEC,充电 | +| 太阳能板 | - | +| 电池仓 | - | +| TF卡卡槽 | - | +| PIR | - | + +### 1.2.2. 配件 + +| 物料 | 备注 | +|----|----| +| 捆绑轧带 | - | +| 快充电池 | - | +| 快充适配器 | - | + +## 1.3. 硬件设计 + +### 1.3.1. 关键外设 +1. 双摄像头; +2. PIR sensor; +3. IR leds; +4. 电池(箱体); +5. 电源开关; +6. 复位按键:同步/复位/格式化; +7. 功能按键:拍摄/cpu通电启动/ +8. tf card; +9. usb接口; +10. 光感传感器:白天/黑夜; +11. 单色指示灯:设备状态(工作/WiFi连接/异常); + +## 1.4. 软件设计 + +### 1.4.1. 多态单例设计模式 + +  多态单例模式包含两部分:抽象接口 + 抽象接口实例,代码基于抽象接口存在,业务基于抽象接口实例存在。 + +#### 1.4.1.1. 多态单例图示 + +  下述图示分别为:类图 / 依赖关系图 / 编译链接关系图 +```mermaid +classDiagram + APP --> AbstractInterface:使用 + AbstractInterface <|.. Instance:实现 + 应用 --> 抽象接口库:依赖 + 抽象接口库 ..> 实例库:依赖 + main线程 --> 抽象接口代码库:链接 + main线程 --> 实例代码库:链接 +``` +#### 1.4.1.2. 多态单例模块使用时序图 + +  在使用多态单例设计模式开发功能模块时,使用统一的命名规则: +* 抽象接口命名:xxx + Abstract,例如:libLogAbstract.a; +* 实例库命名:xxx + 具体实例名称,例如:libLogEasylogging.a; + +**调用关系如下图** +```mermaid +sequenceDiagram +User ->> +libLogAbstract.a:调用抽象接口 +libLogAbstract.a --> +libLogEasylogging.a:实际调用实例接口 +libLogEasylogging.a --> -libLogAbstract.a:return +libLogAbstract.a -->> -User:return +``` +**只有main函数实际调用实例库的实例化接口时,log功能才会生效。** + +#### 1.4.1.3. 多态单例目录结构规范 + +  根据多态单例设计模式,指定使用多态单例模式开发的模块的源码目录结构,耦合思路清晰。 +``` +└── Log // 多态单例模式模块的目录 + ├── include // 多态单例模块对外暴露的头文件目录,抽象接口定义 + │   └── ILogAbstract.h + ├── abstract // 多态单例模式抽象接口声明 + │   └── ILogAbstract.cpp + └── src // 多态单例接口实例代码,目录名称可根据实际功能定义 + ├── LogAstract.cpp + └── LogAstract.h +``` +  构建时把abstract目录和src目录的源码分别编译成库,main线程根据实际需要链接并实例化即可。 + +#### 1.4.1.4. 混合多态单例 + +  多态单例的分类有C++版本多态单例,C语言版本多态单例,混合(C/C++)多态单例。混合多态单例的提出是由于纯C语言多态单例开发难度较高,纯C++语言的多态单例不适合底层(特指本文的分层结构中的适配层)接口为C++时,很多C语言代码调用困难。 + +  混合多态单例,内部多态实现使用C++,保留C++开发便捷性和易维护性(智能指针),对外同时提供C语言多态抽象接口和C++多态抽象接口,满足C/C++混编时易用性。最大特点是include文件夹里面会包含两个头文件。 + +##### 1.4.1.4.1. 多态单例目录结构 +``` +hal +├── abstract // 抽象接口库的基础代码 +│   ├── IHal.cpp +│   └── IHalCpp.cpp +├── include +│   ├── IHalCpp.h // C++抽象接口头文件 +│   └── IHal.h // C语言抽象接口头文件 +└── src // 抽象接口实例库代码 + ├── Hal.c // C语言接口实例 + ├── HalCpp.cpp // C++接口实例 + ├── HalCpp.h + ├── Hal.h + ├── HalMakePtr.cpp // 负责创建内部实例 + └── HalMakePtr.h +``` + +#### 1.4.1.5. 多态单例总结: + +1. 应用代码只使用抽象接口,禁止直接依赖实例代码; +2. 应用代码只有在main线程初始化时实例化实例模块即可; +3. 多态单例模块由两个库组成,一个是抽象接口库,一个是实例代码库,支持静态多态和动态多态; + +### 1.4.2. 产品业务功能设计 + +  基于芯片大小核架构的启动设计。 + +#### 1.4.2.1. 白/黑切换状态启动 + +  由外置单片机检测光敏adc,判断由白天切换到黑夜或者黑夜切换到白天时,主动给主控上电,主控上电后会校验并保存新的环境参数,以下次正常PIR启动时,可以避免ircut耗时快速收敛第一帧,最大程度实现快启功能。 + +**启动时序图** + +```mermaid +sequenceDiagram +participant MCU +participant 小核 +participant 大核 +loop 光敏检测 + MCU ->> MCU:定时唤醒(定时时间待定) + opt 光敏>>>黑夜状态 + note over MCU:由外置单片机点亮红外补光灯 + MCU ->> MCU:点亮红外灯 + end + opt 光敏>>>黑/白切换 + MCU ->> 小核:上电 + activate 小核 + note over 小核:根据上次启动的ircut切换条件初始化ircut IO
本次启动上次的切换条件是异常的 + 小核 ->> 小核:ircut切换-消耗0ms + 小核 ->> 小核:Sensor初始化 + 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 + activate 大核 + 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms + 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms + 大核 ->> 大核:启动脚本启动APP-?ms + 大核 ->> +MCU:获取启动模式 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复启动模式 + opt 黑/白切换状态 + 大核 ->> +MCU:获取黑/白状态 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复黑或者白 + opt 黑/白状态不符合抓拍的初始化参数 + 大核 ->> 大核:ircut重新切换 + 大核 ->> 大核:重新初始化sensor参数 + end + 大核 ->> MCU:关机 + MCU ->> 大核:断电 + end + deactivate 大核 + end +end +``` + +#### 1.4.2.2. 红外触发状态启动(正常工作快启) + +  红外触发启动作为产品正常工作时最经常最重要的启动状态。启动后快速抓拍/录像,快速关机。 + +1. 为保证快启速度,IRCUT需要业务设计进行提前切换; +2. 每次启动抓拍/录像完,需要校验IRCUT状态,保证sensor初始化参数和环境相匹配; +3. 如果发生sensor初始化参数和光照环境不匹配,需要重新初始化sesor并补拍; + +**启动时序图** + +```mermaid +sequenceDiagram +participant MCU +participant 小核 +participant 大核 +MCU ->> MCU:PIR中断唤醒 +opt 光敏>>>黑夜状态 +note over MCU:由外置单片机点亮红外补光灯 + MCU ->> MCU:点亮红外灯 +end +opt PIR信号触发 + alt 主控未开机 + MCU ->> 小核:上电 + activate 小核 + note over 小核:根据上次启动的ircut切换条件初始化ircut IO
消耗0ms是由于ircut IO会提前切换好 + 小核 ->> 小核:ircut切换-消耗0ms + 小核 ->> 小核:Sensor初始化 + 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 + activate 大核 + 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms + 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms + 大核 ->> 大核:启动脚本启动APP-?ms + 大核 ->> +MCU:获取启动模式 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复启动模式 + opt PIR触发状态 + 大核 ->> +MCU:获取黑/白状态 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复黑或者白 + alt sensor初始化参数和环境参数匹配 + note over 大核:环境参数未发生变化时,可直接保存快启的抓拍 + 大核 ->> 大核:保存到sd卡-?ms + else sensor初始化参数和环境参数不匹配 + note over 大核:环境参数发生变化时,需要重新初始化sensor并补拍 + 大核 ->> 大核:ircut重新切换 + 大核 ->> 大核:重新初始化sensor参数 + 大核 ->> 大核:重新抓拍/录像 + 大核 ->> 大核:保存到sd卡-?ms + end + end + alt TEST拨键-OFF + 大核 ->> MCU:关机 + MCU ->> 小核:断电 + MCU ->> 大核:断电 + else TEST拨键-ON + opt 超时关机 + 大核 ->> MCU:关机 + MCU ->> 小核:断电 + MCU ->> 大核:断电 + end + end + deactivate 大核 + else 主控已经开机 + MCU ->> +大核:发送抓拍指令 + 大核 ->> 大核:抓拍 + 大核 ->> MCU:回复抓拍 + 大核 ->> 大核:保存抓拍 + 大核 ->> -MCU:关机指令 + MCU ->> 大核:断电 + end +end +``` + +#### 1.4.2.3. 定时触发状态启动 + +**定时触发状态启动时序图** + +```mermaid +sequenceDiagram +participant MCU +participant 小核 +participant 大核 +MCU ->> MCU:定时中断唤醒 +opt 光敏>>>黑夜状态 +note over MCU:由外置单片机点亮红外补光灯 + MCU ->> MCU:点亮红外灯 +end +opt 根据定时参数上电 + MCU ->> 小核:上电 + activate 小核 + note over 小核:根据上次启动的ircut切换条件初始化ircut IO
消耗0ms是由于ircut IO会提前切换好 + 小核 ->> 小核:ircut切换-消耗0ms + 小核 ->> 小核:Sensor初始化 + 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 + activate 大核 + 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms + 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms + 大核 ->> 大核:启动脚本启动APP-?ms + 大核 ->> +MCU:获取启动模式 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复启动模式 + opt 定时启动状态 + 大核 ->> +MCU:获取黑/白状态 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复黑或者白 + alt sensor初始化参数和环境参数匹配 + note over 大核:环境参数未发生变化时,可直接保存快启的抓拍 + 大核 ->> 大核:保存到sd卡-?ms + else sensor初始化参数和环境参数不匹配 + note over 大核:环境参数发生变化时,需要重新初始化sensor并补拍 + 大核 ->> 大核:ircut重新切换 + 大核 ->> 大核:重新初始化sensor参数 + 大核 ->> 大核:重新抓拍/录像 + 大核 ->> 大核:保存到sd卡-?ms + end + end + note over 大核:定时状态启动抓拍完直接关机 + 大核 ->> MCU:关机 + MCU ->> 小核:断电 + MCU ->> 大核:断电 + deactivate 大核 +end +``` + +#### 1.4.2.4. 设置/调试状态启动 + +  特殊的启动状态,可以较长时间通电完成其它功能,期间可供用户完成相关调试和参数设置,此时功耗较高。超时进入工作模式。 + +1. 设置状态按键触发CPU上电,首先进入设置状态启动,5分钟后自动切换到工作状态。 + +**设置状态启动时序图** + +```mermaid +sequenceDiagram +participant MCU +participant 小核 +participant 大核 +MCU ->> MCU:待机 +opt 光敏>>>黑夜状态 +note over MCU:由外置单片机点亮红外补光灯 + MCU ->> MCU:点亮红外灯 +end +opt TEST拨键-ON + MCU ->> 小核:上电 + activate 小核 + MCU ->> 大核:上电 + activate 大核 + note over 小核:根据上次启动的ircut切换条件初始化ircut IO
消耗0ms是由于ircut IO会提前切换好 + 小核 ->> 小核:ircut切换-消耗0ms + 小核 ->> 小核:Sensor初始化 + 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 + 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms + 大核 ->> 大核:启动脚本启动APP-?ms + 大核 ->> +MCU:获取启动模式 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复启动模式 + opt TEST状态 + 大核 ->> +MCU:获取黑/白状态 + note over 大核:大核启动后,需要通过串口获取启动模式,
来执行后续的任务 + MCU -->> -大核:回复黑或者白 + opt sensor初始化参数和环境参数不匹配 + note over 大核:环境参数发生变化时,需要重新初始化sensor并补拍 + 大核 ->> 大核:ircut重新切换 + 大核 ->> 大核:重新初始化sensor参数 + end + alt WiFi链接 + 大核 ->> 大核:常通电待机 + else 无WiFi连接/无操作 + opt 超时 + 大核 ->> MCU:关机 + MCU ->> 小核:断电 + MCU ->> 大核:断电 + end + end + end + deactivate 大核 +end +``` + +#### 1.4.2.5. 厂测状态启动 + +  生产测试状态触发:使用tf card配置文件触发生产测试状态; + +**厂测状态启动时序图** + +```mermaid +sequenceDiagram +participant MCU +participant 小核 +participant 大核 +MCU ->> MCU:物理上电 +MCU ->> 小核:上电 + activate 小核 + MCU ->> 大核:上电 + activate 大核 + 小核 ->> 小核:Sensor初始化 + 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 + 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms + 大核 ->> 大核:启动脚本启动APP-?ms + alt TEST拨键-ON + alt tf card厂测配置文件存在 + 大核 ->> 大核:常通电待机 + else tf card厂测配置文件不存在 + opt 超时 + 大核 ->> MCU:关机 + MCU ->> 小核:断电 + MCU ->> 大核:断电 + end + end + else TEST拨键-OFF + alt tf card厂测配置文件存在 + 大核 ->> 大核:常通电待机 + else tf card厂测配置文件不存在 + 大核 ->> MCU:关机 + MCU ->> 小核:断电 + MCU ->> 大核:断电 + end + end + deactivate 大核 +``` + +#### 1.4.2.6. 快启时序时间消耗 + +```mermaid +sequenceDiagram +participant MCU +participant 小核 +participant 大核 +MCU ->> MCU:PIR中断唤醒 +note right of MCU:设此时为时间轴0ms +MCU ->> 小核:上电 +MCU ->> 大核:上电 +activate MCU +activate 小核 +activate 大核 +note right of 大核:竞品时间12ms + opt 光敏>>>黑夜状态 + note over MCU:由外置单片机点亮红外补光灯 + MCU ->> MCU:点亮红外灯 + end +deactivate MCU + opt PIR信号触发 + alt 主控未开机 + note over 小核:根据上次启动的ircut切换条件初始化ircut IO
消耗0ms是由于ircut IO会提前切换好 + note right of 大核:竞品在CPU启动后,获取MCU的光敏值
再切ircut和打开红外灯-时间168ms + 小核 ->> 小核:ircut切换-消耗0ms + 小核 ->> 小核:Sensor初始化 + 小核 --> 大核:Sensor初始化完成-100ms +deactivate 小核 + activate 大核 + 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms + note right of 大核:竞品第一帧时间350ms + 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms + 大核 ->> 大核:启动脚本启动APP-?ms + deactivate 大核 + end + end +deactivate 大核 +``` + +### 1.4.3. 根据软件模块作用域分层 + +#### 1.4.3.1. 应用层(application) + +##### 1.4.3.1.1. 应用层概述 + +  应用层负责处理产品级的复杂业务关系,是产品功能的直接体现,应用层模块全部使用C++接口的多态单例模式设计,各模块之间可以互相调用接口,应用层各库可以随意任意调用中间件或者工具类接口。 + +##### 1.4.3.1.2. 网络服务模块 + +###### 1.4.3.1.2.1. 网络服务概述 + +  根据产品联网属性,网络服务模块分为不联网 / 联网(B端)/ 联网(自研)三个多态属性。联网时,IPC的图片 / 视频资源通过网络服务器进行管理。 + +1. 不联网版本:网络服务模块不实例化即可; +2. 联网(B端):媒体资源由三方服务器管理; +3. 联网(自研):媒体资源由自研服务器管理; + +###### 1.4.3.1.2.2. 网络服务多态设计模式 + +  通过构建配置文件选择需要实例化的网络服务模块代码。 + +##### 1.4.3.1.3. 相机任务管理 + +  相机主业务逻辑使用状态机机制进行管理。 + +###### 1.4.3.1.3.1. 任务状态 + +  任务状态是指相机启动需要执行的任务,可能是拍照 / 视频,可能是其它任务。 + +**例如:** +1. 移动物体侦测启动; +2. 定时启动拍照 / 录像; +3. 测试启动; + +###### 1.4.3.1.3.2. 状态机设计 + +```mermaid +stateDiagram-v2 +[*] --> TopState +TopState --> PowerOff +TopState --> MSDCState +TopState --> DeviceAbnormal +TopState --> MissionState +MissionState --> 存储管理 +存储管理 --> EMMC +存储管理 --> SD卡 +SD卡 --> 插卡 +SD卡 --> 拔卡 +SD卡 --> 卡异常 +MissionState --> 网络管理 +网络管理 --> 联网 +联网 --> 上传文件 +网络管理 --> 未联网 +MissionState --> 直播 +MissionState --> 4G管理 +4G管理 --> Sim卡初始化 +4G管理 --> 注网状态 +MissionState --> Upgrade +``` + +###### 1.4.3.1.3.3. 任务状态获取启动 + +  应用程序运行后,首先需要知道主控是由于何种任务被唤醒,然后根据任务来执行相应的功能代码; + +**时序图** + +```mermaid +sequenceDiagram +participant MCU +participant 大核 +MCU ->> MCU:待机 +opt MCU上电 + MCU ->> 大核:上电 + activate 大核 + 大核 ->> 大核:系统初始化 + 大核 ->> 大核:启动脚本拉起APP + 大核 ->> +MCU:读取启动任务 + MCU -->> -大核:return + alt PIR触发 + 大核 ->> 大核:APP初始化 + 大核 ->> 大核:抓拍并保存 + else 定时 + 大核 ->> 大核:APP初始化 + 大核 ->> 大核:抓拍并保存 + else TEST + 大核 ->> 大核:APP初始化 + 大核 ->> 大核:待机 + end + deactivate 大核 +end +``` + +#### 1.4.3.2. 中间件(middleware) + +##### 1.4.3.2.1. 中间件概述 + +  一些相对中性的业务功能库,这些库可以提供给不同的产品需求使用,在应用层不同的调用方式可实现不同的产品功能。中间件只能被应用层调用或者向下调用适配层或者调用工具库,中间件各模块之间不能互相调用。中间件库接口可以使用C或者C++接口。 + +##### 1.4.3.2.2. 设备管理模块 + +  设备,统指Linux的设备节点,应用层唯一的硬件设备接口库。包含灯 / 按键 / GPIO / SD卡 / 串口 / USB等。 + +##### 1.4.3.2.3. 相机管理模块 + +  应用层唯一的摄像头接口库。 + +##### 1.4.3.2.4. MCU管理模块 + +  MCU通信接口库,一般使用串口进行通信,需要考虑多态其它接口(例如I2C),考虑多态协议数据结构。MCU负责管理外设的电源控制 / 充当硬狗等。 + +###### 1.4.3.2.4.1. MCU管理模块设计模式 + +  使用C++接口的多态单例模式。 + +基本功能: + +1. 使用utils当中的串口功能模块,支持多态切换到其它串口功能模块; +2. 设置MCU管理的监视器monitor,用于回调处理MCU接受到的业务事件; +3. 通信协议不暴露,内部处理基于协议的数据解析 / 组包; +4. 通信协议支持多态拓展,通信协议独立成库; + +##### 1.4.3.2.5. MCU协议模块 + +  负责对MCU协议进行封包/解包,负责协议的多态替换。协议数据统一使用网络字节序(大端字节序)。 + +###### 1.4.3.2.5.1. 协议格式 + +| 协议头 | 流水号 | 命令字 | 长度 | 数据段 | 校验码 | +|----|----|----|----|----|----| +| 2字节
0xFAC1 | 4字节 | 2字节 | 2字节 | - | 2字节 | + +**流水号** + +  流水号用于强绑定问答型协议的发送数据和回复数据,回复者原数据回传即可。例如: + +``` +unsigned char ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01, 0x00, 0x0C, 0x71, 0x88}; +unsigned char REPLY_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89}; +``` + +  流水号管理发送方和接收方互相独立,各自往外发的协议中流水号存在重复的可能,接收方直接复制回传即可。 + +  流水号必须大于等于1,0用于代码初始化值,代码意义上表示无效的流水号。 + +**协议收发匹配逻辑** +  协议发送时,附带自管理的流水号,对端回复时,根据流水号绑定发送的协议,为了避免对端回复时,流水号错误导致的业务逻辑错乱,本端除了匹配流水号,还需要根据协议匹配回复的命令字,保证回复内容的有效匹配。如果流水号和命令字无法同时匹配,该回复的数据包被丢弃。 + +**校验码算法** + +  校验码算法使用ModBus CRC16方法计算。 + +**参考代码(查表法)** + +``` +/* Table of CRC values for high–order byte */ +unsigned char chCRCHi[] ={ + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 +}; + +/* Table of CRC values for low–order byte */ +unsigned char chCRCLo[] ={ + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, + 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, + 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, + 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, + 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, + 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, + 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, + 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, + 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, + 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, + 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, + 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, + 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, + 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, + 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 +}; +/** + * @brief 计算校验和 + * + * @param pData 数据指针 + * @param length 数据长度 + * @return unsigned short + */ +unsigned short calculate_check_sum(const unsigned char* pData, unsigned short length) +{ + unsigned char CRCHi = 0xFF; + unsigned char CRCLo = 0xFF; + int uIndex; + while (length--) + { + uIndex = CRCHi ^ *pData++; + CRCHi = CRCLo ^ chCRCHi[uIndex]; + CRCLo = chCRCLo[uIndex]; + } + return (CRCHi << 8 | CRCLo); +} +``` + +###### 1.4.3.2.5.2. 协议内容 + +**基本描述** +1. 大于等于0x8000的命令字由CPU发给MCU; +2. 小于0x8000的命令字由MCU发给CPU; +3. 大于0x0801而小于0xC101的命令由CPU主动发送给MCU,大于等于0xC101的命令由CPU回复发送给MCU; +4. 问答型协议只有按位最高位相反,其它位相等,例如:0x8101与0x0101是一问一答的协议; + +| 命令字 | CPU | MCU | 数据段 | 协议解析 | 备注 | +|----|----|----|----|----|----| +| 0x8101 | ask | - | - | 获取启动模式 | - | +| 0x0101 | - | reply | Data[0]:启动模式
0x01:PIR启动
0x02:TEST启动
0x03:连拍启动
0x04:PIR延时启动
0x05:定时(间隔一定时间)启动
0x06:关机
0x07:低电关机 | 回复启动模式 | - | +| 0x8102 | ask | - | - | 断电关机 | - | +| 0x8103 | ask | - | - | 喂狗 | - | +| 0x8104 | ask | - | Data[0]:Hour
0-23
Data[1]:Min
0-59
Data[2]:Sec
0-59 | 开启狗/设置喂狗周期 | - | +| 0x0104 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 开启狗/设置喂狗周期回复 | - | +| 0x8105 | ask | - | - | 关闭狗 | - | +| 0x0105 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 关闭狗回复 | - | +| 0x8106 | ask | - | Data[0]:Hour
0-23
Data[1]:Min
0-59
Data[2]:Sec
0-59 | 设置间隔启动时间 | - | +| 0x0106 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置间隔启动时间回复 | - | +| 0x8107 | ask | - | Data[0]:Year
Data[1]:Mon
1-12
Data[2]:Day
0-31
Data[3]:Hour
0-23
Data[4]:Min
0-59
Data[5]:Sec
0-59 | 设置日期和时间 | - | +| 0x0107 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置日期和时间回复 | - | +| 0x8108 | ask | - | Data[0]:灵敏度
0-9 | 设置PIR灵敏度 | - | +| 0x0108 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置PIR灵敏度回复 | - | +| 0x8109 | ask | - | Data[0]:Hour
0-23
Data[1]:Min
0-59
Data[2]:Sec
0-59 | 设置连拍间隔 | - | +| 0x0109 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置连拍间隔回复 | - | +| 0x810A | ask | - | Data[0]:控制模式
0-关闭红外灯
1-开启红外灯 | 红外灯控制 | - | +| 0x010A | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 红外灯控制回复 | - | +| 0x810B | ask | - | - | 获取光敏值 | - | +| 0x010B | - | reply | Data[0]:结果
0-100 | 获取光敏值回复 | - | +| ====== | === | ====== | ============================ | ==================== | ======= | +| 0xC101 | reply | - | Data[0]:结果
0x01:成功
0x02:失败 | 发送启动模式回复 | - | +| 0x4101 | - | ask | Data[0]:启动模式
0x01:PIR启动
0x02:TEST启动
0x03:连拍启动
0x04:PIR延时启动
0x05:定时(间隔一定时间)启动
0x06:关机
0x07:低电关机 | 发送启动模式 | - | + +##### 1.4.3.2.6. IPC配置库 + +  负责管理IPC产品相关的配置数据。 + +###### 1.4.3.2.6.1. IPC配置库设计模式 + +  使用多态单例设计模式,对外提供C语言接口,内部不局限使用C或者C++。 + +**基本功能** + +1. 敏感数据(例如:账号 / 密码)需要加密处理; +2. 读到内存使用二进制数据,缓存到数据结构体; +3. 调用utils工具里面的配置库,对配置文件进行读 / 写; +4. 使用二进制结构体 + 明文配置文件结合的模式,既可减少内存消耗,又可以规避二进制数据升级迭代数据匹配困难问题; +5. 使用枚举方式管理IPC配置数据定义,当使用纯16进制保存数据时,可不链接utils工具里面的配置库,直接保存16进制数据到文件系统即可; +6. 应用程序全局唯一可以操作IPC配置文件的库,保证配置文件正确读写; + +###### 1.4.3.2.6.2. IPC配置库类图 +```mermaid +classDiagram + i_ipc_config <.. ipc_config:实现 + ipc_config --> i_config_manager:依赖 + ipc_config --> IHal:依赖 + i_config_manager <.. config_manager:实现 + config_manager --> libconfig开源库:依赖 +``` + +###### 1.4.3.2.6.3. 关键业务时序图 + +  **时序图会忽略抽象接口直接使用实例接口表示。** + +* IPC配置库初始化 / 解初始化 +```mermaid +sequenceDiagram +participant User +participant ipc_config +participant i_config +participant IHal +User ->> +ipc_config:初始化 + ipc_config ->> +IHal:获取文件系统路径 + IHal -->> -ipc_config:return + ipc_config ->> +i_config:打开配置文件 + i_config -->> -ipc_config:return + alt 打开成功 + rect rgba(255,220,200,1) + loop 读取所有数据到IPC数据结构体 + ipc_config ->> +i_config:读取一个数据到IPC数据结构体 + i_config -->> -ipc_config:return + rect rgba(255,255,200,1) + opt 读取失败 + ipc_config ->> ipc_config:生成默认数据 + ipc_config ->> +i_config:设置默认数据 + i_config ->> -ipc_config:return + end + end + end + ipc_config ->> +i_config:关闭配置文件 + i_config -->> -ipc_config:return + end + else 打开失败 + rect rgba(255,200,200,1) + ipc_config ->> ipc_config:生产默认数据 + ipc_config ->> +i_config:创建配置文件 + i_config -->> -ipc_config:return + ipc_config ->> +i_config:设置默认数据 + i_config -->> -ipc_config:return + ipc_config ->> +i_config:关闭配置文件 + i_config -->> -ipc_config:return + end + end +ipc_config -->> -User:return +User ->> +ipc_config:解初始化 + ipc_config ->> ipc_config:释放内存中的数据 +ipc_config -->> -User:return +``` + +* 读 / 写(修改)数据 + +```mermaid +sequenceDiagram +participant User +participant ipc_config +User ->> +ipc_config:读取数据 + ipc_config ->> ipc_config:返回内存保存的数据 +ipc_config -->> -User:return +User ->> +ipc_config:修改数据 + ipc_config ->> ipc_config:修改内存保存的数据 +ipc_config -->> -User:return +``` + +* 保存数据 + + +```mermaid +sequenceDiagram +participant User +participant ipc_config +participant i_config +User ->> +ipc_config:保存 + ipc_config ->> +i_config:打开配置文件 + i_config -->> -ipc_config:return + ipc_config ->> +i_config:同步数据 + i_config -->> -ipc_config:return + ipc_config ->> +i_config:保存配置文件 + i_config -->> -ipc_config:return + ipc_config ->> +i_config:关闭配置文件 + i_config -->> -ipc_config:return +ipc_config -->> -User:return +``` + + +##### 1.4.3.2.7. 高级配置库 + +  对配置库的二级封装,提供更便捷的功能服务,例如:可以监控文件的修改事件 / 可以直接捕获某个配置文件或者数据的操作对象。 + +###### 1.4.3.2.7.1. 高级配置库设计 + +  对外暴露C++接口,使用多态单例设计模式。 + +##### 1.4.3.2.8. 状态机管理 + +  提供实现状态机管理机制C++接口,使用鸿蒙状态机开源源码进行改造封装。 + +###### 1.4.3.2.8.1. 状态机管理设计模式 + +  使用多态单例设计模式,暂定使用鸿蒙状态机开源代码改造实现,后续可替换其它源码或者自研代码。 + +##### 1.4.3.2.9. 文件数据库 + +  文件数据库负责管理设备的媒体资源(图片 / 视频等)。 + +###### 1.4.3.2.9.1. 文件数据设计模式 + +  使用混合多态单例模式开发。 + +###### 1.4.3.2.9.2. 开源库选型 + +  sqlite3开源库,编译成工具类库提供给文件数据库使用。 + +###### 1.4.3.2.9.3. 基本功能和业务需求 + +1. 对媒体资源文件的增删改查处理; +2. 记录媒体资源文件的生成时间,任务(是否发送); +3. 业务根据需要,通过数据库判断哪些文件已经发送完成,哪些文件发送失败,哪些文件待发送; + +#### 1.4.3.3. 硬件适配层(hal) + +  负责适配不同的硬件平台。 + +##### 1.4.3.3.1. 硬件适配层设计模式 + +  基于C语言接口的多态单例模式,编译时静态多态链接对应的芯片平台适配代码,实现芯片接口的标准功能定义。 + +##### 1.4.3.3.2. 媒体适配方案: + +  IPC应用在适配芯片平台的多媒体接口时,使用多进程的方式实现。满足IPC应用可以快起(无需等待媒体相关的初始化)的需求。 + +**媒体基本需求** + +1. 图片抓拍; +2. 视频抓拍; + +**多进程通信方案** + +  使用本地socket的方式进行多进程通信,媒体进程为客户端,IPC应用为服务端(IPC先启动)。 + +1. 客户端可自动重连; +2. 服务端可多次关闭和开启,满足gtest资源回收需求; + +##### 1.4.3.3.3. 适配层多进程类图 + +```mermaid +classDiagram + i_hal <.. hal:实现 + hal --> v_media_handle:依赖 + v_media_handle --> local_socket:依赖 + local_socket .. media进程:跨进程 + media进程 --> 芯片媒体API:依赖 +``` + +##### 1.4.3.3.4. 跨进程业务时序图 + +* 本地socket链接 + +```mermaid +sequenceDiagram +participant hal +participant v_media_handle +participant local_socket_s +participant local_socket_c +participant media进程 +participant 芯片媒体API +hal ->> +v_media_handle:初始化 + v_media_handle ->> +local_socket_s:本地socket服务端启动 + par 本地socket初始化 + local_socket_s -->> -v_media_handle:return +v_media_handle -->> -hal:return + and + media进程 ->> media进程:启动 + media进程 ->> +local_socket_c:初始化服务端 + local_socket_c -->> local_socket_s:链接 + local_socket_c -->> -media进程:return + local_socket_s -->> local_socket_c:初始化媒体 + local_socket_c ->> media进程:回调回传协议事件 + media进程 ->> +芯片媒体API:初始化媒体 + 芯片媒体API -->> -media进程:return + end +``` + +* 存在问题: +使用C语言开发时如何解决智能指针问题? + +#### 1.4.3.4. 工具库(utils) + +##### 1.4.3.4.1. 工具库概述 +  工具库是功能单一的不依赖任何三方库的独立库(日志库和返回码管理库除外),必须提供C语言接口,内部实现不限于C或者C++。工具类库可以被任意的其它模块调用,特别指hal/component/application三大层级。 + +##### 1.4.3.4.2. 日志库 + +###### 1.4.3.4.2.1. 日志库概述 +  提供程序的日志管理功能,含日志的实时打印/保存/跟踪(实时上传云端)。 + +###### 1.4.3.4.2.2. 日志库设计模式 +  C语言接口的多态单例模式,可动态/静态加载多态实例。 + +###### 1.4.3.4.2.3. 日志库启动 +  日志库是否启用一般来讲是dubug版本启用日志功能,release版本禁用日志功能,考虑到release版本的维护问题,标准启动时,main线程在启动时使用dlopen系列函数去加载日志库(多态),特殊版本仍可在main线程加载日志库后,二次实例化日志库(多态)来实现不同的日志功能。 + +1. 标准流程:main线程加载sd卡动态库,如有即可动态实现日志功能,正常出货sd卡不带日志库,此时没有日志功能; +2. 可以通过配置参数决定是否启用日志; +3. sd卡的日志动态,根据实际售后维护,可以是实时打印log/保存本地log/云log的多态实例库; +4. 多态日志功能,可以忽略debug和release版本的区别,只发布一个版本即可; + +##### 1.4.3.4.3. 状态码管理库 + +  提供整个应用程序的返回码管理功能,例如:打印返回码的字符串含义。提供C语言接口,纯C语言开发的模块,形成项目内部唯一返回码标准。 + +###### 1.4.3.4.3.1. 状态码功能 + +1. 创建返回码操作“句柄”; +2. 打印返回码/获取返回码(字符串); +3. 不同模块可继承实现各自的返回码处理接口; +4. 不同模块之间可透传状态码,避免错误码的转换麻烦; +5. 状态码的定义是跟着模块走的,独立模块的状态码定义在模块内部,不链接时不占用程序空间; + +###### 1.4.3.4.3.2. 基础状态码定义 + +  基础状态码是全局的基础状态码,枚举值全局唯一,其它独立模块必须继承基础状态码累加枚举值,但是,独立模块之间的枚举值可重复,状态码在使用时,日志只关注状态码的字符串,不关心状态码枚举值,代码逻辑使用枚举值。 + +``` +enum STATUS_CODE +{ + STATUS_CODE_OK = 0, + STATUS_CODE_NOT_OK, + STATUS_CODE_VIRTUAL_FUNCTION, + STATUS_CODE_INVALID_PARAMENTER, + STATUS_CODE_END +}; +``` +| 枚举名 | 字符串 | 描述 | +| ------ | :------------------------------- | --------- | +| STATUS_CODE_OK | STATUS_CODE_OK | 成功 | +| STATUS_CODE_NOT_OK | STATUS_CODE_NOT_OK | 失败 | +| STATUS_CODE_VIRTUAL_FUNCTION | STATUS_CODE_VIRTUAL_FUNCTION | 抽象接口,提示抽象接口未实例化 | +| STATUS_CODE_INVALID_PARAMENTER | STATUS_CODE_INVALID_PARAMENTER | 无效的参数 | +| STATUS_CODE_END | STATUS_CODE_END | 结束,无意义 | +| 其它 | ? | 其它状态码在各自模块定义 | + +###### 1.4.3.4.3.3. 已知漏洞 + +  状态码在代码层面是存在重复的可能性的,代码逻辑在使用状态码枚举值时,可能会出现逻辑错误。 + +* 解决方案 +在使用状态码进行逻辑判断时,使用状态码枚举值的字符串。 +Example: +``` +static inline bool StatusCodeEqual(const StatusCode code, const char *value) +``` + +##### 1.4.3.4.4. 系统标准接口库 + +  对系统标准接口的套壳封装,主要是为了对系统标准打桩满足测试需求。 + +  使用普通的C语言接口封装即可,通过使用gcc编译参数在Linux x86系统中满足打桩需求,在交叉编译(担心工具链兼容问题)测试程序中无法对系统标准接口进行打桩。 + +##### 1.4.3.4.5. 通用配置库 + +###### 1.4.3.4.5.1. 通用配置库概述 + +  配置库负责管理软件配置参数,对配置数据进行设置 / 获取 / 存储 / 备份 / 升级等功能;通用配置库不限制使用场景,是一个通用的配置文件管理库。 + +###### 1.4.3.4.5.2. 配置库设计模式 + +  对外提供C语言接口,内部不局限使用C或者C++。整个软件唯一可以直接操作文件系统配置文件的库。配置库可以理解为简单的三方库的接口直接封装,使用多态单例设计模式实现静态或者动态切换三方库的使用。 + +**基本功能** + +1. 使用**三方库**保存明文格式的配置文件到文件系统; +2. 可注册回调函数,监听文件的操作事件; +3. 使用字符串名字key + 值的方式管理配置文件,作为通用的配置文件管理库; + +###### 1.4.3.4.5.3. 开源库 + +两种方案: +1. 使用libconfig作为文件操作的开源库,实现文件和数据的读 / 写。 +2. 使用sqlite3作为文件操作的开源库,作为数据库文件处理。 + +###### 1.4.3.4.5.4. 通用配置库类图 +  多态单例设计模式,main线程静态链接多态库。 +```mermaid +classDiagram + i_config_manager <.. config_manager:实现 + config_manager --> libconfig开源库:依赖 + i_config_manager <.. sqlite_manager:实现 + sqlite_manager --> sqlite3数据库:依赖 +``` + +###### 1.4.3.4.5.5. 备份机制 + +  备份数据用于数据异常时可还原旧数据。 + +方案选择: +1. 出厂默认配置文件为只读文件,在数据破坏时还原; + +###### 1.4.3.4.5.6. 升级机制 + +  程序升级后配置数据发生增 / 删时如何兼容和还原。 + +##### 1.4.3.4.6. 串口功能模块 + +  串口的打开 / 关闭 / 数据读 / 数据写 功能。 + +###### 1.4.3.4.6.1. 串口开源库 +使用下述开源库对串口数据进行收发。 +``` +https://gitee.com/RT-Thread-Mirror/TinyFrame +``` + +##### 1.4.3.4.7. MCU协议库 + +  负责MCU通信协议的组包 / 拆包 / 事件转换。 + +###### 1.4.3.4.7.1. MCU协议库设计模式 + +  基于C语言的多态单例设计模式。 + +###### 1.4.3.4.7.2. 协议数据结构 + +##### 1.4.3.4.8. 多进程通讯库 + +  负责多进程之间的数据交换。使用local socket方式实现。 + +##### 1.4.3.4.9. 多进程协议库 + +  负责IPC应用和媒体进程之间的协议组包 / 拆包,在协议和业务之间进行转换接口的封装。 + +## 1.5. 生产测试/研发调试 + +  基于公版代码派生出来的特定的定制版本,用于辅助生产和测试。 + +## 1.6. 自动化测试 + +### 1.6.1. 自动化测试概述 + +  自动化测试是该产品设计的一大特点,需要严格执行。自动化测试指使用纯代码对业务设计进行测试用例设计,实现业务集成测试的能力。 + + +### 1.6.2. 自动化测试规范 + +1. 每个源码文件在开发时,均要写调试的example,用于验证该文件的接口功能;测试文件的命名规则为:文件名 + “_Test.c(pp)”; +例如: +* C语言:log_impl.c对应的测试文件为log_impl_Test.cpp; +* C++:LogImpl.cpp对应的测试文件为LogImpl_Test.cpp; + +## 1.7. 编码规范 + +1. 文件命名统一使用大驼峰命名规则; +2. 混合多态单例的C++抽象接口头文件需要有Cpp关键字标识; +3. 多单单例的头文件 / 类名 统一使用“I”前缀,interface的单词首字母; +4. 抽象对象接口类统一使用“V”前缀, virtual的单词首字母; +5. 所有函数统一使用大驼峰命名规则; +6. 其它遵循华为的编码规范要求; \ No newline at end of file diff --git a/doc/develop_standard.md b/doc/develop_standard.md new file mode 100644 index 00000000..c218327d --- /dev/null +++ b/doc/develop_standard.md @@ -0,0 +1,111 @@ +# 1. SDK开发规范 + +## 1.1. 编码规范 + +### 1.1.1. 指针/智能指针 + +* C++编码只能使用智能指针; +* 指针遵循谁使用谁进行“非空”判断,且无比使用前进行“非空”判断; +* 智能指针经过转换后务必进行“非空”判断; + +理论上,**明显不可能为空的指针,可以不进行“非空”判断**,可以不进行“非空”判断的场景: + +``` +void McuManagerImpl::OtherSideSendIpcMission(const unsigned int &serialNumber, const unsigned char &mission) +{ + class McuRecvIpcMission : public McuRecvImpl, public McuRecv + { + public: + McuRecvIpcMission(std::shared_ptr &mcuManager, const unsigned int &serialNumber, + const OtherSideSendType &sendType, const unsigned char &mission) + : McuRecvImpl(serialNumber, sendType) + { + McuRecv::mDataRecvReply = mission; + McuRecvImpl::mMcuManager = mcuManager; + } + ~McuRecvIpcMission() = default; + void ReplyFinished(const bool result) override + { + // 此处可以不进行“非空”判断,该值在有限范围内(OtherSideSendIpcMission函数内部)就能看出是否为空 + McuRecvImpl::mMcuManager->ReplyOtherSideSendIpcMission(ASK_RESULT::SUCCEED, McuRecvImpl::mSerialNumber); + } + }; + std::shared_ptr monitor = GetMcuMonitor(); + std::shared_ptr manager = std::dynamic_pointer_cast(SharedFromThis()); + std::shared_ptr recv = + std::make_shared(manager, serialNumber, OtherSideSendType::SEND_IPC_MISSION, mission); + if (monitor) { + monitor->RecvIpcMissionEvent(recv, static_cast(mission)); + } + else { + LogWarning("mMonitor is nullptr, AddMcuRecv.\n"); + AddMcuRecv(recv); + } +} +``` + +**没有进行“非空”判断的代码,应该开发测试用例,保证“空指针”的报错。** + +### 1.1.2. 注释 + +* 注释必须使用英文,且使用翻译器翻译; +  避免编码问题导致的乱码,且需要保证阅读困难时可使用翻译器翻译成可读的中文; + +**注:** 注释翻译工具使用[百度翻译](https://fanyi.baidu.com/);翻译的注释在使用doxygen工具生成接口文档时,在网页上方便翻译成中文。 + +### 1.1.3. C++继承 + +* 子类使用父类的函数时,函数前必须加父类名,降低阅读难度,没有父类名的一律为本类函数(有可能是虚函数); + +### 1.1.4. 变量命名 + +#### 1.1.4.1. 结构体/类成员 + +* 结构体和类成员必须要使用驼峰命名法,且首字母必须为m表示成员变量; + +``` +typedef struct app_get_product_info +{ + app_get_product_info(); + std::string mModel; + std::string mCompany; + std::string mSoc; + std::string mSp; +} AppGetProductInfo; +``` + +### 1.1.5. 文件命名 + +* 文件名必须使用驼峰命名法,且首字母大写; + +### 1.1.6. 代码排版 + +* 使用统一标准的代码排版风格,保持多人开发时代码的整洁,避免因为排版(特别是编辑工具的自动排版功能)导致每次提交时都产生大量的排版修改,影响后续代码异常排查; + +  请使用仓库跟目录下.clang-format配置文件进行排版,如果使用vscode编辑器开发代码,可直接使用快捷键ctrl+alt+f进行排版;也可以使用构建脚本对代码进行排版。 + +**对发生修改的代码进行格式化:** + +```code +$ make cmake // 在仓库根目录执行,对发生修改的文件创建格式化命令 +$ cd cmake-shell/ +$ make improve_modified_code // 文件格式化命令,统一排版,此命名只对发生修改的文件进行格式化 +``` + +**对全部文件进行格式化:** + +```code +详见配置文件://build/global_config.cmake +把 COMPILE_IMPROVE_SUPPORT 设置为 true 时,将会在每次编译代码时进行格式化。 +if(${LINUX_TEST} MATCHES "true") + set(CLANG_TIDY_SUPPORT "true") + set(CLANG_FORMAT_SUPPORT "true") + set(COMPILE_IMPROVE_SUPPORT "false") # 开启后每次编译可能会很慢 + set(LLVM_PATH "$ENV{HOME}/llvm-project") +endif() +``` + +### 1.1.7. 函数 + +* 单个函数代码行控制在50行内,阅读时无需上下滚动去理解代码逻辑;极少数初始化数据的无逻辑推理的代码除外; +* 函数参数不能超过10个; diff --git a/doc/doxygen_user_guide.md b/doc/doxygen_user_guide.md new file mode 100644 index 00000000..33907f60 --- /dev/null +++ b/doc/doxygen_user_guide.md @@ -0,0 +1,21 @@ +# 1. Linux嵌入式项目使用Doxygen生成API文档 + +## 1.1. Doxygen简介 + +  Doxygen是一个开源的文档生成工具,可以用来生成项目源代码的API文档。 + +## 1.2. Doxygen安装 + +  Doxygen安装非常简单,直接在官网下载最新版本即可。 + +``` + $ sudo apt-get install doxygen +``` + +## 1.3. 安装Graphviz + +  Doxygen本身不直接支持画图功能,但它可以生成DOT格式的图形描述文件,然后使用Graphviz工具进行渲染。 + +``` +$ sudo apt-get install graphviz +``` \ No newline at end of file diff --git a/doc/gdb_coredump_guide.md b/doc/gdb_coredump_guide.md new file mode 100644 index 00000000..b7de2ad7 --- /dev/null +++ b/doc/gdb_coredump_guide.md @@ -0,0 +1,209 @@ +# 1. gdb coredump分析 + +  本文介绍ubuntu系统环境下coredump文件的分析方法。 + +**一个coredump示例:** + +``` +$ ../output_files/test/bin/McuManagerTest --gtest_filter=McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission +Note: Google Test filter = McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission +[==========] Running 1 test from 1 test suite. +[----------] Global test environment set-up. +[----------] 1 test from McuManagerTest +NewLog succeed. +LogImplInit +[ RUN ] McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission +2024-05-15 17:43:04,782 INFO [default] [McuManagerMakePtr.cpp:23]:CreateMcuManager is ok. + +2024-05-15 17:43:04,783 INFO [default] [IMcuManager.cpp:72]:Instance changed succeed. + +2024-05-15 17:43:04,783 INFO [default] [UartDeviceImpl.cpp:277]:Create the uart device object. + +Can't Open Serial Port: No such file or directory +2024-05-15 17:43:04,784 ERROR [default] [McuDevice.cpp:51]:IUartOpen failed. + +2024-05-15 17:43:04,787 INFO [default] [UartDeviceImpl.cpp:277]:Create the uart device object. + +Can't Open Serial Port: No such file or directory +2024-05-15 17:43:04,787 ERROR [default] [McuDevice.cpp:51]:IUartOpen failed. + +terminate called without an active exception +Aborted (core dumped) +``` + +## 1.1. coredump文件生成路径查询 + +``` +$ cat /proc/sys/kernel/core_pattern +|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E +``` + +修改coredump文件生成路径: + +``` +$ sudo sh -c 'echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern' +$ cat /proc/sys/kernel/core_pattern +/home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p +``` +命令: +sudo sh -c 'echo /path/core.%e.%p > /proc/sys/kernel/core_pattern' + +例如: +``` +sudo sh -c 'echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern' +``` + +**发现路径下并未生成coredump文件** + +``` +$ ulimit -a +core file size (blocks, -c) 0 // 0表示终端未开启core dump +data seg size (kbytes, -d) unlimited +scheduling priority (-e) 0 +file size (blocks, -f) unlimited +pending signals (-i) 63499 +max locked memory (kbytes, -l) 65536 +max memory size (kbytes, -m) unlimited +open files (-n) 1024 +pipe size (512 bytes, -p) 8 +POSIX message queues (bytes, -q) 819200 +real-time priority (-r) 0 +stack size (kbytes, -s) 8192 +cpu time (seconds, -t) unlimited +max user processes (-u) 63499 +virtual memory (kbytes, -v) unlimited +file locks (-x) unlimited +``` + +解决: +``` +$ ulimit -c unlimited +``` + +sudo echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern + +## 1.2. gdb查看堆栈信息 + +**Ubuntu系统需要加sudo执行程序才会生成coredump文件。** + +### 1.2.1. 无法识别coredump文件 + +  在gdb中无法识别coredump文件,如下所示: + +``` +$ sudo gdb ../output_files/test/bin/McuManagerTest core.smbd.3390383 +[sudo] password for xiaojiazhu: +Sorry, try again. +[sudo] password for xiaojiazhu: +GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 +Copyright (C) 2020 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +Type "show copying" and "show warranty" for details. +This GDB was configured as "x86_64-linux-gnu". +Type "show configuration" for configuration details. +For bug reporting instructions, please see: +. +Find the GDB manual and other documentation resources online at: + . + +For help, type "help". +Type "apropos word" to search for commands related to "word"... +Reading symbols from ../output_files/test/bin/McuManagerTest... + +warning: core file may not match specified executable file. // 表示coredump文件与可执行文件不匹配 +[New LWP 3390383] +Core was generated by `/usr/sbin/smbd --foreground --no-process-group'. +Program terminated with signal SIGABRT, Aborted. +#0 0x00007fd59718600b in ?? () +(gdb) bt +#0 0x00007fd59718600b in ?? () +#1 0x0000000000001c80 in ?? () +#2 0x0000000000000000 in ?? () +``` + +由于gdb和asan同时启用会冲突,导致无法识别coredump文件。解决办法如下: + +修改://build/sdk_config.cmake + +``` +# Gdb debug +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + message("---------------------------Debug mode.-----------------------") + SET(CMAKE_BUILD_TYPE "Debug") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -Wall -g -ggdb") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -g -ggdb") + SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") + SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") + # asan + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined") + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined") +else() + message("---------------------------Release mode.-----------------------") + SET(CMAKE_BUILD_TYPE "Release") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os") +endif() +``` + +解决后: + +``` +$ sudo gdb ../output_files/test/bin/McuManagerTest core.McuManagerTest.3406751 +GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 +Copyright (C) 2020 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +Type "show copying" and "show warranty" for details. +This GDB was configured as "x86_64-linux-gnu". +Type "show configuration" for configuration details. +For bug reporting instructions, please see: +. +Find the GDB manual and other documentation resources online at: + . + +For help, type "help". +Type "apropos word" to search for commands related to "word"... +Reading symbols from ../output_files/test/bin/McuManagerTest... +[New LWP 3406751] +[New LWP 3406753] +[New LWP 3406752] +[Thread debugging using libthread_db enabled] +Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". +Core was generated by `../output_files/test/bin/McuManagerTest --gtest_filter=McuManagerTest.RH_INTEGR'. +Program terminated with signal SIGABRT, Aborted. +#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 +50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. +[Current thread is 1 (Thread 0x7fd355968740 (LWP 3406751))] +(gdb) bt +#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 +#1 0x00007fd35598f859 in __GI_abort () at abort.c:79 +#2 0x00007fd355d678d1 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 +#3 0x00007fd355d7337c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 +#4 0x00007fd355d733e7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6 +#5 0x000055c247b3ae41 in std::thread::operator= (__t=..., this=0x55c248d19748) at /usr/include/c++/9/thread:152 +#6 McuProtocol::Init (this=this@entry=0x55c248d196f8) at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/src/McuProtocol.cpp:58 +#7 0x000055c247b03e57 in McuManagerImpl::Init (this=0x55c248d19680) + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/middleware/McuManager/src/McuManagerImpl.cpp:46 +#8 0x000055c247acd3d4 in McuManagerTest::McuManagerTest_RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission_Test::TestBody (this=) + at /usr/include/c++/9/bits/shared_ptr_base.h:1020 +#9 0x000055c247b303fd in void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) () at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#10 0x000055c247b23343 in testing::Test::Run() () at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#11 0x000055c247b2342b in testing::TestInfo::Run() () + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#12 0x000055c247b2376e in testing::TestSuite::Run() () + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#13 0x000055c247b2a0fa in testing::internal::UnitTestImpl::RunAllTests() () + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#14 0x000055c247b3085e in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) () + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#15 0x000055c247b23529 in testing::UnitTest::Run() () + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121 +#16 0x000055c247ac9287 in RUN_ALL_TESTS () + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/external/gtest/googletest-release-1.11.0/googletest/include/gtest/gtest.h:2490 +#17 main (argc=, argv=) + at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/test/middleware/McuManager/mainTest.cpp:22 +(gdb) +``` \ No newline at end of file diff --git a/doc/git_guide.md b/doc/git_guide.md new file mode 100644 index 00000000..f7984770 --- /dev/null +++ b/doc/git_guide.md @@ -0,0 +1,239 @@ +# 1. git使用手册 + +## 1.1. 概述 + +  git是分布式版本控制系统,在多人开发中,git可以很好的管理代码的版本。 + +## 1.2. 源码托管服务器 + +  github和gitlab还有gitee(国产)都是开源的代码托管服务器,可以用来管理源码。 + +## 1.3. git安装 + +## 1.4. git分支管理 + +### 1.4.1. git创建本地分支 + +* 基于远端分支创建一个本地分支,同时新建一个对应的远端分支: + +  当主干发生较大变化,例如:原厂更新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 +Compressing objects: 100% (2/2), done. +Writing objects: 100% (2/2), 250 bytes | 250.00 KiB/s, done. +Total 2 (delta 1), reused 0 (delta 0) +remote: Powered by GITEE.COM [GNK-6.4] +remote: Create a pull request for 'sdk-202405' on Gitee by visiting: +remote: https://gitee.com/shenzhen-jiuyilian/ipc-rk1106/pull/new/shenzhen-jiuyilian:sdk-202405...shenzhen-jiuyilian:master +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 + remotes/origin/app_test + remotes/origin/master + 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.4.4. git删除远端地址 + +```code +# git remote remove +$ git remote -v +--------------- +Germany payton@git.affgt.com:Germany/hunting.git (fetch) +Germany payton@git.affgt.com:Germany/hunting.git (push) +origin git@gitee.com:shenzhen-jiuyilian/ipc.git (fetch) +origin git@gitee.com:shenzhen-jiuyilian/ipc.git (push) +$ git remote remove Germany +--------------------------- +$ git remote -v +---------------- +origin git@gitee.com:shenzhen-jiuyilian/ipc.git (fetch) +origin git@gitee.com:shenzhen-jiuyilian/ipc.git (push) +``` + +### 1.4.5. git删除一个远端分支 + +```code +# git push --delete +$ git branch -r +--------------- + origin/Branch_QT + origin/HEAD -> origin/master + origin/master + origin/master-develop + origin/without-testtools +$ git push origin --delete Branch_QT +------------------------------------- +remote: Powered by GITEE.COM [GNK-6.4] +To gitee.com:shenzhen-jiuyilian/ipc.git + - [deleted] Branch_QT +``` + +## 1.5. 多仓库管理 + +### 1.5.1. 合并两个无关联记录的仓库 + +  在一个仓库上合并另外一个无关联记录的仓库。 + +```code +# 假设A仓库的代码合入到B仓库 +# 在需要合并的仓库A下面执行 +$ rm -rf .git # 如果不需要A仓库的修改记录,需要重新创建一个新的本地分支和记录; +$ git init # 初始化一个空的仓库,并创建.git目录; +$ git add . # 添加A仓库的代码; +$ git commit -m "new log" # 保存代码,创建新的log;此时创建了一个本地的master分支; +$ git remote add B # 添加B仓库的地址; +$ git fetch B # 拉取B仓库的信息; +$ git checkout -b open B/master # 创建一个B仓库的本地分支,并切换到该分支; +$ git merge master --allow-unrelated-histories # 合并A仓库的代码,并允许两个分支没有关联记录; +$ git checkout --theirs . # 合并如果有冲突,选择A仓库的代码; +$ git restore --source=master output_files/libs/ # 按需,恢复A仓库的某些代码; +$ git add . # 添加需要合并的代码; +$ git commit -m "merge log" # 合并后的代码,保存到本地仓库; +$ git push B open:master # 推送到B仓库的master分支; +``` + +## 1.6. 存疑 + +* 不同的分支之间如何同步某个文件? diff --git a/doc/huntting_project_report.md b/doc/huntting_project_report.md new file mode 100644 index 00000000..e8d03600 --- /dev/null +++ b/doc/huntting_project_report.md @@ -0,0 +1,20 @@ +# 1. 项目进度汇总 + +## 1.1. 软件开发进度 + +```mermaid +gantt +dateFormat YYYY-MM-DD +title 软件进度-3月 +section 3月 +6帧探RTSP推流 : done, rtsp_media, 2024-03-18,3d +SC230AI快启验证(快启报错) : crit, active, 2024-03-21,3d +6帧探视频回放 : active, 2024-03-25,3d +``` + +### 1.1.1. 总结 + +* 截至2024-3-25: +1. 6侦探协议框架含http和tcp,http协议框架开发完成,rtsp推流到手机APP完成; +2. 存在问题:rtsp推流存在卡顿问题,待优化; +3. 更换SC230AI调试快启,快启报错,需要提问题单找原厂协助; \ No newline at end of file diff --git a/doc/markdown_user_guide.md b/doc/markdown_user_guide.md new file mode 100644 index 00000000..4cb0f9b7 --- /dev/null +++ b/doc/markdown_user_guide.md @@ -0,0 +1,101 @@ +# 1. Markdown使用手册 + +## 1.1. 概述 + +使用markdown编辑开发文档有以下好处: + +* markdown语法是一种语言,类似代码一样可以方便git管理,查看修改记录; +* 对代码显示支持良好; +* 可以进行UML类图和时序图的编辑/迭代/维护(强烈推荐); + +## 1.2. 如何使用Markdown + +此处介绍基于vscode编辑环境下使用Markdown的方法: + +* 首先安装vscode插件: + 1. Markdown All in One + 2. Markdown Preview Enhanced +* 使用Markdown语法编辑开发文档,并使用vscode预览; +* 右键使用浏览器打开并打印可生成PDF文档; + +## 1.3. 基本语法介绍 + +提供常用语法参考,直接copy模块代码进行编辑。 + +### 1.3.1. 常用命令 + +``` +Markdown All in One: Create Table of Contents 创建目录 +Markdown All in One: Update Table of Contents 更新目录 +Markdown All in One: Add/Update section numbers 添加 / 更新章节编号 +Markdown All in One: Remove section numbers 删除章节编号 +Markdown All in One: Toggle code span 触发设置代码范围(`code`) +Markdown All in One: Toggle code block 触发设置代码块(```codes```) +Markdown All in One: Print current document to HTML +Markdown All in One: Toggle math environment 触发设置数学环境 +Markdown All in One: Toggle list 触发设置列表环境 +``` + +### 1.3.2. 代码段 + +``` +/*This is your code.*/ +#include +int main() +{ + return 0; +} +``` + +### 1.3.3. UML类图语法 + +```mermaid +classDiagram + Animal <|-- Fish:继承 + Animal <|.. Zebra:实现 + Animal : +int age + Animal : +String gender + Animal: +isMammal() + Animal: +mate() + class Animal{ + <> + +call() int + } + class Fish{ + -int sizeInFeet + -canEat() + } + class Zebra{ + <> + -func(int, int) int + +bool is_wild + +run(void) + } +``` + +实现:一般指对抽象类的实例类 \ +继承:一般指对普通功能基类的派生/重载 + +### 1.3.4. UML时序图 + +```mermaid +sequenceDiagram +Alice->>+Jhon:Call function +Jhon->>Jhon:handle +Jhon-->>-Alice:Call return +note left of Alice:function + +Alice->>+Jhon:Call function +Jhon->>+Fancy:Call +Fancy-->>-Jhon:Call return +Jhon-->>-Alice:Call return + +Alice->>+Jhon:Call function +Jhon->>+Fancy:Call +Fancy->>-Fancy:End +Jhon-->>-Alice:Call return +``` + +### 1.3.5. 踩坑记录 + +1. 状态图不能使用default关键字作为一个状态名称,无法画图; \ No newline at end of file diff --git a/doc/sdk_build_guide.md b/doc/sdk_build_guide.md new file mode 100644 index 00000000..cecfbd8b --- /dev/null +++ b/doc/sdk_build_guide.md @@ -0,0 +1,9 @@ +# 1. SDK构建设计文档 + +## 1.1. 概述 + +  SDK使用cmake构建,把分层解耦合的独立模块编译成静态库,应用程序根据依赖关系进行自动关联链接。 + +## 1.2. 启用/禁用功能模块 + +  根据不同的产品需求来启用/禁用功能模块,避免编译不需要的模块。 diff --git a/doc/vscode_ssh_guide.md b/doc/vscode_ssh_guide.md new file mode 100644 index 00000000..60b5f6b7 --- /dev/null +++ b/doc/vscode_ssh_guide.md @@ -0,0 +1,89 @@ +# 1. vscode使用ssh链接虚拟机服务器 + +# 2. 前言 + +   在vscode使用ssh工具远程登录虚拟机服务器进行代码编辑。 + +| 内容 | 时间 | 作者 | 备注 | +|----|----|----|----| +| 首版 | 2024-2-26 | xjz | - | + +## 2.1. Windows系统 + +* 安装ssh + +   直接安装git工具即可支持ssh + +安装完后确认: +``` +xiaojiazhu@ubuntu:~/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell$ ssh +usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] + [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] + [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] + [-i identity_file] [-J [user@]host[:port]] [-L address] + [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] + [-Q query_option] [-R address] [-S ctl_path] [-W host:port] + [-w local_tun[:remote_tun]] destination [command] +``` + +* vscode安装ssh插件 + +   使用 Remote - SSH 插件 + +* ssh密钥配置 + +1. Windows生成密钥; +2. 把xxx.pub文件内容拷贝到虚拟机的ssh目录下的authorized_keys文件; +此处是: + +``` +xiaojiazhu@ubuntu:~/project/.ssh$ pwd +/home/xiaojiazhu/project/.ssh +xiaojiazhu@ubuntu:~/project/.ssh$ ls +authorized_keys id_rsa id_rsa.pub +``` + +这样设置后,每次登录ssh无需手动输入密码; + +3. 在Windows远程登录虚拟机: + +参考命令:ssh xiaojiazhu@192.168.1.29 + +``` +PS C:\Users\xjz\.ssh> ssh xiaojiazhu@192.168.1.29 +Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-94-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + +Expanded Security Maintenance for Applications is not enabled. + +75 updates can be applied immediately. +To see these additional updates run: apt list --upgradable + +9 additional security updates can be applied with ESM Apps. +Learn more about enabling ESM Apps service at https://ubuntu.com/esm + +New release '22.04.3 LTS' available. +Run 'do-release-upgrade' to upgrade to it. + +Your Hardware Enablement Stack (HWE) is supported until April 2025. +*** System restart required *** +Last login: Sun Feb 25 17:20:04 2024 from 192.168.1.29 +xiaojiazhu@ubuntu:~$ +``` +## 2.2. vscode设置 + +配置文件参考 + +``` +Host dgiot // 自定义的主机名 + HostName 192.168.1.29 // 远端的IP地址 + User xiaojiazhu 用户名 + Port 22 + IdentityFile "C:\Users\xjz\.ssh\id_ed25519" // 本端的私钥文件路径 + ForwardAgent yes // 忽略 +``` + +多个远端IP复制即可。 diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 1b27a22c..3da84f13 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -20,4 +20,5 @@ add_subdirectory(httpserver.h-master/src) add_subdirectory(cJSON-1.7.17) add_subdirectory(libhv/libhv-1.3.2) -add_subdirectory(ffmpeg) \ No newline at end of file +add_subdirectory(ffmpeg) +add_subdirectory(libconfig) \ No newline at end of file diff --git a/external/ffmpeg/CMakeLists.txt b/external/ffmpeg/CMakeLists.txt index 908b6802..1310e1e3 100644 --- a/external/ffmpeg/CMakeLists.txt +++ b/external/ffmpeg/CMakeLists.txt @@ -1,12 +1,8 @@ - add_custom_target( ffmpeg - # DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libgo.a - # COMMAND mkdir ${GOAHEAD_UPLOAD_TMP_PATH} - # COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/modify/http.c ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/src - # COMMAND touch ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/src/http.c COMMAND test -f ${EXTERNAL_SOURCE_PATH}/ffmpeg/Makefile || tar -xf ffmpeg_6.1.1.orig.tar.xz + COMMAND chmod 777 -R ffmpeg-6.1.1 COMMAND cd ffmpeg-6.1.1 && ./configure --enable-cross-compile --target-os=linux --arch=arm64 --cc=${CMAKE_C_COMPILER} --cxx=${CMAKE_CXX_COMPILER} @@ -27,6 +23,7 @@ add_custom_target( --disable-outdevs --disable-ffprobe --disable-ffmpeg --disable-ffplay --disable-debug COMMAND cd ffmpeg-6.1.1 && make COMMAND cd ffmpeg-6.1.1 && make install + COMMAND cd ffmpeg-6.1.1 && make clean WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/ffmpeg/ ) diff --git a/external/libconfig/CMakeLists.txt b/external/libconfig/CMakeLists.txt new file mode 100644 index 00000000..69fa8ab8 --- /dev/null +++ b/external/libconfig/CMakeLists.txt @@ -0,0 +1,26 @@ +set(LIBCONFIG_INSTALL_PATH "${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig") +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + set(CONFIGURE_COMMAND "--disable-cxx --enable-static=yes --prefix=${LIBCONFIG_INSTALL_PATH}") +else() + set(CONFIGURE_COMMAND "--host=${COMPILE_HOST} --disable-cxx --enable-static=yes --prefix=${LIBCONFIG_INSTALL_PATH}") +endif() +message("Compile libconfig comand : ${CONFIGURE_COMMAND}") +add_custom_target( + libconfig + COMMAND test -f ${EXTERNAL_SOURCE_PATH}/libconfig-1.7.3/Makefile || tar zxvf libconfig-1.7.3.tar.gz + COMMAND chmod 777 -R libconfig-1.7.3 + # COMMAND cd libconfig-1.7.3 && ./configure --disable-cxx --enable-static=yes --prefix=${LIBCONFIG_INSTALL_PATH} + COMMAND cd libconfig-1.7.3 && bash -c "./configure ${CONFIGURE_COMMAND}" + COMMAND cd libconfig-1.7.3 && make + COMMAND cd libconfig-1.7.3 && make install + COMMAND cd libconfig-1.7.3 && make clean + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/ +) +add_custom_target( + remove_libconfig_source_files + COMMAND rm -rf libconfig-1.7.3 + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/ +) + +# 将clean目标依赖于我们自定义的clean_script目标 +add_dependencies(sdk_clean remove_libconfig_source_files) \ No newline at end of file diff --git a/hal/CMakeLists.txt b/hal/CMakeLists.txt index 87358f33..a299a953 100644 --- a/hal/CMakeLists.txt +++ b/hal/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories( ${UTILS_SOURCE_PATH}/Log/include ${UTILS_SOURCE_PATH}/LinuxApi/include ${UTILS_SOURCE_PATH}/KeyControl/include + ${UTILS_SOURCE_PATH}/LedControl/include ) #do not rely on any other library # link_directories( @@ -24,7 +25,7 @@ aux_source_directory(./src IMPL_SRC_FILES) set(ABSTRACT_TARGET HalAbstract) set(IMPL_TARGET Hal) add_library(${ABSTRACT_TARGET} STATIC ${ABSTRACT_SRC_FILES}) -target_link_libraries(${ABSTRACT_TARGET} LinuxApi KeyControl StatusCode Log) +target_link_libraries(${ABSTRACT_TARGET} LinuxApi KeyControl LedControl StatusCode Log) add_library(${IMPL_TARGET} STATIC ${IMPL_SRC_FILES}) target_link_libraries(${IMPL_TARGET} ${ABSTRACT_TARGET}) diff --git a/hal/abstract/IHalCpp.cpp b/hal/abstract/IHalCpp.cpp index 766bcdcf..7395da0a 100644 --- a/hal/abstract/IHalCpp.cpp +++ b/hal/abstract/IHalCpp.cpp @@ -14,7 +14,10 @@ */ #include "IHalCpp.h" #include "ILog.h" +#include "StatusCode.h" +#include #include +#include camera_report_event::camera_report_event(const std::string &fileName, const CameraType &cameraType) : mFileName(fileName), mCameraType(cameraType) { @@ -64,8 +67,14 @@ void VCameraHalMonitor::ReportEvent(const CameraReportEvent &event) { LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); } +StatusCode VCameraTaskContext::TaskFinished(void) +{ + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); + return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); +} camera_task_param::camera_task_param(const CameraTaskType &cameraTask) : mCameraTask(cameraTask) { + mVideoRecordingTimeMs = DEFAULT_VIDEO_RECORDING_TIME_MS; } void VCameraHal::SetCameraMonitor(std::shared_ptr &monitor) { @@ -76,6 +85,21 @@ StatusCode VCameraHal::StartSingleTask(const CameraTaskParam ¶m) LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } +StatusCode VCameraHal::StopTask(void) +{ + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); + return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); +} +StatusCode VCameraHal::SetAudioStreamCallback(AudioStreamCallback callback) +{ + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); + return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); +} +StatusCode VCameraHal::SetVideoStreamCallback(VideoStreamCallback callback) +{ + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); + return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); +} void VSdCardHalMonitor::ReportEvent(const SdCardHalStatus &status) { LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n"); diff --git a/hal/include/IHalCpp.h b/hal/include/IHalCpp.h index fab89b6c..344e294f 100644 --- a/hal/include/IHalCpp.h +++ b/hal/include/IHalCpp.h @@ -15,6 +15,7 @@ #ifndef I_HAL_CPP_H #define I_HAL_CPP_H #include "StatusCode.h" +#include #include #include #include @@ -70,7 +71,6 @@ public: virtual void CheckKeyStatus(void); virtual void GetHoldPressingTimeMs(long int &holdTimeMs, VirtualKeyEvent &event); virtual void SetKeyMonitor(std::shared_ptr &monitor); - // virtual std::string GetKeyHalName(void); }; class VLedHal { @@ -100,6 +100,7 @@ class VCameraTaskContext public: VCameraTaskContext() = default; virtual ~VCameraTaskContext() = default; + virtual StatusCode TaskFinished(void); }; template class CameraTaskContext : public VCameraTaskContext @@ -113,12 +114,18 @@ public: public: T mData; }; +constexpr int DEFAULT_VIDEO_RECORDING_TIME_MS = 10 * 1000; typedef struct camera_task_param { camera_task_param(const CameraTaskType &cameraTask); const CameraTaskType mCameraTask; + unsigned int mVideoRecordingTimeMs; std::shared_ptr mCtx; } CameraTaskParam; +// using AudioStreamCallback = void (*)(const void *, const int, const unsigned long long); +// using VideoStreamCallback = void (*)(const void *, const int, const unsigned long long); +using AudioStreamCallback = std::function; +using VideoStreamCallback = std::function; class VCameraHal { public: @@ -126,6 +133,9 @@ public: virtual ~VCameraHal() = default; virtual void SetCameraMonitor(std::shared_ptr &monitor); virtual StatusCode StartSingleTask(const CameraTaskParam ¶m); + virtual StatusCode StopTask(void); + virtual StatusCode SetAudioStreamCallback(AudioStreamCallback callback); + virtual StatusCode SetVideoStreamCallback(VideoStreamCallback callback); }; class VSdCardHalMonitor { diff --git a/hal/src/CameraHal.cpp b/hal/src/CameraHal.cpp new file mode 100644 index 00000000..5a5bc0f4 --- /dev/null +++ b/hal/src/CameraHal.cpp @@ -0,0 +1,58 @@ +/* + * 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 "CameraHal.h" +#include "IHalCpp.h" +#include "StatusCode.h" +CameraHal::CameraHal() : mTaskRuning(false), mAudioStreamCallback(nullptr), mVideoStreamCallback(nullptr) +{ +} +void CameraHal::Init(void) +{ +} +void CameraHal::UnInit(void) +{ +} +StatusCode CameraHal::StartSingleTask(const CameraTaskParam ¶m) +{ + mTaskRuning = true; + return CreateStatusCode(STATUS_CODE_OK); +} +StatusCode CameraHal::StopTask(void) +{ + mTaskRuning = false; + return CreateStatusCode(STATUS_CODE_OK); +} +StatusCode CameraHal::SetAudioStreamCallback(AudioStreamCallback callback) +{ + mAudioStreamCallback = callback; + return CreateStatusCode(STATUS_CODE_OK); +} +StatusCode CameraHal::SetVideoStreamCallback(VideoStreamCallback callback) +{ + mVideoStreamCallback = callback; + return CreateStatusCode(STATUS_CODE_OK); +} +void CameraHal::GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ + if (mTaskRuning && nullptr != mAudioStreamCallback) { + mAudioStreamCallback(stream, length, timeStamp); + } +} +void CameraHal::GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ + if (mTaskRuning && nullptr != mVideoStreamCallback) { + mVideoStreamCallback(stream, length, timeStamp); + } +} \ No newline at end of file diff --git a/hal/src/CameraHal.h b/hal/src/CameraHal.h new file mode 100644 index 00000000..1ab18c04 --- /dev/null +++ b/hal/src/CameraHal.h @@ -0,0 +1,45 @@ +/* + * 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 CAMERA_HAL_H +#define CAMERA_HAL_H +#include "IHalCpp.h" +#include +#include +constexpr unsigned int NO_MEDIA_RECORDING = -1; +class CameraHal : public VCameraHal, public std::enable_shared_from_this +{ +public: + CameraHal(); + virtual ~CameraHal() = default; + virtual void Init(void); + virtual void UnInit(void); + +protected: + StatusCode StartSingleTask(const CameraTaskParam ¶m) override; + StatusCode StopTask(void) override; + StatusCode SetAudioStreamCallback(AudioStreamCallback callback) override; + StatusCode SetVideoStreamCallback(VideoStreamCallback callback) override; + +protected: + void GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp); + void GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp); + +private: + // std::mutex mMutex; + bool mTaskRuning; + AudioStreamCallback mAudioStreamCallback; + VideoStreamCallback mVideoStreamCallback; +}; +#endif \ No newline at end of file diff --git a/hal/src/Hal.c b/hal/src/Hal.c index 465db48e..36ed540a 100644 --- a/hal/src/Hal.c +++ b/hal/src/Hal.c @@ -13,7 +13,9 @@ * limitations under the License. */ #include "Hal.h" +#include "IHal.h" #include "ILog.h" +#include "StatusCode.h" #include #include StatusCode HalInit(IHal *hal) diff --git a/hal/src/HalCpp.cpp b/hal/src/HalCpp.cpp index 088387f2..bf7a7128 100644 --- a/hal/src/HalCpp.cpp +++ b/hal/src/HalCpp.cpp @@ -14,9 +14,15 @@ */ #include "HalCpp.h" #include "HalMakePtr.h" +#include "IHalCpp.h" #include "ILog.h" #include "SdCardHal.h" +#include "StatusCode.h" #include "WifiHal.h" +#include +#include +#include +#include StatusCode HalCpp::Init(void) { LogInfo("HalCpp::Init\n"); @@ -30,12 +36,8 @@ StatusCode HalCpp::Init(void) if (nullptr != sdCardImpl) { sdCardImpl->Init(); } - HalMakePtr::GetInstance()->CreateAllKeyHal(mKeys); - // auto checkPinValue = [](std::shared_ptr impl) { - // LogInfo("HalCpp::CheckAllPinVauleThread start\n"); - // impl->CheckAllPinVauleThread(); - // }; - // mCheckPinThread = std::thread(checkPinValue, shared_from_this()); + HalMakePtr::GetInstance()->CreateAllKeysHal(mKeys); + HalMakePtr::GetInstance()->CreateAllLedsHal(mLeds); return CreateStatusCode(STATUS_CODE_OK); } StatusCode HalCpp::UnInit(void) @@ -45,10 +47,6 @@ StatusCode HalCpp::UnInit(void) if (nullptr != sdCardImpl) { sdCardImpl->UnInit(); } - mThreadRuning = false; - if (mCheckPinThread.joinable()) { - mCheckPinThread.join(); - } mWifiHal.reset(); mSdCardHal.reset(); return CreateStatusCode(STATUS_CODE_OK); @@ -63,6 +61,19 @@ StatusCode HalCpp::GetSdCardHal(std::shared_ptr &sdCard) sdCard = mSdCardHal; return CreateStatusCode(STATUS_CODE_OK); } +StatusCode HalCpp::GetAllLeds(std::map> &allLeds) +{ + LogInfo("GetAllLeds, size = %d\n", mLeds.size()); + for (auto &led : mLeds) { + std::shared_ptr ledControl = std::dynamic_pointer_cast(led); + if (nullptr == ledControl) { + LogError("ledControl is nullptr\n"); + continue; + } + allLeds.insert(std::make_pair(led->GetLedName(), ledControl)); + } + return CreateStatusCode(STATUS_CODE_OK); +} StatusCode HalCpp::GetAllKeys(std::map> &allKeys) { LogInfo("GetAllKeys\n"); @@ -76,12 +87,3 @@ StatusCode HalCpp::GetAllKeys(std::map> &a } return CreateStatusCode(STATUS_CODE_OK); } -void HalCpp::CheckAllPinVauleThread(void) -{ - // mThreadRuning = true; - // while (mThreadRuning) { - // for (auto &keyHalImpl : mKeys) { - // } - // std::this_thread::sleep_for(std::chrono::milliseconds(PERIPHERAL_CHECK_PERIOD_MS)); - // } -} diff --git a/hal/src/HalCpp.h b/hal/src/HalCpp.h index 87e627ba..9f54bd37 100644 --- a/hal/src/HalCpp.h +++ b/hal/src/HalCpp.h @@ -16,6 +16,7 @@ #define HALCPP_H #include "IHalCpp.h" #include "KeyControl.h" +#include "LedControl.h" #include #include class HalCpp : public IHalCpp, public std::enable_shared_from_this @@ -27,17 +28,15 @@ public: StatusCode UnInit(void) override; StatusCode GetWifiHal(std::shared_ptr &wifi) override; StatusCode GetSdCardHal(std::shared_ptr &sdCard) override; + StatusCode GetAllLeds(std::map> &allLeds) override; StatusCode GetAllKeys(std::map> &allKeys) override; private: - void CheckAllPinVauleThread(void); - private: std::vector> mLedHals; std::shared_ptr mWifiHal; std::shared_ptr mSdCardHal; std::vector> mKeys; - bool mThreadRuning = false; - std::thread mCheckPinThread; + std::vector> mLeds; }; #endif \ No newline at end of file diff --git a/hal/src/HalMakePtr.cpp b/hal/src/HalMakePtr.cpp index 69b5bdb8..39636e9b 100644 --- a/hal/src/HalMakePtr.cpp +++ b/hal/src/HalMakePtr.cpp @@ -15,14 +15,21 @@ #include "HalMakePtr.h" #include "Hal.h" #include "HalCpp.h" +#include "IHal.h" +#include "IHalCpp.h" #include "ILog.h" +#include "KeyControl.h" +#include "LedControl.h" #include "SdCardHal.h" +#include "StatusCode.h" #include "WifiHal.h" +#include +#include StatusCode CreateHalModule(void) { - IHal *hal = NULL; + IHal *hal = nullptr; StatusCode code = HalMakePtr::GetInstance()->CreateHalPtr(&hal); - if (IsCodeOK(code) && NULL != hal) { + if (IsCodeOK(code) && nullptr != hal) { LogInfo("Create Hal instance ok.\n"); ResetHalImpl((IHal *)hal); } @@ -93,7 +100,12 @@ StatusCode HalMakePtr::CreateSdCardHal(std::shared_ptr &impl) impl = std::make_shared(); return CreateStatusCode(STATUS_CODE_OK); } -StatusCode HalMakePtr::CreateAllKeyHal(std::vector> &keys) +StatusCode HalMakePtr::CreateAllKeysHal(std::vector> &keys) +{ + LogInfo("STATUS_CODE_VIRTUAL_FUNCTION.\n"); + return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); +} +StatusCode HalMakePtr::CreateAllLedsHal(std::vector> &leds) { LogInfo("STATUS_CODE_VIRTUAL_FUNCTION.\n"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); diff --git a/hal/src/HalMakePtr.h b/hal/src/HalMakePtr.h index 72dfbf54..6001ed26 100644 --- a/hal/src/HalMakePtr.h +++ b/hal/src/HalMakePtr.h @@ -16,8 +16,9 @@ #define HALMAKEPTR_H #include "IHal.h" #include "IHalCpp.h" -#include "StatusCode.h" #include "KeyControl.h" +#include "LedControl.h" +#include "StatusCode.h" #include class HalMakePtr { @@ -38,6 +39,7 @@ public: virtual StatusCode CreateWifiHal(std::shared_ptr &impl); virtual StatusCode CreateCameraHal(std::shared_ptr &impl); virtual StatusCode CreateSdCardHal(std::shared_ptr &impl); - virtual StatusCode CreateAllKeyHal(std::vector> &keys); + virtual StatusCode CreateAllKeysHal(std::vector> &keys); + virtual StatusCode CreateAllLedsHal(std::vector> &leds); }; #endif \ No newline at end of file diff --git a/hal/src/SdCardHal.cpp b/hal/src/SdCardHal.cpp index 9582de1a..5b1237f3 100644 --- a/hal/src/SdCardHal.cpp +++ b/hal/src/SdCardHal.cpp @@ -13,17 +13,19 @@ * limitations under the License. */ #include "SdCardHal.h" +#include "IHalCpp.h" #include "ILog.h" #include "LinuxApi.h" -#include +#include "StatusCode.h" +#include #include +#include #include #include -#include #include -#include -#include +#include #include +#include #include const char *SD_CARD_DEVICE = SD_CARD_DEV; const char *SD_MOUNT_PATH = SD_CARD_MOUNT_PATH; diff --git a/hal/src/SdCardHal.h b/hal/src/SdCardHal.h index 5aabdb7c..6050c67b 100644 --- a/hal/src/SdCardHal.h +++ b/hal/src/SdCardHal.h @@ -23,7 +23,8 @@ public: virtual ~SdCardHal() = default; void SetSdCardMonitor(std::shared_ptr &monitor) override; SdCardHalStatus GetSdCardStatus(void) override; - StatusCode GetCapacity(unsigned long long &totalSizeMB, unsigned long long &freeSizeMB, unsigned long long &usedSizeMB) override; + StatusCode GetCapacity(unsigned long long &totalSizeMB, unsigned long long &freeSizeMB, + unsigned long long &usedSizeMB) override; void Init(void); void UnInit(void); void DevDetectingThread(void); diff --git a/hal/src/WifiHal.cpp b/hal/src/WifiHal.cpp index 8e684354..e7e7cd04 100644 --- a/hal/src/WifiHal.cpp +++ b/hal/src/WifiHal.cpp @@ -15,6 +15,8 @@ #include "WifiHal.h" #include "ILog.h" #include "LinuxApi.h" +#include "StatusCode.h" +#include #include #include #include @@ -29,12 +31,22 @@ StatusCode WifiHal::OpenApMode(void) constexpr int SLEEP_TIME_MS = 5; constexpr int WAITING_TIME_MS = 1000 * 10; unsigned int sleepingTime_ms = 0; + unsigned int resetWifiPowerCount = 0; mInitRunning = true; while (CheckWlan0IfExist() == false) { std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); sleepingTime_ms += SLEEP_TIME_MS; if (sleepingTime_ms > WAITING_TIME_MS) { - LogError("wlan0 not found. \n"); + if (0 == resetWifiPowerCount) { + LogWarning("wlan0 not found, try to reset. \n"); + PowerOff(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + PowerOn(); + sleepingTime_ms = 0; + resetWifiPowerCount++; + continue; + } + LogError("wlan0 not found, reset wifi power count: %d. \n", resetWifiPowerCount); return CreateStatusCode(STATUS_CODE_NOT_OK); } if (false == mInitRunning) { @@ -84,7 +96,5 @@ bool WifiHal::CheckWlan0IfExist(void) if (wlan0_found) { return true; } - else { - return false; - } + return false; } \ No newline at end of file diff --git a/middleware/AppManager/src/AppClient.cpp b/middleware/AppManager/src/AppClient.cpp index 53983215..50328db0 100644 --- a/middleware/AppManager/src/AppClient.cpp +++ b/middleware/AppManager/src/AppClient.cpp @@ -13,9 +13,12 @@ * limitations under the License. */ #include "AppClient.h" +#include "IAppManager.h" #include "IAppProtocolHandle.h" #include "ILog.h" #include "TcpModule.h" +#include +#include AppClient::AppClient(const void *clientObject) : mClientObject(clientObject) { } diff --git a/middleware/AppManager/src/AppManager.cpp b/middleware/AppManager/src/AppManager.cpp index ad0d9b09..2cd71631 100644 --- a/middleware/AppManager/src/AppManager.cpp +++ b/middleware/AppManager/src/AppManager.cpp @@ -15,10 +15,15 @@ #include "AppManager.h" #include "AppClient.h" #include "AppManagerMakePtr.h" +#include "IAppManager.h" +#include "IAppProtocolHandle.h" #include "IHalCpp.h" #include "ILog.h" +#include "StatusCode.h" #include "TcpModule.h" #include "WebServer.h" +#include +#include AppManager::AppManager() : mTcpServer(nullptr), mInitRuning(false) { } diff --git a/middleware/AppManager/src/AppManagerMakePtr.cpp b/middleware/AppManager/src/AppManagerMakePtr.cpp index d65d978f..afb73fb2 100644 --- a/middleware/AppManager/src/AppManagerMakePtr.cpp +++ b/middleware/AppManager/src/AppManagerMakePtr.cpp @@ -14,7 +14,11 @@ */ #include "AppManagerMakePtr.h" #include "AppManager.h" +#include "IAppManager.h" +#include "IAppProtocolHandle.h" #include "ILog.h" +#include "StatusCode.h" +#include // extern bool CreateProtocolHandleImpl(); bool CreateAppManagerModule(void) { diff --git a/middleware/AppManager/src/IAppManager.cpp b/middleware/AppManager/src/IAppManager.cpp index 950f9553..aba2ba69 100644 --- a/middleware/AppManager/src/IAppManager.cpp +++ b/middleware/AppManager/src/IAppManager.cpp @@ -14,6 +14,10 @@ */ #include "IAppManager.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include +#include app_get_product_info::app_get_product_info() { } diff --git a/middleware/AppManager/src/IAppProtocolHandle.cpp b/middleware/AppManager/src/IAppProtocolHandle.cpp index 7c435ff4..a8a3d095 100644 --- a/middleware/AppManager/src/IAppProtocolHandle.cpp +++ b/middleware/AppManager/src/IAppProtocolHandle.cpp @@ -13,7 +13,12 @@ * limitations under the License. */ #include "IAppProtocolHandle.h" +#include "IAppManager.h" #include "ILog.h" +#include "WebServer.h" +#include +#include +#include protocol_packet::~protocol_packet() { if (nullptr != mData) { diff --git a/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp b/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp index 5d84c10f..7f35fd40 100644 --- a/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp +++ b/middleware/AppManager/src/Protocol/SixFrame/SixFrameHandle.cpp @@ -13,11 +13,21 @@ * limitations under the License. */ #include "SixFrameHandle.h" +#include "IAppManager.h" +#include "IAppProtocolHandle.h" #include "ILog.h" +#include +#include +#include #include +#include +#include +#include #include #include +#include #include +#include using std::placeholders::_1; using std::placeholders::_2; using std::placeholders::_3; @@ -423,8 +433,8 @@ void SixFrameHandle::ResponseGetParamItems(cJSON *result, const AppGetCapability 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_AddItemToArray(index, cJSON_CreateNumber(0)); } } // { @@ -714,16 +724,10 @@ AppSetParamValue inline SixFrameHandle::RequestSetParamValueParse(const std::str auto parseFunc = [](const std::string &key, const std::string &value, std::shared_ptr &parse) { std::shared_ptr> parseImpl = std::dynamic_pointer_cast>(parse); - if ("switchcam" == key) { - parseImpl->mData.mName = "switchcam"; - parseImpl->mData.mValue = std::stoi(value); + if ("param" == key) { + parseImpl->mData.mName = value; } - if ("rec" == key) { - parseImpl->mData.mName = "rec"; - parseImpl->mData.mValue = std::stoi(value); - } - if ("mic" == key) { - parseImpl->mData.mName = "mic"; + if ("value" == key) { parseImpl->mData.mValue = std::stoi(value); } }; @@ -1010,10 +1014,8 @@ std::shared_ptr SixFrameHandle::MakePacket(const cJSON *json) if (nullptr != resultStr) { return std::make_shared(resultStr, strlen(resultStr)); } - else { - LogError("MakePacket failed.\n"); - return std::make_shared(); - } + LogError("MakePacket failed.\n"); + return std::make_shared(); } void SixFrameHandle::SetAppMonitor(std::shared_ptr &monitor) { diff --git a/middleware/AppManager/src/Protocol/SixFrame/SixFrameMakePtr.cpp b/middleware/AppManager/src/Protocol/SixFrame/SixFrameMakePtr.cpp index b64e8241..b01b67a2 100644 --- a/middleware/AppManager/src/Protocol/SixFrame/SixFrameMakePtr.cpp +++ b/middleware/AppManager/src/Protocol/SixFrame/SixFrameMakePtr.cpp @@ -13,8 +13,12 @@ * limitations under the License. */ #include "SixFrameMakePtr.h" +#include "AppManagerMakePtr.h" +#include "IAppProtocolHandle.h" #include "ILog.h" #include "SixFrameHandle.h" +#include "StatusCode.h" +#include bool CreateProtocolHandleImpl(void) { LogInfo("CreateProtocolHandleImpl SixFrameMakePtr.\n"); diff --git a/middleware/DeviceManager/src/DeviceManager.cpp b/middleware/DeviceManager/src/DeviceManager.cpp index a23b1913..1ae5a32f 100644 --- a/middleware/DeviceManager/src/DeviceManager.cpp +++ b/middleware/DeviceManager/src/DeviceManager.cpp @@ -13,10 +13,13 @@ * limitations under the License. */ #include "DeviceManager.h" +#include "IDeviceManager.h" #include "ILog.h" #include "KeyManager.h" #include "LedManager.h" -#include +#include "StatusCode.h" +#include +#include const StatusCode DeviceManager::Init(void) { KeyManager::GetInstance()->Init(); diff --git a/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp b/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp index bb8d2452..93a9fb23 100644 --- a/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp +++ b/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp @@ -14,7 +14,10 @@ */ #include "DeviceManagerMakePtr.h" #include "DeviceManager.h" +#include "IDeviceManager.h" #include "ILog.h" +#include "StatusCode.h" +#include bool CreateDeviceManagerModule(void) { auto instance = std::make_shared(); diff --git a/middleware/DeviceManager/src/IDeviceManager.cpp b/middleware/DeviceManager/src/IDeviceManager.cpp index 4ad0e7d1..cb6e5bca 100644 --- a/middleware/DeviceManager/src/IDeviceManager.cpp +++ b/middleware/DeviceManager/src/IDeviceManager.cpp @@ -14,6 +14,9 @@ */ #include "IDeviceManager.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include void VKeyMonitor::KeyEventReport(const std::string &keyName, const VirtualKeyEvent &event, const unsigned int &timeMs) { } diff --git a/middleware/DeviceManager/src/KeyManager.cpp b/middleware/DeviceManager/src/KeyManager.cpp index aaf68cd9..8ca3c1d1 100644 --- a/middleware/DeviceManager/src/KeyManager.cpp +++ b/middleware/DeviceManager/src/KeyManager.cpp @@ -13,7 +13,17 @@ * limitations under the License. */ #include "KeyManager.h" +#include "IDeviceManager.h" +#include "IHalCpp.h" #include "ILog.h" +// #include "KeyControl.h" +#include "StatusCode.h" +#include +#include +#include +#include +#include +#include std::shared_ptr &KeyManager::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/middleware/DeviceManager/src/LedManager.cpp b/middleware/DeviceManager/src/LedManager.cpp index 5f3a33ae..5b26158c 100644 --- a/middleware/DeviceManager/src/LedManager.cpp +++ b/middleware/DeviceManager/src/LedManager.cpp @@ -13,7 +13,16 @@ * limitations under the License. */ #include "LedManager.h" +#include "IDeviceManager.h" +#include "IHalCpp.h" #include "ILog.h" +#include "LedControl.h" +#include +#include +#include +#include +#include +#include std::shared_ptr &LedManager::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/middleware/FilesManager/src/FilesDatabase.h b/middleware/FilesManager/src/FilesDatabase.h index 0cc2f04d..55b91c70 100644 --- a/middleware/FilesManager/src/FilesDatabase.h +++ b/middleware/FilesManager/src/FilesDatabase.h @@ -14,9 +14,9 @@ */ #ifndef FILES_DATABASE_H #define FILES_DATABASE_H -#include "StatusCode.h" #include "FilesHandle.h" #include "IFilesManager.h" +#include "StatusCode.h" class FilesDatabase : public FilesHandle { public: diff --git a/middleware/FilesManager/src/FilesHandle.cpp b/middleware/FilesManager/src/FilesHandle.cpp index 14f21775..5c329243 100644 --- a/middleware/FilesManager/src/FilesHandle.cpp +++ b/middleware/FilesManager/src/FilesHandle.cpp @@ -14,17 +14,14 @@ */ #include "FilesHandle.h" #include "ILog.h" -#include #include #include #include #include -#include #include #include #include -#include -#include +#include std::string FilesHandle::CreateFilePathName(const std::string &sourceFile) { const std::string ERROR_SUFFIX = ""; diff --git a/middleware/FilesManager/src/FilesManagerImpl.cpp b/middleware/FilesManager/src/FilesManagerImpl.cpp index aa3dc8fb..d459663b 100644 --- a/middleware/FilesManager/src/FilesManagerImpl.cpp +++ b/middleware/FilesManager/src/FilesManagerImpl.cpp @@ -13,7 +13,10 @@ * limitations under the License. */ #include "FilesManagerImpl.h" -#include "IStorageManager.h" +#include "IFilesManager.h" +// #include "IStorageManager.h" +#include "FilesDatabase.h" +#include "StatusCode.h" StatusCode FilesManagerImpl::Init(void) { FilesDatabase::Init(); diff --git a/middleware/FilesManager/src/FilesManagerMakePtr.cpp b/middleware/FilesManager/src/FilesManagerMakePtr.cpp index 0ced43bd..2b870764 100644 --- a/middleware/FilesManager/src/FilesManagerMakePtr.cpp +++ b/middleware/FilesManager/src/FilesManagerMakePtr.cpp @@ -13,8 +13,11 @@ * limitations under the License. */ #include "FilesManagerMakePtr.h" -#include "ILog.h" #include "FilesManagerImpl.h" +#include "IFilesManager.h" +#include "ILog.h" +#include "StatusCode.h" +#include bool CreateFilesManagerModule(void) { auto instance = std::make_shared(); diff --git a/middleware/FilesManager/src/IFilesManager.cpp b/middleware/FilesManager/src/IFilesManager.cpp index c65e86de..1fa17a4a 100644 --- a/middleware/FilesManager/src/IFilesManager.cpp +++ b/middleware/FilesManager/src/IFilesManager.cpp @@ -14,6 +14,9 @@ */ #include "IFilesManager.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include save_file_info::save_file_info(const std::string &fileName) : mFileName(fileName) { } diff --git a/middleware/FilesManager/src/sqlite3/FilesDatabase.cpp b/middleware/FilesManager/src/sqlite3/FilesDatabase.cpp index 1c19e0d6..17c7c747 100644 --- a/middleware/FilesManager/src/sqlite3/FilesDatabase.cpp +++ b/middleware/FilesManager/src/sqlite3/FilesDatabase.cpp @@ -13,9 +13,13 @@ * limitations under the License. */ #include "FilesDatabase.h" +#include "FilesHandle.h" +#include "IFilesManager.h" #include "ILog.h" #include "IStorageManager.h" #include "SqliteHandle.h" +#include "StatusCode.h" +#include void FilesDatabase::Init(void) { SqliteHandle::GetInstance()->Init(); diff --git a/middleware/FilesManager/src/sqlite3/SqliteHandle.cpp b/middleware/FilesManager/src/sqlite3/SqliteHandle.cpp index f67be8f2..3d184c53 100644 --- a/middleware/FilesManager/src/sqlite3/SqliteHandle.cpp +++ b/middleware/FilesManager/src/sqlite3/SqliteHandle.cpp @@ -15,6 +15,8 @@ #include "SqliteHandle.h" #include "ILog.h" #include "sqlite3.h" +#include +#include std::shared_ptr &SqliteHandle::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); @@ -31,7 +33,7 @@ std::shared_ptr &SqliteHandle::GetInstance(std::shared_ptr #include #include diff --git a/middleware/HuntingUpgrade/src/HuntingUpgradeMakePtr.cpp b/middleware/HuntingUpgrade/src/HuntingUpgradeMakePtr.cpp index 2f4ad03c..72b4f465 100644 --- a/middleware/HuntingUpgrade/src/HuntingUpgradeMakePtr.cpp +++ b/middleware/HuntingUpgrade/src/HuntingUpgradeMakePtr.cpp @@ -14,7 +14,10 @@ */ #include "HuntingUpgradeMakePtr.h" #include "HuntingUpgradeImpl.h" +#include "IHuntingUpgrade.h" #include "ILog.h" +#include "StatusCode.h" +#include bool CreateHuntingUpgradeModule(void) { auto instance = std::make_shared(); diff --git a/middleware/HuntingUpgrade/src/IHuntingUpgrade.cpp b/middleware/HuntingUpgrade/src/IHuntingUpgrade.cpp index a746536d..c4f9b0b1 100644 --- a/middleware/HuntingUpgrade/src/IHuntingUpgrade.cpp +++ b/middleware/HuntingUpgrade/src/IHuntingUpgrade.cpp @@ -14,6 +14,8 @@ */ #include "IHuntingUpgrade.h" #include "ILog.h" +#include "StatusCode.h" +#include std::shared_ptr &IHuntingUpgrade::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/middleware/IpcConfig/src/IIpcConfig.cpp b/middleware/IpcConfig/src/IIpcConfig.cpp index 1759b5e1..54006888 100644 --- a/middleware/IpcConfig/src/IIpcConfig.cpp +++ b/middleware/IpcConfig/src/IIpcConfig.cpp @@ -14,6 +14,9 @@ */ #include "IIpcConfig.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include working_time::working_time() : mHourFrom(0), mHourTo(0), mMinuteFrom(0), mMinuteTo(0) { } diff --git a/middleware/IpcConfig/src/IpcConfigImpl.cpp b/middleware/IpcConfig/src/IpcConfigImpl.cpp index ad98ff04..88b6953b 100644 --- a/middleware/IpcConfig/src/IpcConfigImpl.cpp +++ b/middleware/IpcConfig/src/IpcConfigImpl.cpp @@ -13,13 +13,22 @@ * limitations under the License. */ #include "IpcConfigImpl.h" +#include "ConfigBase.h" +#include "IIpcConfig.h" #include "ILog.h" #include "LinuxApi.h" -#include +#include "StatusCode.h" +#include +#include +#include +#include +#include #include #include #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"; diff --git a/middleware/IpcConfig/src/IpcConfigMakePtr.cpp b/middleware/IpcConfig/src/IpcConfigMakePtr.cpp index 33bb6fcd..8274675d 100644 --- a/middleware/IpcConfig/src/IpcConfigMakePtr.cpp +++ b/middleware/IpcConfig/src/IpcConfigMakePtr.cpp @@ -13,8 +13,11 @@ * limitations under the License. */ #include "IpcConfigMakePtr.h" +#include "IIpcConfig.h" #include "ILog.h" #include "IpcConfigImpl.h" +#include "StatusCode.h" +#include bool CreateIpcConfigModule(void) { auto instance = std::make_shared(); diff --git a/middleware/McuAskBase/src/McuAskBase.cpp b/middleware/McuAskBase/src/McuAskBase.cpp index a5173594..19fffc3f 100644 --- a/middleware/McuAskBase/src/McuAskBase.cpp +++ b/middleware/McuAskBase/src/McuAskBase.cpp @@ -13,7 +13,8 @@ * limitations under the License. */ #include "McuAskBase.h" -#include "ILog.h" +#include "IMcuManager.h" +#include McuAskBase::McuAskBase(const McuAskBlock isBlock, const McuAskReply needReply, const unsigned int timeoutMs) : mIsBlock(isBlock), mNeedReply(needReply), mTimeout(timeoutMs) { diff --git a/middleware/McuManager/src/IMcuManager.cpp b/middleware/McuManager/src/IMcuManager.cpp index 64d307c8..1b777787 100644 --- a/middleware/McuManager/src/IMcuManager.cpp +++ b/middleware/McuManager/src/IMcuManager.cpp @@ -14,6 +14,9 @@ */ #include "IMcuManager.h" #include "ILog.h" +#include "IMcuManager.h" +#include "StatusCode.h" +#include mcu_ask_date_time::mcu_ask_date_time(const unsigned short year, const unsigned char mon, const unsigned char day, const unsigned char hour, const unsigned char min, const unsigned char second) : mYear(year), mMon(mon), mDay(day), mHour(hour), mMin(min), mSecond(second) diff --git a/middleware/McuManager/src/McuDevice.cpp b/middleware/McuManager/src/McuDevice.cpp index a003cb71..01561881 100644 --- a/middleware/McuManager/src/McuDevice.cpp +++ b/middleware/McuManager/src/McuDevice.cpp @@ -14,7 +14,19 @@ */ #include "McuDevice.h" #include "ILog.h" +#include "IMcuManager.h" +#include "McuProtocol.h" +#include "StatusCode.h" +#include "UartDevice.h" +#include +#include +#include +#include +#include +#include #include +#include +#include constexpr int SLEEP_TIME_MS = 1000; constexpr bool REMOVE_THE_ASK = true; constexpr bool KEEP_THE_ASK = false; diff --git a/middleware/McuManager/src/McuManagerImpl.cpp b/middleware/McuManager/src/McuManagerImpl.cpp index c9bfbdc9..71ea14d6 100644 --- a/middleware/McuManager/src/McuManagerImpl.cpp +++ b/middleware/McuManager/src/McuManagerImpl.cpp @@ -14,7 +14,19 @@ */ #include "McuManagerImpl.h" #include "ILog.h" +#include "IMcuManager.h" #include "McuAskBase.h" +#include "McuDevice.h" +#include "McuProtocol.h" +#include "StatusCode.h" +#include +#include +#include +#include +#include +#include +#include +#include class McuRecvImpl { public: diff --git a/middleware/McuManager/src/McuManagerMakePtr.cpp b/middleware/McuManager/src/McuManagerMakePtr.cpp index e47fafeb..366af84e 100644 --- a/middleware/McuManager/src/McuManagerMakePtr.cpp +++ b/middleware/McuManager/src/McuManagerMakePtr.cpp @@ -14,7 +14,10 @@ */ #include "McuManagerMakePtr.h" #include "ILog.h" +#include "IMcuManager.h" #include "McuManagerImpl.h" +#include "StatusCode.h" +#include bool CreateMcuManager(void) { auto instance = std::make_shared(); diff --git a/middleware/McuManager/src/UartRecvAsk.cpp b/middleware/McuManager/src/UartRecvAsk.cpp index 1d5c3ed6..1cef32b9 100644 --- a/middleware/McuManager/src/UartRecvAsk.cpp +++ b/middleware/McuManager/src/UartRecvAsk.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "UartRecvAsk.h" +#include "McuAskBase.h" UartRecvAsk::UartRecvAsk() : McuAskBase(McuAskBlock::NOT_BLOCK, McuAskReply::NEED_REPLY) { } \ No newline at end of file diff --git a/middleware/MediaManager/src/IMediaManager.cpp b/middleware/MediaManager/src/IMediaManager.cpp index 9ee046e7..68ee030d 100644 --- a/middleware/MediaManager/src/IMediaManager.cpp +++ b/middleware/MediaManager/src/IMediaManager.cpp @@ -14,6 +14,10 @@ */ #include "IMediaManager.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include +#include media_report_event::media_report_event(const std::string &fileName, const MediaChannel &mediaChannedl) : mFileName(fileName), mMediaChannedl(mediaChannedl) { diff --git a/middleware/MediaManager/src/MediaHandle.cpp b/middleware/MediaManager/src/MediaHandle.cpp index ca1f5fcc..3435f19b 100644 --- a/middleware/MediaManager/src/MediaHandle.cpp +++ b/middleware/MediaManager/src/MediaHandle.cpp @@ -13,11 +13,48 @@ * limitations under the License. */ #include "MediaHandle.h" +#include "IHalCpp.h" #include "ILog.h" +#include "IMediaManager.h" +#include "SaveStream.h" +#include "StatusCode.h" +#include +#include +#include +#include +#include +#include MediaHandle::MediaHandle(const MediaChannel &mediaChannel, const std::shared_ptr &cameraHal) - : mMediaChannel(mediaChannel), mCameraHal(cameraHal) + : mMediaChannel(mediaChannel), mCameraHal(cameraHal), mTaskRuning(false) { } +void MediaHandle::Init(void) +{ + if (mCameraHal == nullptr) { + LogError("CameraHal is null.\n"); + return; + } + auto audioFunc = std::bind(&MediaHandle::GetAudioStreamCallback, this, _1, _2, _3); + mCameraHal->SetAudioStreamCallback(audioFunc); + auto videoFunc = std::bind(&MediaHandle::GetVideoStreamCallback, this, _1, _2, _3); + mCameraHal->SetVideoStreamCallback(videoFunc); +} +void MediaHandle::UnInit(void) +{ + mTaskRuning = false; + mCv.notify_one(); + if (mTaskTimerThread.joinable()) { + mTaskTimerThread.join(); + } + if (mCameraHal) { + /** + * @brief Before releasing the class instance, it is necessary to call the UnInit function to ensure that the + * callback function is cleared elsewhere, otherwise it will crash. + */ + mCameraHal->SetAudioStreamCallback(nullptr); + mCameraHal->SetVideoStreamCallback(nullptr); + } +} StatusCode MediaHandle::ExecuteTask(std::shared_ptr &task) { std::lock_guard locker(mMutex); @@ -29,11 +66,18 @@ StatusCode MediaHandle::ExecuteTask(std::shared_ptr &task) return CreateStatusCode(STATUS_CODE_NOT_OK); } } + mStreamHandle = std::make_shared(); + if (nullptr == mStreamHandle) { + LogError("Create stream handle failed.\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + mStreamHandle->Init(); CameraTaskType taskType = TaskTypeConvert(task->GetTaskType()); CameraTaskParam data(taskType); auto code = mCameraHal->StartSingleTask(data); if (IsCodeOK(code)) { mCurrentTask = task; + StartTaskTimer(); } else { LogError("Execute task failed.\n"); @@ -48,7 +92,53 @@ StatusCode MediaHandle::ClearTask(void) { return CreateStatusCode(STATUS_CODE_OK); } +void MediaHandle::StartTaskTimer(void) +{ + auto taskTimerThread = [=](std::shared_ptr media) { + LogInfo("StartTaskTimer start.\n"); + media->TaskTimer(); + }; + std::shared_ptr media = shared_from_this(); + mTaskTimerThread = std::thread(taskTimerThread, media); +} +void MediaHandle::TaskTimer(void) +{ + constexpr int TASK_TIMER = 1000 * 10; + mTaskRuning = true; + while (mTaskRuning) { + std::unique_lock lock(mMutex); + mCv.wait_for(lock, std::chrono::milliseconds(TASK_TIMER), [&] { + return !mTaskRuning; + }); + /** + * @brief If the recording time is over, you need to stop the recording timer here. + */ + mTaskRuning = false; + } + if (mCameraHal) { + mCameraHal->StopTask(); + } + mMutex.lock(); + auto runingTask = mCurrentTask.lock(); + if (mCurrentTask.expired()) { + LogWarning("SdCardHal: monitor is expired.\n"); + return; + } + LogInfo("Task finished response to application.\n"); + std::vector responses; + runingTask->Response(responses); + mCurrentTask.reset(); + mMutex.unlock(); +} CameraTaskType MediaHandle::TaskTypeConvert(const MediaTaskType &type) { return CameraTaskType::END; +} +void MediaHandle::GetVideoStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp) +{ + mStreamHandle->GetVideoStream(stream, length, timeStamp); +} +void MediaHandle::GetAudioStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp) +{ + mStreamHandle->GetAudioStream(stream, length, timeStamp); } \ No newline at end of file diff --git a/middleware/MediaManager/src/MediaHandle.h b/middleware/MediaManager/src/MediaHandle.h index 809785b8..ecc733f5 100644 --- a/middleware/MediaManager/src/MediaHandle.h +++ b/middleware/MediaManager/src/MediaHandle.h @@ -16,23 +16,41 @@ #define MEDI_AHANDLE_H #include "IHalCpp.h" #include "IMediaManager.h" +#include "VStreamHandle.h" +#include #include +#include +using std::placeholders::_1; +using std::placeholders::_2; +using std::placeholders::_3; class MediaHandle : public VMediaHandle, public std::enable_shared_from_this { public: MediaHandle(const MediaChannel &mediaChannel, const std::shared_ptr &cameraHal); virtual ~MediaHandle() = default; + void Init(void); + void UnInit(void); + +protected: StatusCode ExecuteTask(std::shared_ptr &task) override; StatusCode StopTask(void) override; StatusCode ClearTask(void) override; private: + void StartTaskTimer(void); + void TaskTimer(void); CameraTaskType TaskTypeConvert(const MediaTaskType &type); + void GetVideoStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp); + void GetAudioStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp); private: std::mutex mMutex; + std::condition_variable mCv; const MediaChannel &mMediaChannel; std::shared_ptr mCameraHal; std::weak_ptr mCurrentTask; + std::shared_ptr mStreamHandle; + bool mTaskRuning; + std::thread mTaskTimerThread; }; #endif \ No newline at end of file diff --git a/middleware/MediaManager/src/MediaManagerImpl.cpp b/middleware/MediaManager/src/MediaManagerImpl.cpp index a3356e8d..d58751a5 100644 --- a/middleware/MediaManager/src/MediaManagerImpl.cpp +++ b/middleware/MediaManager/src/MediaManagerImpl.cpp @@ -13,8 +13,14 @@ * limitations under the License. */ #include "MediaManagerImpl.h" +#include "IHalCpp.h" #include "ILog.h" +#include "IMediaManager.h" #include "MediaHandle.h" +#include "StatusCode.h" +#include +#include +#include StatusCode MediaManagerImpl::Init(void) { IHalCpp::GetInstance()->GetCameraHal(mAllCameras); @@ -23,6 +29,7 @@ StatusCode MediaManagerImpl::Init(void) } StatusCode MediaManagerImpl::UnInit(void) { + UnInitMediaHandles(); return CreateStatusCode(STATUS_CODE_OK); } StatusCode MediaManagerImpl::GetMediaChannel(const MediaChannel &channel, std::shared_ptr &handle) @@ -76,8 +83,21 @@ void MediaManagerImpl::InitMediaHandles(std::map(i); - std::shared_ptr media = std::make_shared(channel, camera->second); + std::shared_ptr media = std::make_shared(channel, camera->second); + media->Init(); mAllMediaChannels[channel] = media; LogInfo("InitMediaHandles. channel = %d \n", static_cast(i)); } +} +void MediaManagerImpl::UnInitMediaHandles(void) +{ + for (auto &media : mAllMediaChannels) { + LogInfo("UnInitMediaHandles. channel = %d \n", media.first); + std::shared_ptr mediaImpl = std::dynamic_pointer_cast(media.second); + if (nullptr == mediaImpl) { + LogWarning("mediaImpl is null.\n"); + continue; + } + mediaImpl->UnInit(); + } } \ No newline at end of file diff --git a/middleware/MediaManager/src/MediaManagerImpl.h b/middleware/MediaManager/src/MediaManagerImpl.h index 20fe1b75..330dc4aa 100644 --- a/middleware/MediaManager/src/MediaManagerImpl.h +++ b/middleware/MediaManager/src/MediaManagerImpl.h @@ -33,6 +33,7 @@ public: private: void SetCamerasMonitor(std::map> &allCameras); void InitMediaHandles(std::map> &allCameras); + void UnInitMediaHandles(void); private: std::map> mAllCameras; diff --git a/middleware/MediaManager/src/MediaManagerMakePtr.cpp b/middleware/MediaManager/src/MediaManagerMakePtr.cpp index aa1d19b2..30df0cb4 100644 --- a/middleware/MediaManager/src/MediaManagerMakePtr.cpp +++ b/middleware/MediaManager/src/MediaManagerMakePtr.cpp @@ -14,7 +14,10 @@ */ #include "MediaManagerMakePtr.h" #include "ILog.h" +#include "IMediaManager.h" #include "MediaManagerImpl.h" +#include "StatusCode.h" +#include bool CreateMediaManagerModule(void) { auto instance = std::make_shared(); diff --git a/middleware/MediaManager/src/SaveStream.cpp b/middleware/MediaManager/src/SaveStream.cpp new file mode 100644 index 00000000..81b07f7e --- /dev/null +++ b/middleware/MediaManager/src/SaveStream.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this mFileAudio 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 "SaveStream.h" +#include "ILog.h" +#include +#include +#include +SaveStream::SaveStream() : mFileAudio(nullptr), mFileVideo(nullptr) +{ +} +void SaveStream::Init(void) +{ + mFileAudio = fopen("/tmp/audio.g711", "a+"); // TODO: + mFileVideo = fopen("/tmp/video.h264", "a+"); // TODO: +} +void SaveStream::UnInit(void) +{ + if (mFileAudio) { + fclose(mFileAudio); + mFileAudio = nullptr; + } + if (mFileVideo) { + fclose(mFileVideo); + mFileVideo = nullptr; + } +} +void SaveStream::GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ + if (mFileVideo) { + size_t writeLength = fwrite(stream, 1, length, mFileVideo); + if (writeLength != length) { + LogError("Write video stream failed.\n"); + } + fflush(mFileVideo); + } +} +void SaveStream::GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ + if (mFileAudio) { + size_t writeLength = fwrite(stream, 1, length, mFileAudio); + if (writeLength != length) { + LogError("Write video stream failed.\n"); + } + fflush(mFileAudio); + } +} \ No newline at end of file diff --git a/middleware/MediaManager/src/SaveStream.h b/middleware/MediaManager/src/SaveStream.h new file mode 100644 index 00000000..7cf5ba2c --- /dev/null +++ b/middleware/MediaManager/src/SaveStream.h @@ -0,0 +1,33 @@ +/* + * 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 SAVE_STREAM_H +#define SAVE_STREAM_H +#include "VStreamHandle.h" +#include +class SaveStream : public VStreamHandle +{ +public: + SaveStream(); + virtual ~SaveStream() = default; + void Init(void) override; + void UnInit(void) override; + void GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) override; + void GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) override; + +private: + FILE *mFileAudio; + FILE *mFileVideo; +}; +#endif \ No newline at end of file diff --git a/middleware/MediaManager/src/VStreamHandle.cpp b/middleware/MediaManager/src/VStreamHandle.cpp new file mode 100644 index 00000000..c34becaf --- /dev/null +++ b/middleware/MediaManager/src/VStreamHandle.cpp @@ -0,0 +1,27 @@ +/* + * 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 "VStreamHandle.h" +void VStreamHandle::Init(void) +{ +} +void VStreamHandle::UnInit(void) +{ +} +void VStreamHandle::GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ +} +void VStreamHandle::GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ +} \ No newline at end of file diff --git a/middleware/MediaManager/src/VStreamHandle.h b/middleware/MediaManager/src/VStreamHandle.h new file mode 100644 index 00000000..d7e23d88 --- /dev/null +++ b/middleware/MediaManager/src/VStreamHandle.h @@ -0,0 +1,27 @@ +/* + * 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 V_STREAM_HANDLE_H +#define V_STREAM_HANDLE_H +class VStreamHandle +{ +public: + VStreamHandle() = default; + virtual ~VStreamHandle() = default; + virtual void Init(void); + virtual void UnInit(void); + virtual void GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp); + virtual void GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp); +}; +#endif \ No newline at end of file diff --git a/middleware/StateMachine/src/IStateMachine.cpp b/middleware/StateMachine/src/IStateMachine.cpp index 1af3d751..e1ba6b59 100644 --- a/middleware/StateMachine/src/IStateMachine.cpp +++ b/middleware/StateMachine/src/IStateMachine.cpp @@ -14,7 +14,10 @@ */ #include "IStateMachine.h" #include "ILog.h" -#include +#include "StatusCode.h" +#include +#include +#include std::string State::GetStateName() { return mStateName; diff --git a/middleware/StateMachine/src/StateMachineImpl.cpp b/middleware/StateMachine/src/StateMachineImpl.cpp index 98a5dfe5..60c4d165 100644 --- a/middleware/StateMachine/src/StateMachineImpl.cpp +++ b/middleware/StateMachine/src/StateMachineImpl.cpp @@ -13,7 +13,10 @@ * limitations under the License. */ #include "StateMachineImpl.h" +#include "IStateMachine.h" #include "StateMachineMakePtr.h" +#include "StatusCode.h" +#include const StatusCode StateMachineImpl::CreateStateMachine(std::shared_ptr &stateMachine) { return StateMachineMakePtr::GetInstance()->CreateStateMachine(stateMachine); diff --git a/middleware/StateMachine/src/StateMachineMakePtr.cpp b/middleware/StateMachine/src/StateMachineMakePtr.cpp index f4705dcb..363f45f7 100644 --- a/middleware/StateMachine/src/StateMachineMakePtr.cpp +++ b/middleware/StateMachine/src/StateMachineMakePtr.cpp @@ -16,8 +16,10 @@ #include "ILog.h" #include "IStateMachine.h" #include "StateMachineImpl.h" +#include "StatusCode.h" #include "state_machine.h" -#include +#include +#include bool CreateStateMachine(void) { auto instance = std::make_shared(); diff --git a/middleware/StorageManager/src/EmmcHandle.cpp b/middleware/StorageManager/src/EmmcHandle.cpp index 36e2f070..ddef3795 100644 --- a/middleware/StorageManager/src/EmmcHandle.cpp +++ b/middleware/StorageManager/src/EmmcHandle.cpp @@ -12,4 +12,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "EmmcHandle.h" \ No newline at end of file +// #include "EmmcHandle.h" \ No newline at end of file diff --git a/middleware/StorageManager/src/IStorageManager.cpp b/middleware/StorageManager/src/IStorageManager.cpp index 9aec9a73..867ccbc1 100644 --- a/middleware/StorageManager/src/IStorageManager.cpp +++ b/middleware/StorageManager/src/IStorageManager.cpp @@ -14,6 +14,9 @@ */ #include "IStorageManager.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include sd_card_info::sd_card_info() : mEvent(StorageEvent::END), mTotalSizeMB(0), mFreeSizeMB(0) { } diff --git a/middleware/StorageManager/src/SdCardHandle.cpp b/middleware/StorageManager/src/SdCardHandle.cpp index 071c8b2e..0eb9d43f 100644 --- a/middleware/StorageManager/src/SdCardHandle.cpp +++ b/middleware/StorageManager/src/SdCardHandle.cpp @@ -13,8 +13,15 @@ * limitations under the License. */ #include "SdCardHandle.h" +#include "IHalCpp.h" #include "ILog.h" +#include "IStorageManager.h" #include "LinuxApi.h" +#include "StatusCode.h" +#include "StorageBase.h" +#include +#include +#include void SdCardHandle::ReportEvent(const SdCardHalStatus &status) { LogInfo("SdCardHal: ReportEvent.\n"); diff --git a/middleware/StorageManager/src/StorageBase.cpp b/middleware/StorageManager/src/StorageBase.cpp index d94ee1cc..2320181f 100644 --- a/middleware/StorageManager/src/StorageBase.cpp +++ b/middleware/StorageManager/src/StorageBase.cpp @@ -14,11 +14,12 @@ */ #include "StorageBase.h" #include "ILog.h" +#include "IStorageManager.h" +#include #include #include #include #include -#include bool StorageBase::CheckDirectory(const char *filepath) { LogInfo("CheckDirectory:%s\n", filepath); diff --git a/middleware/StorageManager/src/StorageManagerImpl.cpp b/middleware/StorageManager/src/StorageManagerImpl.cpp index f787c43b..b1e3a9bf 100644 --- a/middleware/StorageManager/src/StorageManagerImpl.cpp +++ b/middleware/StorageManager/src/StorageManagerImpl.cpp @@ -13,7 +13,13 @@ * limitations under the License. */ #include "StorageManagerImpl.h" -#include "ILog.h" +// #include "ILog.h" +#include "IStorageManager.h" +#include "SdCardHandle.h" +#include "StatusCode.h" +#include "StorageBase.h" +#include +#include StatusCode StorageManagerImpl::Init(void) { SdCardHandle::SdCardInit(); diff --git a/middleware/StorageManager/src/StorageManagerMakePtr.cpp b/middleware/StorageManager/src/StorageManagerMakePtr.cpp index 3f9243cb..275287fc 100644 --- a/middleware/StorageManager/src/StorageManagerMakePtr.cpp +++ b/middleware/StorageManager/src/StorageManagerMakePtr.cpp @@ -14,7 +14,10 @@ */ #include "StorageManagerMakePtr.h" #include "ILog.h" +#include "IStorageManager.h" +#include "StatusCode.h" #include "StorageManagerImpl.h" +#include bool CreateStorageManagerModule(void) { auto instance = std::make_shared(); diff --git a/test/all/CMakeLists.txt b/test/all/CMakeLists.txt index 584121f2..06f4a050 100644 --- a/test/all/CMakeLists.txt +++ b/test/all/CMakeLists.txt @@ -16,6 +16,7 @@ include_directories( link_directories( ${LIBS_OUTPUT_PATH} ${EXTERNAL_LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib ) aux_source_directory(. SRC_FILES) diff --git a/test/application/HuntingCamera/CMakeLists.txt b/test/application/HuntingCamera/CMakeLists.txt index 8131a8c3..da59f582 100644 --- a/test/application/HuntingCamera/CMakeLists.txt +++ b/test/application/HuntingCamera/CMakeLists.txt @@ -31,6 +31,7 @@ include_directories( link_directories( ${LIBS_OUTPUT_PATH} ${EXTERNAL_LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib ${TEST_TOOLS_OUTPUT_PATH} ) diff --git a/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp b/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp index 8d0ad3c5..8ff68d94 100644 --- a/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp +++ b/test/application/HuntingCamera/src_mock/AppMonitor_Mock_Test.cpp @@ -178,7 +178,9 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_AUTO_SetParamValue) MainThread::GetInstance()->Init(); TestManager::ResetTimeOut(1000 * 3); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - MockSetParamValue(); + MockSetParamValue("mic", "1"); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + MockGetParamValue("mic"); MainThread::GetInstance()->Runing(); } // ../output_files/test/bin/HuntingCameraTest diff --git a/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp b/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp index dc5844e4..dff135cf 100644 --- a/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp +++ b/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp @@ -32,7 +32,6 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaReprot) MockReportCameraEvent("/tmp/test.MP4", CameraType::MAIN_CAMERA); CreateUpgradeFile(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - // McuManagerTestTool::MockMcuDeviceOpenFailed(mLinuxTest); MainThread::GetInstance()->Init(); TestManager::ResetTimeOut(1000 * 4); std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -40,4 +39,17 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaReprot) MainThread::GetInstance()->Runing(); RemoveUpgradeFile(); } +// ../output_files/test/bin/HuntingCameraTest +// --gtest_filter=HuntingCameraTest.INTEGRATION_HunttingCamera_EXAMPLE_MediaTask +TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaTask) +{ + McuManagerTestTool::MockOtherSideIpcMissionReply(IpcMission::TEST); + SetAllCamerasResult(mAllCamerasMock); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + MainThread::GetInstance()->Init(); + TestManager::ResetTimeOut(1000 * 15); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + HalTestTool::MockKeyClick("reset", 200); // Simulate pressing a button. + MainThread::GetInstance()->Runing(); +} } // namespace MediaManager_Mock_Test \ No newline at end of file diff --git a/test/middleware/AppManager/src/AppManager_Test.cpp b/test/middleware/AppManager/src/AppManager_Test.cpp index f65bc77c..64cddc87 100644 --- a/test/middleware/AppManager/src/AppManager_Test.cpp +++ b/test/middleware/AppManager/src/AppManager_Test.cpp @@ -269,7 +269,7 @@ TEST_F(AppManagerTest, INTEGRATION_AppManager_EXAMPLE_AUTO_SetParamValue) IAppManager::GetInstance()->Init(mAppParam); IAppManager::GetInstance()->SetAppMonitor(monitor); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - MockSetParamValue(); + MockSetParamValue("mic", "1"); 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 7031bc0b..5101ff36 100644 --- a/test/middleware/AppManager/tool/include/AppManagerTestTool.h +++ b/test/middleware/AppManager/tool/include/AppManagerTestTool.h @@ -40,7 +40,7 @@ protected: // About http void MockGetLockVideoStatus(void); void MockGetStorageInfo(void); void MockGetStorageFileList(void); - void MockSetParamValue(void); + void MockSetParamValue(const std::string &item, const std::string &value); void MockEnterRecorder(void); void MockAppPlayback(void); void MockMonitorSetFileList(std::vector &files); diff --git a/test/middleware/IpcConfig/CMakeLists.txt b/test/middleware/IpcConfig/CMakeLists.txt index d30bac57..10b205ca 100644 --- a/test/middleware/IpcConfig/CMakeLists.txt +++ b/test/middleware/IpcConfig/CMakeLists.txt @@ -23,6 +23,7 @@ include_directories( link_directories( ${LIBS_OUTPUT_PATH} ${EXTERNAL_LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib ${TEST_TOOLS_OUTPUT_PATH} ) diff --git a/test/support_test/audio.g711a b/test/support_test/audio.g711a new file mode 100755 index 00000000..bb40a247 --- /dev/null +++ b/test/support_test/audio.g711a @@ -0,0 +1 @@ +UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVQWTWUUTUUUUUUUUUUUUUUUUUUUUUUUTTTTTUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUTTUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUTUUTUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWVVVWWWWWWTTTTTUUUUUUUUUUUUTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTUUUUUUTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUTTUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUTTUUTUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUTTTTTTTTTTTUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUTTUUTTTTTTWWWWWWTTTTTTTTTTTTTTUUTUUUUUUUUTTTTTTUUUTUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUTTUTUUUUTTUUUUUUUUTTUUUUUUUTUUUUUUUTTTTTTTTUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUTTWWWWTTWTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTTTTTUTTUTTTUUTUUTTUUUUUUUUUUUUUUUUUUUUUUUTTUUUTTTUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUTTUUUUUUUUUUUUUUTTTUUUUUUUUUUUUTTTWWVVWWWWWTTTTTUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUTUUTTUUUUUUUUUUUUTUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUTTUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTWVVQQQQVVWWWWTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUTTTTTTTTTTUUUUUUUUUUUTTUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWWWWWWWTTTTTTTTTUUUUUUUUUUUUUUTTTTWWWWTTTTTTTTUVS]\]RQWUUTWVQQVTUUTTTTUTVPSRRSPPQVWWTTTTTTTUWRY[X_SWUVS\_^\RQUWVQVVTUTWVVVWTUTTWWTTUUTTTTTTUUUUUTTWVQQQVWTV\XEE[^]PVTUTQR_^^_\RPVWTUWVQQVWWTUSYZDDZX^\RSQWUTQSRRRSPPQQVWTUUUUTTTWTTUUUQSR]\_^YYY_]QTWQSR]\\]RPVTUTWVQQQVWTUQ_[EEEZ[ZZZZY\QUUTVQS]\_\]SVUWVWUS^[ZEDGACBB@GX]VTUTVPSSSPQVWVVPR\^YY^]PQQS]RSPQQVVTU]XZ[YYXZG@BCFXSUVPSPQVWTTWVQS]_Y[Z[^]SS\X[X^RU\BuvqqvwwwwwJBYUTTTTTVS]____\___]SQWWP]YX\WUEw~edde{y~|st@QV_[DABNJuuKMGYRQWUV\D@AD]I{`mmf~J_Pu~eeysKG]TErdafzpB_T@ajbsHye~u]WQV\J{bhkiaqSWXEGGD^VrmoAddrRVQ]DKtuA]TSGKvuLX]_EFESocuSvzfet\YXFIttFwgcayMTS^Y\mjj`J@segxu\Bwsrq@Rt{`l`|VZttO[WS|`lmxSVCqzBEKvssJRZOw~zgeJVDIIMF^Cdmle^Yu~e~[QYMv}MYNp}|rqu[SFKJLZTsclcsMd{OFpy}ORt|vN@GDSTXMLCDZ^PxmmdH]vedsEWKsstETDutuJNOJN^SEDFLLZU@ao`yGLd{wCS^KwssJ_QLvspwHFYTQ^GBC@DSSzm`{tS_KsrvLP@w}vGVPGNttqxyKSRIt@SV{lbd}A^Kzxq^QBwqvuDZv|u^T[MF_Pqcbag~Aux{sJ^@wvtOEWXu|{puFQ]Vra`mlfwPOp{dzwZ\NvtNA[VZMuvvJB[Qw|gccdpE@v}|rqI\P[MJtHLAYY_VQRR\^[ZZX\STusgcazrL_Cw}|stL\RBttvqqJCE\V]]RSUE}`b`fdq]Op|~x|tDVP@u|zzy|v@QTQTqega`ayJD\O}xxyvD^trxddxruZBHv|zypwtXUEBusrqtI[WEJqr}rqu@_TJJuprquLMYV^FKtuuK@^WWX@ItttJLF_UJuu}|pqHMZP[ANHJKCGYUW_XAMOOB@D_VVIBwy}r|wKFPW_ZNuuuIB[STWP]XEEDDZYRWDZt~r|xrwKDVV_LKJttIMF^SUP\]_^]PWTSYwrp~yrqwC\TVGMIwwttKMD\VUVPWTRtpv~pqwC\VXACHuHuJOCD^PTU_uwv|ppwA^TQDMNutNNLDZYPVVUTPXKww}}qvt@^W_G@NJIHHM@D_SVUW[Htwr}pwJAYV_D@OHOLMFZX\QWUWVQQT_Lwwqspvu@_V\EDLuJLNNOA\VTPAuqsrpqwOZQT_ECIKIOBFGE^RVTWWURDIwr|}qtLD]]GLKutwvwJCXSU]ELJq}|pJF\WW]Z@NJJJKNM@E_PZNtvpr||}vB]QZCLNIKuttKCYQW@tqppqppqwLY\FNJuuJJKICE]UEuprrsspqwNETPX@ItwvwuLD_VFw|}sqvtOETV_DBHtqppvKF]TTOr{{y}vJHLF]_@Kwp}~~|qO^TTTUUWWTSveaagyqH@D^TVGNKHINIHJHMZVT]YX^RVJeblbd}KD^RFwssvJOM@EP^OttN@DDFFXV[elilgqGPUB}{~pNGXYSwefd~J[QUQ\]WW|mkhcE@}ee|H]^Ks~|qO^Q^XX\SVU[{moa}YMsp@WYCBD\\@uwH^PG@XTUSxlicrPA}{HW\LuO\GwwL\\ZZ]TUQW|bn`p]_qx~u_FwwLRT^CIIL@[\SQVQQTq`l`sR@rys@TDuvN\VCp}v@RUVWUWT|`cgtQQw}sJYWU^HJMZPNzerAWQTRFGV@z`frXIspuA_PSCL@FE\ArvBYRQ_Z^W@eadsGRQuqtJHB_P[ALJN^Erx}KXVT^EYTUUKegxqNAUS@MOwqLVQAKJ@R\q~suMERU_\PQQPTKzex|vMUPGHpsORUEAA@FYWYJuHHNA]VWUVWV}zzx~qE@wqtOD\T\GMCXPUTUQXACAGEZ^PVWUH|~zd{wWW@IKtvH_W]^EFGYV\@Z^XDD^QP^_VUWUIwrzdxtPQ_AwqHDXS\ZEEZLtLZ[XSVPQQ\RUFLvxd{pB]]BtuOM@_WRYFJpqJICYTUVPQVUPGu~dd~qNPRCwvuJODVQCtwpsvHF_TWQVVXwzfgeyqX[JvvpvKEQ_Nvr|}qJFRTLygggdxJSEItr|stMXYBts}rqtM_\v~edge}IGT]Atr}rquFVWZOtvqqtLZPDtp|x{wNAT_LtvqqtB^WPXALHJHBG_TTNvq}|pNF[PFIJttKBZ]TW]XGCMMAZ_VWOpr|sKGYPDNJutJMG^QTTS_ZFA@GX\Q[wr{xpODRT^ButwwKBDRWV]XFAAAE\PDwr~zy|pHFRT_BtwqvJI@YRQ^DF@CGY]Dtrxd{|su@RT_AKwqvuHLFXQSYZGFDX\T]Nq~dfzqIE\AHtqsqwHAD_TTRYDGE^]W_HqygagzsHDWWAts}}ssvHART]XDGD[_V[trydffd|KYU^Mq|}ptHODSUQ][F@FXQPt{edggerBTXLtvprrpvKF\UWRXZEZYRTFs{eeddd{pAYKqrspvttJB^TQS]_Y[[\TXp{ede{{yrK]EJp}}pwuHO@_V\_]SPS]]VCdgdx|rqtBVQ[Nv||rwLZSV\Y[X^]PTu{fagz|ptIEQ^FOup|~~}w@RWR_[EDZ^SUC~fafe}tMZR]FMHuwpsrswM_RXDGGDEY\VOz`caesKF^Q]MJuJJutuN@YWPYDA@GXRMz`b`epOD^QQLvqvuuuuIDSSY[DCNutJC^Kdccg|N^WPKs}swJHOARXHtuNCBNKODTJgonbeJPTH{~pNZ]WTHzxsIZ]PWVRRTq`infvQPt~{}OSZtpqwHCFYV\[EYPUpam`~MUMqstFQQDOLDYZAM@_RDA[PUWufobxA\v~}H^USLJOZSW]EGZ]VPYGG[RWWQVtgba}DUVH}}uZPUXNuMXRPWUPEMLC[]R]PWZzccxFQt}rK_TTWMuHDSTWUBppuGRQPTS\VF{af@QZvpwL[]S^LBDY\SW]MwwKB[QR_]VJegxIWTUtpuBE^\SAA[ZGZPV_GOJtH[WQR\SUuyxrL\YT_uHAACZPTRYZDLB_^IvvK[WW\YSMyrKGA_PBAZBJL]YANCR\BJutNG]VSSPQq}wHL@RXYBwJXR@CA^PQV^Z@uqtA]]^\STXsrvwtuZPDKwLRT^ZX[FG\UYOttOD^VUVWVVTIpqvqwO]OJIGY]UQ\ZCM[QVYANuuOESQPVTuvtqspM]LLFF@XTSZFGX\RVT\GLHLFXRTAwvsyq_XC@LuKYQ]_XGE^VT[@B@C@ZQCJw}x~vYV^DLwH[]VU\E[^\RQT]YYYED[\PQVZCu}{ypB\WYFHJLAXPP\Y[D[^]_Y_RS]RPPSRSQWTXEJzqHAT^[@IJLD_RUQ\[GABCC@E\PWTWVQVUW_Dwy~puKGTR]GNNAEY]TV^GBONIMG^SUTQWT]\As{~pttEWR@JIBBAX^FLKtuN@[]UUTT_vxy}psHYNINuJB^WU[@NwqtHCEQTT_q~~||HSVSEFHwtH@ESVYLvqqvuMXWFvr|y|BDXVZHuuuKMXUPAHtqqwKCXP@JqryvIH_ZCNtwuNG_WVXAHtuKKCXS[BJvr|qJuGTQ^FIJuKMG^SYFBBOMFZ_VYFHwqrqJu@PPY@OIIL@G\VWUW]^Y[[^\SWXGNtvsvJu@]VT\GBNKNOBZ_PWS\YY^^]QUUEFItwqwKJA\SQYDMNNIOAE^PVR\_^_]PTZDLttvwHKB^\UV^Z@OLLO@G[]QUTVVSSPQTU^XOuuvtJJFY]PYFBBOLFGXRWTVQRSPQT\_@JKwwJuMEXWT]ZFCLLAAG^SQUTPPPSQTP]XOHKtJHNG[RWRYEG@AAAZY_PTUTTVR@IHwwuuL@ZQP_ZGC@A@GY^]WTUUTVDLLututHMF\QUSYEA@CBAGZ_SQ^CCHtJtJNB[]VUS^EF@M@AF[\RWVGFLtuutHNFY\V\YEG@@FAD^^RWT[ZFJHKtHNC[^WUS\[EF@GFDY^]WWU[[DHNNuIO@ZYPQS^[DFGFFXX_QVTYYZNOOJNL@ZYPTV]_XEZDDXX^SPVS__CLBKIOMGE_WTS_YZDEDZXX]SPW_R[MAMIMO@GZRQTWS\^[EEDDZ[Y_RQWUU\S[CGBLCBFDXSQUUVP]^XXZZXY^]PVTUSV[FEBMCBFGXRSUWQS_^Y[[XX^\RPVTWPQ[DECC@CFFX\RTWVR\_^YYY_\RPQWSW]E[E@FAFDZ_\PUWPR\__Y^\_]PPVUQWSZ[Z@FAAGEY^RTUWVP]]\^\\_RSSWUVUSXYZAGAFGEY^STTWVS]]\^\__SSSWTUTWW^YYGGGADDXY_QWUWPS\__Y^__]RSVWUVWQY^XGGGGDEYY]VWTQPR\\_^__\]RPVTVTQY^XDDGGDEYY]VWQQS\\\_\\]RPVWUQTPX^[GGGGDEYYRVVVVP]]\_\\\RPQWWVVYY[GFFAFFXX_QVTUVPS\__YY_^\RSQWUQW\XXDFFAAAE[XRQVUVQS\\\^_\_]SPVTPW\XXEFFAFFZYYPWWVVPR]]__]\]SPVUVTRYXZFAAFAEXXRVWVQP]\\^^__\RSPWUQW\X[DAA@AAEXXSVWVQS]\\^^__\RSPWUVW_[EFCCB@@E[YSWUQPR\__Y^_\\RPQWVPPZEG@BCC@@[[_VTUTWQ]]_YY^Y^\]RQWTQ_XGCMONOM@GX\QUVP]_YX[XXY^\RQWURR_GF@MMMCAGY^SQPS^Y^[XY^_RQWUR_XAMLIHILBAX\PWP\YZEEDE[[^]RQT\\ZCMLIINBCG^\VUQS_X[EDEEZX^\RQTP_^AMLIKINBC[\PWPRY[ZEDZZX^]RQT\_EMLNJHHLBD_SUTP]YZEDGDZ[Y\RPTY_[LOOJKHOCA_RVVR_[DFGFAEZ[\RPTRXGLIKuuKNBDYPUVR_XEFFAAGEZ^]SWQE\AOMNKLLFD^QTPY[GC@BCFG[^]QTS[ALKuuuJNME^QWS_XZGGGFD[Z^]]QTTQX_CNLIJNOAG_QUP[[ALBOOCCGX_PUTR@CNtttwJICE_WUQ\XZDFFGGGXXYSPPU\Y^MNLKKOLFE]W][ZCLMNLB@DX\VUUWXBBJttttHLFYPVRY[DGGFDEDY^^PPSUTX_EOOOuINBF[RWPY[AMLLNM@FE_RVT]A@IutttHN@Z]WUP\Y[DDDGE[E^__PQQUTUY\ZOOOuHIL@E_QUPYXFBBMLCFG[\STT\AAIuuttHICE\VTS_X[DGDDD[ZX]\RQQWU^RZLMLJNNMAZ\PUS^[FBMMOM@FZ_RVUQZFBKJJuJOME^QTS\^X[[ZYX^]]RVQVTTTUU\SYCCBHNLMAZ\PUVR_DA@MMCAGZ^RQV\EFOHKJJNMAXRWQR_Y[[[ZY^^]R]VQQTTWUUV\]FBCOHLL@G^RVV]XE@BBBMAGE_SVWREFLHJJuHOCE_QVR_Y[ZDZZZX^^]RSQWTT\PEC@LHLL@GYRQWP_ZG@B@M@GDXRPTPZDMIHHJNOCE^PWS\^XZE[DEYZY]_RWQW_SXC@BHLMCF[\PUPR^GF@MC@@G[^]QWS[GBOHKJIOCEYPWP]^YZZ[DEXEY\^RVPTS\SA@AONMMAG_RVSRYGDAB@A@EX_RWTRYDBMNHIOMF[\QTQR_^Y[X[ZYYY]\]QVW\Q[AGCOBBAGX]SUVP]EEDBCFCGZ[_PWU]YEBLOHIOM@Z^PUTVS\_^YX^YY___RRSQVVTUU_SX@ACNMBCFZ\RTVP]EZGCAFAD[^]QUS\XABMNNLBAE^STUWP]\_YX^XY_Y_R]SVQWUUPSSGGFMM@CGZ_]VWP][EDA@AFD[_]PUUS^Z@BONNLBFZ_PTQS]\^^^[Y^X_]_SQPTQSSGGGML@CFE_]VTSRXGDACFGF[^_PTQ\YGCBOOLB@DYRVUVPR\\^^^XY^Y_]_RPSVTTVRPEGDCMA@GZ_RVTPPXZZAADFEXY]PWP\^G@@LLBCFZ_SWTVQS\\_^__\\\]]RPPVWWTRQ_FGFLC@@GX\STWPRYZZDGEZ[^RSV\\[@@BOBBADX]QUWQS\__^Y^_^\]]SQQWUURP[GD@MA@FEY\PUUPS][[[DZX[^]SVV\\EAACM@@G[_STTQPR__^Y^^_\]SPQTUUQ]]EFGCMA@GZ_RVUQR\Y[[ZEY^^SQQ\\YFAAB@FD[_SWVSS]_\__\\]RSQQVTUS\\DAG@BGGEYRQWPS]XYXZY^Y]SSWU\Y^ACABBFGZ_SVTWP]]\^__\]SPQVWTWTUWTTTU]]_GFD@FEZYRQUTVR]\XX^XY]\RVVWU\\YFGG@GZX\PWWQS\]\\RSPVWTUWVQPPPQQVTTW\Y^ZD[ZZY_]QUTPR_XYX[^_\SQWT]YYEFEDDX^]PTUQSS]]RRSVWUTVQPPSPPQVWTUUUTTUTUUUUTTWVQQPPPPPQQVWTUVVS^\_[Y__RQVUWVP]]R]RPVWUWVVQPQQVWTUTTWVVVVWWTTTUUUUUTTWWVVVVWWTUVSS\_\\\SPQTUTVQQPPQVWTUTWWWWWWTUUUTTTTTTTUUTTWWWWWTTTUUUTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUVUUQWVWVWTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWTTTTUUUUTTUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUTTTTTTTTTTUUUUUTTWVQQWUUTWP]__RWSAIO[W]ZFDRTR^X[XSS]\]SWUS]RPWUP]RPTTQSSQTUWVQVWUTWWTUUWVVTVKrrHUT]AuuAT_EGA@EVWYEZY\PWS_RSHpvAUSEOOEQ\Y[EG[PT[@FYQTU}clgYT]B}z}XDNHIJK[FuJLEXZ^QZZPtamfCQZq{BYCNNJtC[JttttO]YBDWam\[qfbdDAwsr|}@[q|sJ@^PAMESUfkjaWP[wda{[GtvqpqDAr~|wKI[]NO^dnNXvgmaJ^Jp}~~tUwx~pJ@U@JBRgiJXwdm`w_Jp|yywt~xysJBPZIMRgiOYwgm`wRIq}yyvKxy|pHTAuO^~j}WIemm~Gurxz|XEp~y~}vX^IHDQ`oDRwfl`tUFt}{zpWFq|~~rt^^ML[QyksC{bb~_Np~z~@Sus|}qOTY@F\Qfl@SJdb`vZKsy{}_\Jp}st@UR[[\RVdoNSNzb`sXHp~{|EQMvr}w@QW\X[X]{ijmNSC~afpXNv}~}DVMwr|}wCPT_ZEX]wlkorTXpga~P]Bts|OCvr|sKV^CBDXReonf[QByfdK[OwrqREuvsrswER@MGYR~mna@WF|geu^Bup}v\PMuqpvNYP^XX_V~bogXTEre{ITX@IvswR]CJwvwO\PR\_^\V[dbmyUM~e|DT^GNvpNRDNtwwBQPE@DSTVQWv`obtSveepVPXAursFU_AKtvuZRG@XWUVQVs`mf@Rqz{tT]GurqEQZNtqtERXYPTP__PufbfHWtx{tURDJsvZQYLtvtETZAZRPSRVtefeLWK}}HVU_LwK_PEMJtO^TZ@ZPWSQQ{bm{SGe~CSCprKTV[IvvMWVXE[XX^]T^szxIDvpJ\VFJKDUPZOJNDYZG[QV^_V_emm~O{gyARuK_IvtEWTSAJJATVWUQQCqru_RMJNXTXMLEVSENuIAX^XXPT]Rcb{]@~d~BVN}}KVRLwuEV_DCBG\TUTUWPSVYNtKEPYAAXQP[D[RPDNHMD\P]\PWTrfa_Zs~pDBqvMQWAHB_QEBCXQVPSPUQ]]Q\AOMZ]QUT\[[^SVWQ__]PWTS[GGEZEE^WVT^|eewQMspK\POtO[T]A@[RVQXDZ^\RVTR_]PTSFLBZSTU]ZZ^RVTWR\]SQVTURXDDEXYY_QWTLr~s@PTVLJOG]QQ\GDY_]PS_\\_]WUQS\_^\PWWTWWWQ]X[YRW]GC@Z\PTV_Y^\RQWVSRSSPWTP]YDFFDZX\VUUSt}rKX]Q[MCDZZYWWR\_XEYVW\XX]TUS_^_\RPVUUWPSSQVWTT\XX^\]RQUTPSSSRRRQTUTWVP]_^^^X[YRWUWWWWVQVPJsqHBGYS^_XG@GRV_X_QWSSSRRSWUQR\_^Y^]QTPY[YYY_]VTVWVPR]SVTTTUUWQSR_[EGDZ_PTTWVQVTT@uKLLMG]Q^ZE_QVVVTVTUWVWTVPPR^ZEX\SPVWUTVQQVWTW_Z[XEE[]TUUUQR]SPSSSVUUTVQQQR\Y[EGD[]WUUUUTU][[X[Z[^PWWWWUVQVVQPSSQQQVWUUWQPR]_\RPWTUTWQQPSR]]]]]]RRRSPQQVVWWVVVQVWTTTTTUUUUWWTWTUUUTVTUTTUWTVVTQVTWWTTTUTTUUUUUUTTWWTVVUWUTUTUTTUUWTUTUUUUUUUUTUTWQVWWUTUUUTUVWVWQQSPSSQQSSQQQPVUUTVTVWTVTWWTUWTTWTWVVPPSSSRSSPPQVWTTUTTUUTWTTWTVWVTWQTTUWVVPWQVVTTTWTUUTTUUWWVWWTTTWUTWWUWWTWTTUTVTUWUTWUUUUTUWUTWVQVVVTQWTWWTTUUTTTUUWUTWUUUTTTVTWVWWUUWVTTWWUQVTUTWTWTWWTTWVWWTWQUUWTWUUTTUWTUQTTVUTTUWPQQUTVUTQTUWWTTWVVQVQQVQWQVVQQVQVWVWWWTUVR^ZDGFFFGEZ[XYY^^__\\]]RSPWRKpqwtuNEUUSXFF[]]\]STVS]R]YEFFE^\SPQTUTTTF|eyvMZP_DD[[E[]WPSPP_Y_QQ^EGDZZX^]PVQPQUtzer@SXMLF_PQTV^[X\SPQTRECMMCGYPUUVPQUEyd{u]\OtHZVW[AA[STQ[CLM@E^PUVR\SWS}gev\_OtJEUQZCCZPRGONMGX\SVTWQ]\PUR|gev]XItJZS[@AXVQ[BOBE_RPVWTQR]STTrdevSYNtK[P[@AXWUQ_EA@GZY\SQWWQSSQR}d{tPUEKwKYRDB@XWTRY[EDGGZ^SWTWVPPQW_dxHUEuvI\SGBA_Q_ZZX[DFGXSTUTVQQQWUpdev]\Nwu[PEB@YWW_ZGFAAFZ]WUUTVQQQWuedrDPBwtAW^AAYWSXDFAAGXRWTVQPVUtzzqXROwtDTWZCF_UR[ABCF[\QTUTVSRPTFye|BT@wvMSYCC[QV^GBB@E_QTUTQSSW^}z|OPUFuwO_U_A@ZRTVX@BCF[\PTVSSQKxxvZ\IwuGSWTVECFYPWURE@@DX\PWUUVQQTt~}I]^ItOYQWWRG@E_PVTT^G@FZY]QTUTWQQW@}|tXUQCuIESQQTW[FE^]SPWU]ZGD[Y_RQVVQQVWTt}qMRUYOH@^SSPR[Z^]]RSTS^[Y___]PQVQPQTPwrvCSTXONF_]\S][X_\\RPUW]^XY_\]SPQQPPVUTupwC]QW^BMDY_^RP^_]]\]PTWR_^_\]RPQQQQVWQuptC\SW^CCEXXXSP\]]\_]PTUVS\^_\]SPQQQQQWUMvtL[\RRDAE[[Z^TVSSS]__RWUTQS]RSSSSPQVQQWUTNwJBZ^S\EE[ZDD\UVQQR_XYRVWQSRSPSRRSQQPSQWQItHCD[RU^E[XEFG]UTWVV\[[_QVQRRPQPRSPVQSSQTFKI@EX]RX[[DFF^WUTWQ\XY]VVS\]QVVPPVWVSRPTZIICD[_S^YXDAAXQTUWWWVRY^]P]^\QTVWWVPRPWXON@D[_UP_^YEA@ZSWTVQVVS_^]S\^\PTUTWTWVSRQWQCNCFE[SW]_^[FCG_PVQQQQP\_]]^X_STTTTUTVSRQT]CM@GZ^WQR\^ZAAZ]PPPQQP]^_]S^Y_PTTWWUUWPSQWRABFDZ^WVS]\XDG[SVVQVWVP\\RP]^_SWTTTUWPSVTPD@GE[YQVPR\XDGZ\PQQVVQP]\]S]^_RVWWWUTQSQWQZGDE[YQVPR\YEGZ\SPPQVVPR]RR_X^RVWTTTQPVT_DGDE[\TTQPS\[DEY\RRPVVVSR]R]^X^SQWWUTQQWT_EDEZZ_VVPR\YEGDX_]RSQQPR]]]^XX_RQVWUWVVWTV^[[[X^QWVPR^ZZX_]RRQVWQPSS]^X^]PVWTUWWT]X[[XYSTTVQS\XEZX_]]SQVVQSPS\^Y_RQVWTTTUP^YXXX_QTWWVS_[[Y_\\RSQWVQQPS\Y^\SQVTUTUP\YYYY]QUWWVQS_[XY^_\RSQVQQPPR_^_]PQVTUUUUR_YYXYRVTTWWVQR_Y^^__]RPVWVVQPR\\]SQVWUUP\_^Y\PWUTTWVQR_^^^__\RSQQQVQPR\\]RPQWUUUWR_^^Y\PVWWWWVP]_^^___\RPQQQVVQS\\]RSSQWWTTUWS\_^^]PVVVWWVQR\_____\RPVVVWVVS]]RRPPQWTTUVR\_^\SQVVVWVQS\\\___\]SPPPVQQS]]]RSPQWWTTTWS\_^_]PQQQVVQS]\\\\__\]SPPQQQPRRSRSPQWWTUUQR\^^]SPQQVVVQR]]\\\\\]RSSPQPPRRSSSQQVWWWTUUP]_^^]RSPPVVQPR]R]]\\\]RSSPPSRRRRSSPQVVVWTUTS]_^\RSPPPVQQPSSSR]\_\\]RRSRRRRPQVWWWWWWTTWR\^^_]RSSPPPQSSSSR]\__\\\_\\]SSQWTTTTTWWTTWS]__\RRSRSPPPSSSSR]\_^YYY^_]RQVWUUUUUUUQR\_^_\\\_\]RRRRSR]_YX[[[X_]SPVTUWPR]_^^^^YY^__\\]]]]\\\]RSQVTUTWVVQSSSSSSSSSPPQVVVVWWWWTTTUWVVPWVQVQVVQVVVQVQWVVVVTTTTTUUUTTVTVTWTWTTUTVVTTUTUUUUUUUUTTTWTWUWTWWVWVUWTUUUTTWTTWTVWVQQQQVPVVPVQQWWVVPQVUTUUWVWTUVVQQWTV]Y[X^SWWTWQP]__ZXD[X^^]RVWTUWUVVQPVRRSSPVVTWTTWTWTUUTTTTWWQVQVWVWQTQTVTWTTUUTTVTVTVUWWWVWWTWTTWWWWVWQWWTWTWTVWWTUUUTTTTWTVUUTWUUVTWUTTWTUUUUTTUTUTUTUUUWTTTUUWUVUWUWTUUTUTTQWVWTVWWWTVTUUTUTTTTUUUTTUUUTWTVUTTUTTUWTWWWTTTTTUVUVUTUTUUUTTTTUTWWVUWTUTUTUTTTUVTUUTUUTVQQSR]\]RRS]S\PQTUVVWVVS]R\_S_]\\]_S]PQQVQSPPPVQVVPWWSWSVWQVVTQWRQRS]P\WQWVWUVWQTUTVTWWRSTSW_^BJMBEVWWWVQSRR]RSS]SQSQRPSRQPVSPVUUTUUTTUUPWTUQUTWUUUUUTUUUTVTWTWWUUTTTWUTTTTUW\[GBOKJKILCGY]PWTUWVPPSRSVUV^ENtqpwKOFXV\EMJtwtKMD_P\Aw|xz~}ptM__AJp|}qtMXWRFuegdy}vNY_Btry{x|vIDVWUSBwxgaae~sHXXNw}xz{qHEVVRRQZu}d`caz}wG]LwsyzzysJFSV_XYSTMqxaccaxsK^ZJqr~xx|wM[WW\ZDE_UAv~gcb`eruZYIqr|y~}vMXQQ_E@AD^TAq~gcc`esKX[Hp}|~stC_TPYDCCF[PTNr{fccaxwCQTAtr|rvNXVW^DMINBER@pyd`caeqMRGur|}wL^VXCHttKMZPZvzgafepC][Hqr}rpt@RRDLJwwuOESPHszggzsB^RCuqqqvuC_]ELJuwtNA_TQIq}xddzsB^S@uqqqvuB^SDNJwvwJCYV@wp|zde}H[Q[NtwwtuMYPZBHtvwuBXVYItq~zz|JG\URFHuutuNGPVXCHtwwuOD]T]Luq~zeywMZPSGHttwwK@R]GOuwvwK@YQP@Ot}y{uCXQQEHutwtHAPRFHwpsvuB[PXAIp~{~wNG\UXLJuttH@]VFNtpspwMD]YFIszyvKF]UYNutvwKM\^Otsr}stBXWYAIszxqHG]W[HtwvtHCRSMw||qKAWWECvxe}tOXV\CutwwKMXTZKp||}vKA\[MwzdxqHZQ\BwqqqtOETYBus|}tBYVR@IsyzeruAPVXNwttuLF]YFHttqvuNXWPCIv~yz}HFPVXBttuuMD_]YFBOtJJIFZ]UUDIur~~tA]^DHtJKME^UPYZ@@ABGZ_S\]QWWTVWTPSVTXIJvrr|wF]\EBJKNMZ\VQYZGADE^PVVQR\_XXY_RQTQEGBJuvJD_TP_[C@AD^SWW]_XZY^\PVTTWVVPPR]]\\RRPWUPD@MKutKE]W]XECCAE_QUQ\^X[^]PUQR\^^YX^\SWUREFCNHJMXPTP_YZGD[_VTP]YX[X\SVUWS_XZ[^\RQWYFACMMLG\TVR^X[EZX\VVR_YYXY\RVUUWVQVVWU^ZEGA@BE]TTP]R\^^^]VUTVPPR]SPTUWQPSSSPQVVWUTWVVQQQVWTSY[ZEEEX]VWPRRSRSSPVTUTQS]]RRSPQWUDMLNHKJBYWP^DEZZ[X_WQ]YX^^\SVWP]]\RPQWUTVQPPQVWUUTWWWTUUUUTUUUUUUWQPPVVVWWUUTTWWTTTUUUUUUTTUUUUUUUTTTTUUUUUUUUTWVQPR]]\\]]RSPVWTUTR^XXYYX^RVWS]\\RPQWUUTWVPSSPWUUTWWWWWTTUTTTUUUUTTWWWWVVVVWTTUUUUUUUUUUUUUUTTWWWWWWWWWTUUUTWQPPPPPPQVWWWVVVVVWWWVVVVWWTTUQ_[ZZX^_]RQTUWWVPS]]]PWUWQPPQVTTUUTWWWWVVVWTUUUTTTTTTUUUTTTTTWWWTTUUUWQPPPPPPPQQVWTUUUUTWQQQQVWWTTTTUWS_YXY^_\]]SQWTWWVQPPSPQWUUTWQPPPPQVWTTUUUTQR]\\]RRSSPQVTUTWWVVQPSRRRRSPQVWTTUWR^[ZZ[XY_\\RPVTVPSRR]]]]]]RSQVWWWWVVVWWTTUUQ^EF@AGZY_]RPWUQR\\_\\]]]RRSPPQVWTTWWWWTTWXCHuuHMGX]PWTRYEDE[_SVUUQ]YZDDZ^RV\CuvqvJBZRTW^GBLBFXSUS[@NKHLFYQUDus}}stMXVVXCIJKLD\UTRXFCMM@GX]WRMq||qHEVU\GOKJNF_V_GMHJHLF_WXJryyqOYSZMKuJMZPRZBHttJLERFv{x|w@SW^@HttK@_Q\ELuqpvKDTXtzzypL]\FHttJC^TS^FNtqpwNXWWUEv~eeyqCSWYCJwwJ@\WP\ZCKwqwHDVVPVZwzz~qCPVXCHtuHF]VR_[FMHuuKMZQUPRSWSH}{eysLRRGOutK@\TQR_ZALHJIMZQVPQTRIrxzysN\RDLJuKC^TQS_ZALHKIB[PUVQVUPLpy{~sN_RDLuuKC^WP\ZALIILAYVUTT]Np~y|qM\\FNuuH@_TP^DBNNOCE\WUUUU\Np~}vCRV^@IuuNF]VR[ALNNBD_VUTWVVWUWGus}rvL_URZCIHOF_UVRYGBONLAXSUWWWWTUZKq}rvO^PXAOILF_UWS^DCLOBG^QTTTUUU[IvspwM^PXFMOBD\WP_EABBAZ\VUUTTUU^MtvvJC_V_E@CAZRQ\ZFCCAE^PUUUVEIwqwHGSUR[ABBFYQUP_ZFC@G[\PWTTTTTTUUTWVQVTSDNuuIA^WW][GAGXRTVRYEFFDYRVUUTUUWVVT_AIuKMD]UQ^EFFE^QUVR^[ZZY\PTUWVQQVWWTTTTUT_FLNMFXPUV\XZZY]VTVQS]_^^_]RPVTTTWT\AHttIA_TV_EF@GXSVR^[Z[^SUTWQPSSRRSQTUSXDAFE^SUTQR_^Y^]PWUUUUUUTTVQQQWU\AHtuIF]P^EAAE_VUQ]^XY\QUTQR\^^\STUTWVQVTUUTTWVVWTUUUUUUUUUUTTTUUUUTTWWWWTTUUTTWWVQQQQQQVVWTTUWP\_^_]PVWTTTTTTUUUWQPRRRSPQQVWTUTURE@MCD^QUVR_^_RQUTQSRSQTTVQQQWTUUUTWWWWTUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTUUTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTWWTTUUUTTWVVQPPQQVWTUTS\\]RPQVTTTWWWVQVTUTWWTUUUTTUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUTTWVVWUUUUTVPSSPPPQVTUUTTTTTWVVWWTTUUUUTVQQVTUVS]\\_^_]QWTUUTUTWVQQWTUUUTWWTTTTTUUTTWWVWWTTTUUQS]]_YY^RQVWTUVPPQVVVVTUWVVVQQPPPVWTUUS_^YEFFDYRPQTTP]\RSSSSVTWWWVQQVWUUUWVVVWWWWTUUUUTTTTUTVSR\^YY^\]]SQVTTTTWWWVPSR]RSSQVWVRXDCOOCFEX_VVS]^X[[^]SQTUVPSRR]RSQWUTQR_[ZEZY^_RPWTQS\^YXX^\RQWW]XAOLMB@FD\WWR_YXXXX^]PVTUUTTWQQQQVVWTSXFMIJOA[]TPYEGFAAEYRVUWPR]RPW[MKwrruG]U_COCAAD]P\YGCCF[Y\VUWYGBIuJD_PRXDDXXX]QTTVVTQR]_\_Y_SQWUUDNv|sHD]^@LOOLF\Q\Z@NIMFE_VUTXFOtqvCY\]ZFFGGDSWWUUUP_]_X[[^RRSTXOq~}vB^SGLKJKMZQQXAIuJO@[PPEMuvsqA[\^FCCAAEQP^^[GAG[__]WEJs~yqB^]@HttuNDPSZBJtJOAXQSELuqpwGXQV[A@@AA[WU]^^XDD[^\]PTFJp~ruFSXBHJuJC^T\GMHuKME\WTVTURDMHtwJD^VW^ZDGDEYWTWTWQR_R_^_\]SPV[Otp|}t@\\DBNHIC^QUR[BHIMFZRTUT\FOKtwuF_UQ^[EAFDYSQUTQSR\_^\]RPQUDHws}rtAQU_DBHKNF^QW]DBLMAZ^SU]FOKuwtBYP^XEAAGXSVUVPPR]]]]SPQTFJvprrwAWWYFBHJHCYQV\XG@CFZ_SWRFOIIJKC^RXZZEEEYPUWQQWWQS]RSPRRPW^IwvpsqH_RDCMMLBDSP^[DGFG[]V]AOOMOOA^PYEZXYXY]VWQSRQWTQRRSPPSSQUAwspqqwLS\CIICGEYPTP^DAADX_RVTZBMCCB@EPPYEEX^_\RQWVQPPVWVPR]SPQVWU]HpsvvtHEUYLJKBE_RWVR\^EACA[]QTWWTUXMIOC@FE\W][DDX\SPQTWS\\]SSR]]SVUPMvpvuHMDPW]EBIOG\VRYXX[ZEZX]VUVQQWUYCOM@FEX\TUWP]Y[Y\PWUQ\YY_\]]RPWWAuvtHLAE]TP\[F@FXSV]^^Y[EDZ_VUWTPGNIBFZX^STQPP]YXX\QUV\[EZY]QVTUTZOJNBGZ[_VTQSS]^X[YRTWS\___^YY_PURGMBFZY^\PTVQQS]__]VUQS\YYXY]VURGMMAEY_]QTVQQS]_^]QUWP]\\]_^XY]T]GMBAZY^\SUTVVQS\YX_SWWP]\\R]^YX_VPEBBAEY^_RUTWWP\YX_SWTS\____^_]QUUY@M@GZ[X_VUTP_YY\PTUTVQPS]]RQTUQSSQTTWWWUW_ZDEEZX\PUQR\\]SPVWUTVPS]_^^\SVTQXGFGGGZ^QTS\_]RRRPTVSRRR]]]SVTUTWTTUTUW\XZZEDZ^PTTQQPR]]RPWUWQS]__^\]PVUV\Y[EGGZ^SVUTWQSRRSPVWUWQPR]\]RSPVWUWR_XDGDZY\RVUWQSR]]]SQVTTVPSR]]]SPVTUVQS]\\\]]SQVWTUTTWWWWWTUUUUUUUTUUUUUUUTTTWWWWWTTTTTUUTTTTTUUUUUUUUUUUUUUTTTTTTUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUTTUUTTUUUUUUUTUUUUTTTTUTTUUWWTTTUWWTPVTTWVVUTUTTTQVUPVWUSVWUTUTTTTWTTSVWWUTTQVTWQVRUTRTUVWQUUUWVQTSRPWQPPPQWTTVPTVUTPVQTTWWPQVVPUUUVTUUTTTTWTVWWQWPVVTVWVWWTVUWTVTTWTPUWQUUWTTUUUTUUUTTUWTWVTWWTTTVWTTVWWWVVTWTWTWWWWUWUWTUTWWTTWVWWVVVVWQWVVVQWWUUWVWVQQQQVQVWWQPQPQPQQQQQVWWTUTVPS\^_YX[[[[[Y^^_\]]]]RRSPPVWTRYG@FCBADDX_SWWUUVPS_^^YX^^\]]PQPQVQQVVWTTV[GBLMHBDF[PVQS\YXX[^]RWWPP_XY[XYY_RRVSYGMMIHC@F^SWQS^Y[[X\\STWQ\EAFAFZ^RVUPE@NHKJO@G_WV]YZEDZY]QVQ_EDFAGDX]ST_EBIKtHMCZSTQ\XEDDZ^\QTWPRYX[Z[Y_SWWYFMNKJO@FYQUP\XEDDX^]WTP\YZEEE[Y]PTTYDMHKtIB@[PUP\[DGFEX_QTTPR^[EEE[Y\PT]ECHKuuOBG\TWSYEFAGZYRTTQ]YZEDD[^]VV[GOJuwKOBESTQ\ZFA@GZYSWWQ]Y[ZE[X_PWW[FNutwuNMDRTV][F@@AD[RWTQ]Y[ZEZX^SWQ[AIutwuNMERUV_EABB@G[RWV]XEFAAGZ^ST^EMKJwuNLF\VUSYG@C@GE\QUUP_[DFGGZ^RVTYEMHKtKLBERTUPYDA@AGZ]QW^^DB@@@[Y]U]YENIJuNLBXSTURXDF@FG[]PUQ\XEFAFE[\PUQ^ZMIHtHOME]VV_ZGAFFE_SWV_[ECBAFE_RTV_YMIHtHNLG\PV_ZG@AAG^\QPYYGCAFGX\P\[ANKuuIO@XRUUSYEFAFGX]PP_^DFGDEY\QUS_ABOJOLMG^RTRYEGFAF[Y\QWUWPR_X[[Z[^\SWRGNuwqvtKME]W][FBBM@DXSUV_[DA@AG[_STVRE@BIOMBFYRUW]YZEDDX^\PWTUVVQR]R\]]RQW]DCuttvJOCXPUSYDA@AFE\PTSYZGAFGZ^RVQYFCIHNOBD^QTRYZDGGZY\QTUTUS]]YY^Y\SQ^[@IIJKOMFYRTP_[DGFG[_STWRXDF@@FEY]QV\EABNLB@E^STP\Y[ZZ[^\RQVVQPQS]R]]RRSVTW^ZBHHuJNMFYRTSYEGGFDY\QV][DGAGEX\PTTSXDABB@FE^STVR_Y[ZZZY_^\PPPWWWTWVTTTU\YFOLHIMCDYRTQR^X[[[_RQWP\^Y[X^_RQTWSZFCOLMBGX]TTS^XZEZX^RQWUTVPS]\_\]RPWQSXGFBM@AGX\VTP\YX[X^\SVUTVPR\\__]]SVTV]ZG@BCAG[_PUQ]^XX[Y\]PTTQS]\_^_\]PWUUQ][DF@FFDY\QTQR_^YY_RSVWVSR]__\]SQTQRYDG@@FG[_STQR_^Y^^]SQUTQS]\_^_\]SVTQ][DG@ADEY]PTP]_^^_\RPVUUTVPR]__\\RPVUVSYEEFGE[^RVTQR]\\]RPWTUWQR]\\\]SPVTVR_ZDDGEX^]QTWQS]\\\RSVTUWQS]]\\]RPVWTR\XEEDDXY\PWTQSR]]]RPVTTVPR]\\\]RSQWUP]^[ZZZX_RPTTQSR]]]RPQWTUWQPSSSPQVTUVQSR]]]]RSPQQVVVVQQQPPPQQQQQVWWTTTUUUUUUUUUUUUUUUTTTTTUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUTTTTTTTUUUUUTTUUTTTTTTTUUUUUUUUUUUUUTTUTTTTWWTTTTTTTTTTUUUUUUTTTTTTTTTUUV\XZ[^\]SVTUUVS]]]]]]]SQWTWWWWTTTTGKJM[RPWT^ZX\RPQWWR\RPQPVUTVQQQQQVTTWPR]SVUUUTTUZMBZSURX[]VTV]\RQWWTU\[[\QUUTWU[wqJ[_COGPREG[SUS\\PTQ]]SWUWVP\Y^PTWWWTTOvtFVPECF]T\[YSWSRPTUWQQQP]XZYQTVVWTUQv|sBU^CKL]UTP[GZRUQR]PTVVWVSRPWUTP_XY]WUTWWTUI}rIWRDNOYQQP_EZRUUWPRSTWQPQQR\\\^^\QUQPPVvx~KW^@HN_SRRXGE]UUTVQSPTWPRSQPSPVQR__RTTVQVTB|wRT]ZMLZPRS]YYRUTWWVQSVUQRSQQS\XXRWQWUUSpy}AUPY@IBQV\]RYEXSTTTTVPPUVRRPPSSSR\\RPWTWVQVU]v|pFUSXAL@STS]]^X^QWWVVVPPTWPRSPQP]Y^PTQQWUTTFs|vYUSX@LDUQRR]Y[_VTWWWQSPWUVR]SPQRY[\WQSQWWWURv|pFTP_GBASWR]]^X^PTWWTWQQWWS]SQVSYZ_WVSQTUUGs}w^TP^FBDWP]R]^X^PWVWWQSSQTUQR]PQ]X[]UPRPTTu}sMUV]Z@@_SRR\^^RUWWWWVQVUTPRRR]]]PTTQSSVTUUZvsu^TQ\D@DQQ]RR_^_PTVWWVSSQWWVQR]\\]PWTUUUWWWTRtsvGV]Z@FSUQPP]_\PTWWVPSVTTWVPS]]]SVUUWVVVW]upwDV]ZAGSUPPS\^_STWWQSSPQVWVR\_\SWTTTTTTTWWDwqK_UWS\ZF[WWPPS]_\PUTTUWPPVWWWVPSR]\RQTTVVWWTPOtK[UTVS^EZRWSSPR\\RWTWWWVPSPQVQR^^SWTTUUUPOtJZTQS^EZSUQPQSR]STUWWTTVPPQVVS\_]QTUWWWUUGJJAQWQS\XZ\UQSPPSRSVTWTTVPSSRRSSPWUUTWVVTZIKAQVQPRY[\TVPPQPPPWTWWTWVPPPSR]]SVTUTVQVTUEOODVUVPS\YY]UQSPPPSSVTVQVVVQQPPSRSQTWWWT_BO@]WPR]^Y_VWPPPPPPQTUVPPVWWVPR]]SQTUTWWWUXBBEPUWQP]_^RTWQVQQPPVTWWTUTVS]RPWUUTTWWTT[@AXVTVPS]_\PWVVVVVVWTVQVWTWQSR]SQWUTWVVWUV[FG^WWQPS]\\PUTVQQQQQQWTVQVWWVPRRSVUTTWWTU^DE_TUWVQS]RVTWWVVVVTUWVVWTTWVPPSPVUUWWT_DD^VTWVQR\\PUTWWWWVVVWUUTTTTTVS]]SWUTTTTTURZGZRUWQR__RWTTWVQQQWUUTWWWWWQPSRRRPVUTWVVTUSYX^PTTWWWVQS]]PWUUTWTWQPPQWUUWQSRRPVTTWQQVT]EGZ]WUV]^_SWUUVPPVTUUUUTWVQPSRRPVUUTTTUPYXYRVTUUVR\]SVWTUUWQPPQWWTUUVR\]SQWTUUTTUW]^^]PVWUQRRSQVWTUWVVVVVWTUUWQS]RSPVWTTTWWTTWS\\]SPQWUUWQPPPPQVWTUTWVVQQPPPPPPQVWTTTTTTTUQR]RSSQWTUTWVVVQQQWTTTTTTTWWWWWVQPPQWTTUVSRR]]RPVWWWWTWWVVVVVVVWVVVVVQPPPPPQQVWTTTUUVPPS]]RSSSSPQVVVWWWWWWWWWWWWWTTTUUUUUUTUTTWWWWWWWWWVVVVVWWWWWTTTTTTTUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUTTTTUUUTWTTTUUTTUUUWVTUPTPTTTTUUTVTUWVVWWTWTTTWTWTTTTUUUTTTUTTTTUTUWTTTUUTTWUTWUWUTUUUUTTWTUWTUTTTUTUWUWUTTTTTTTTUTTTTWTTUTQS\_^XYY^\RPWWUWQSR]]]]RSPVTQYGAMIOBAD^VQ]^ZEE[^]VTP\Y[EZ[Y^\SVTUTWVVWWUTP\XXX[X\RQTTVP]__^_\\]R]]]RRSPQVVWTQDuqrsvwIYW]Z@LOOCZ\TQ_[GFD[_PQ\[F@FDZ_QT\ZBOM@@ZSUWS_X[XY_RWP_E@OIOAE\WWGKp~}tBXRZ@OHHMZ]WQ\XEDE^STV\[DGFAFXRQTQYDABLCE_VQR\^YY\SVUUTQPR]_^Y[DA@AE\QBwsssquZRGBCC@D_TUP\__\]PTTQ]_^^^_\R]]SPVWWWTUUUYAC@FAD^WUP^[[^]SQTTVPRRRR]\^XEAMBD]WLp|}vIF\PYFLNM[PP__\RRPWUWP]\]SQQQQQVWQ]^Y^RQVWUP[AAD[Y_STTPPSR]\RQUWVQVTTVRYAIuHA]TNsrt@XVVXDGGFGXSUTVS]\]QWP]]SQVWVQQVVQS\YXX_RQVTUT\EFDX\RSQWVS]RSQVVWTTWQQVQR_[DA@ADYSTUWI}y|uDP[BOCE_RPWQ]]PQVVQVWVVWWQPSQWUUWQSSPQPR\_\PUS[FFZ_SQQVTTP]]RPVVQQVWTVSR]\^[GFGXRTTOr~}uETPDLOF^VS\RQUUTUWQPQWUUUWWWWTTVPSSPQVVQQVWUW\[DD[_PVWTTUUWP]\\]PVWWWWWWWQS\YEDEYRTZKvwHDPPXGGZ]WWPSPVUWVQVWWWPR\^[EDZ_Q\MtwJ@\UT]XEEYSTTQSPVTTVPS]\\YEGGXPVPVWZOKNA_WUWS\^_SWUTUWWWTUTTTTWVPS]^[EZYSUWQQWPZBNLF^VUUUTQR\\]PWUUUWVVWUUUTTTTWVQSR_X[[^SWUWVVURZA@FXRWTWTUTQPSPVTTWVWTTUUTTWWWVVQQPS]_YXX_SWTWVVTRYED[\PTUTWWTUTVQQQWUUUTTUUUUTWVQQQQQQQVVWTPXF@GYPTVVWUUWPR]RSVUUTTTTUTTTTTTTWWWWTTTTWWWWWWWWWWWWWWTTTTTTTTTTTUUTQS\_^_RPQVVVQQQVVVQQPPQVVWWWWWWWWWTTTUUP^ZZY]VUTUUTVQVVTUUTWWTTUUUTTTTUUUUUUTTUUUUTTWWVVQQQQPPPPSPPQQVVVVVWWWTTTUUVPPPVWTTTTWWWWWWVVVWTTTUUUUUUUUUUUTTUTWVQQQQQVVVVVVQQQQQQQQQQVWWTUUUTWVQQQQQQQQPPPPSSSSPQQQQQQVWWTTUUTTWWVVVVVVVVVVVVQPSPPPPQQQVVWWTTTUUTTWWVVVVQQPPPPPPPPPQQQQQQVVWWTTTUUTWWWVVVVVVVVVVVQQQQQVVVVVVWWWWTUUTTWWWWWVVVVVQQQQQQPPPQVVVVWWWWWWTTUUUTWVVQQPPQVQQQPPPPPPPQQQVVVWWWWTTTTUTVQPPPPSSPPPSSSSSSSSSSSSPPPQVVWTUUUTTTTWTTTUUUUTTWWTTTWWVVWWVVWWTWWWWTTTTTTTTTTTTTUUUWTTUTTTTTUTUWQTQVWVTUWTVWWWVRVTWQTUWWTUTUUUUUUUTTUUUTUQUQUWVTWQWTVWWWQWVTTUUPPUUUWWWWTUTTUTUTUWTUUTWUUTVTWVUQUUTTWVUUTTWWVTWWUTUUTUUTUTWTWTWTUTUTUWUWUUWTVTUUTTTUUUTUVUTRQTVVVUTTUUUTTUWPVUWUWPWTUWWTTVWWWQTVSWQUWTWQUWWWUQTVVWVVTTUTWTUQTWTUUUTVUUTUVWTQUWVUVUWWWTVTUTTVTTPUUWQVUWTTUTWUUTUUUUWTUUTWUTUTWWWTUTTUUVWTUWUTTTTTTTWUWUUWUTWWTTTTUTUUUTWTTUUUTTUWWUUTTUUUTTUUUTVPPSR\_\\\\___\]]]]RRSPQQWTREFFFAAD^SVVQVTTQSSQQSR]PVWTTUWQPR\^Y^]SQVTTGM@CLLC^UPRSSS]_RVUWVVVVPPQQQR\^^^\\RQVUXHtuJJHARPY[Y___\STUVPSSPPPPQWWVS_XZZX^]SV[IILOOMEWURXX_RRRRWWQSPQQPR]__^ZCIHBYQUDw}svuLZTQ^G@G[_RPUTWQR]RPWTTQS]\_YZE[\PVTUWVW@tJNIIL[VXFE^]]\RVSSQWUWWTTUVS\YECNIA_WRt~rqtL\U^AILFX_RWTQ]_\PTVS]_YXY\\_^_STUTVWTTTU]w}vuuJN\RALA[^^^PTR\]SQVPVTQSR_XDAFDXRQAr|pqpqNV[OOAEEEYTP\_RPQQVUVQR_[EDEE[^PTH}}pssq@VGOMFFAF^P\\]]]]PUUWQS_[DGFGZ_QURwrqqpswYPFCAA@BA\WR\\^^Y_SWUTWP\XEDGGE^SWFqsqr|rKQ]DGGCOLDPVPR^YY]VUTP\^XEFD[]QWRtpwq}}vXV[DD@OHMYVUVPR^[ZX]PVTTTQR_YEGDX\PWGtuup}sOWP^YZ@LMDSTUP^YX_SPVWTP_[ZZ[^_SV]JtuqrrtY]_XFMLA^PWV\^Y^]RSVTTV]X[[Y_\PTMtuwsrqAUS\^DBOBZ]PWW]^Y^\]RQWWS\^_^Y_RVUUBtHuqpwFU]__ZACF^QVUUV]^^^]RRQVTVR__\\\_RVTUSMNLJvwN\TSR\ZGG[RQVUQ\\]RSSQWWQR\]R]\\SWUW@NLHwwHXUTPS]YEEXRQQTV]\\RSSPWTP]]RSR]SWU^DEFLOCYVTTWPSS\YX^RVVWUVP]^XZZX_SPQT]EDDCM@XQTWTTPSRS]^^_]PPPWUTTUWP_XXXXXX_SQQQVTUTWWTUS^^XEEXRWWTUUTWWQQVVWWWTWPPQS]_]PVVVTT]YYX[X^SVWWTUTVQPPR]]SPPPPPPPSSPPPPQQVWWTWQPR\_\RRR]RSRR]RRR]\\]]]RSQVWTTTUUUVPSRR]]]]]]\]]]]]]]]RRSSPQPQQVWWTUUUTWVVVVVVVVVVQQVQQQVWTTTTUUTTTTWVVVVWVVWTUUUUTTTWWTTTUUUUUUUUUUUUUUUUUUUUUTTTTTTUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUTTTTTTTTTUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTUUUUUUTTTTTTTUUUUUUUUUTTTTTTTTTTUUUUUUUUUUUUUUUUUUTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUTWWVQQQVVVWWWWWTTTTTUUUUUUUUUUUUUUUUUUUUUTTTTTTWTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUTUUUUUUUUTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTWWWTTTTTTUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTWWWTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTUUUUUUUUUUUUUUUUUTTTTWWWWWTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTUUTUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUTUUUTUUUUUUUUUUUUTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWVVWWWTTUTTTTTTTWWWWTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUTUUUUUUUUUTUUUUUTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTUUUUUUUUUUUUUUUUUUUTUUUUTWWWWWTTTTTUUUUUUUUUUUUUUUUUTTTUUUUUUUTTTTTTTTTUUUUUUUUUTUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWVVWWWWTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUTUUUTUUUUUUUUUUUUUTTTWWWTTTTTTTTUUUUUUUUUUUUUTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWWWWTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWWWVVVVVVVVVVVQVVWWWWWWWWWWWTTTTTTTUUUUTTUUUUUTTTTTTTTTTWWWWWWTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWWTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTUTTTTTUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWVVVVWWWWWTTTTUUUUUUUUUUUUUUUUUUUUUTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTWWWWWTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUTWWWVVVVWWTTTTTTTTTUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWWWWWTTTTTUUUUUUUUUUUUUUUUUUUUUUUUTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTWWVVVQQQQQQQQQQQVQVVVVVVVVWWWVVVVWWVVVVVVVVVVVVVWWTTTTUUUUUUUUUUUUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTWWTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTUUUUUUUUTTWWWWWWTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTUUUUUUUUUUUUUUUTTWWWWWWTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTUTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU \ No newline at end of file diff --git a/test/support_test/video.h264 b/test/support_test/video.h264 new file mode 100755 index 00000000..db50cf10 Binary files /dev/null and b/test/support_test/video.h264 differ diff --git a/test/utils/Config/CMakeLists.txt b/test/utils/Config/CMakeLists.txt index 643cf259..08fb3f86 100644 --- a/test/utils/Config/CMakeLists.txt +++ b/test/utils/Config/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories( link_directories( ${LIBS_OUTPUT_PATH} ${EXTERNAL_LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib ) aux_source_directory(. SRC_FILES) diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index b24fc139..04cdd65e 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -12,7 +12,7 @@ add_subdirectory(McuProtocol) add_subdirectory(ModBusCRC16) add_subdirectory(LedControl) add_subdirectory(KeyControl) -add_subdirectory(MediaAdapter) +add_subdirectory(MediaBase) add_subdirectory(FxHttpServer) add_subdirectory(Servers) add_subdirectory(TcpModule) diff --git a/utils/ConfigBase/CMakeLists.txt b/utils/ConfigBase/CMakeLists.txt index 8fb72427..40703219 100644 --- a/utils/ConfigBase/CMakeLists.txt +++ b/utils/ConfigBase/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories( ./include ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/Log/include - ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib + ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/include ) # link_directories( # ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs @@ -19,7 +19,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME ConfigBase) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} StatusCode Log libconfig.a) +target_link_libraries(${TARGET_NAME} StatusCode Log config) if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") add_custom_target( @@ -57,20 +57,29 @@ add_custom_command( endif() # build libconfig before make libConfigBase.a +# add_custom_command( +# OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a +# COMMAND echo "Build libconfig-1.7.3. COMPILE_HOST = ${COMPILE_HOST}" +# COMMAND sh build_libconfig.sh ${TARGET_PLATFORM} ${COMPILE_HOST} +# COMMAND mv ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a +# COMMAND cd libconfig-1.7.3; make clean; +# WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/ +# ) +# add_custom_target( +# libconfig.a +# DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a +# ) add_custom_command( - # OUTPUT ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a - OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a - COMMAND echo "Build libconfig-1.7.3. COMPILE_HOST = ${COMPILE_HOST}" - # COMMAND tar zxvf libconfig-1.7.3.tar.gz - COMMAND sh build_libconfig.sh ${TARGET_PLATFORM} ${COMPILE_HOST} - COMMAND mv ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a - WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/ + OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib/libconfig.a + COMMAND echo "Did not libconfig libs in output_files, now compile libconfig." + COMMAND make libconfig + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ ) add_custom_target( - libconfig.a - # DEPENDS ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a - DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a + compile_libconfig + DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig/lib/libconfig.a ) +add_dependencies(${TARGET_NAME} compile_libconfig) define_file_name(${TARGET_NAME}) config_owner(${TARGET_NAME}) diff --git a/utils/ConfigBase/src/ConfigBase.cpp b/utils/ConfigBase/src/ConfigBase.cpp index 4c1e54ad..e9a16365 100644 --- a/utils/ConfigBase/src/ConfigBase.cpp +++ b/utils/ConfigBase/src/ConfigBase.cpp @@ -15,6 +15,9 @@ #include "ConfigBase.h" #include "IConfigBase.h" #include "ILog.h" +#include "StatusCode.h" +#include +#include static bool ObjectCheck(void *object) { if (nullptr == object) { diff --git a/utils/ConfigBase/src/ConfigBaseCode.c b/utils/ConfigBase/src/ConfigBaseCode.c index c6dac5a5..3eca51ae 100644 --- a/utils/ConfigBase/src/ConfigBaseCode.c +++ b/utils/ConfigBase/src/ConfigBaseCode.c @@ -13,7 +13,9 @@ * limitations under the License. */ #include "ConfigBaseCode.h" +#include "ConfigBase.h" #include "ILog.h" +#include "StatusCode.h" #include static const char *ConfigCodeString[CONFIG_CODE_END - STATUS_CODE_END + 1] = {"CONFIG_CODE_PARAM_NOT_EXIST", "CONFIG_CODE_END"}; diff --git a/utils/ConfigBase/src/ConfigBaseImpl.cpp b/utils/ConfigBase/src/ConfigBaseImpl.cpp index 4fe9e294..09fdffd3 100644 --- a/utils/ConfigBase/src/ConfigBaseImpl.cpp +++ b/utils/ConfigBase/src/ConfigBaseImpl.cpp @@ -13,10 +13,16 @@ * limitations under the License. */ #include "ConfigBaseImpl.h" +#include "ConfigBase.h" #include "ConfigBaseCode.h" #include "ILog.h" +#include "StatusCode.h" +#include #include #include +#include +#include +#include #include constexpr int INVALID_RESULT = -1; @@ -38,7 +44,8 @@ bool ConfigBaseImpl::OpenConfigFile(void) if (FIEL_EXIST == access(mFileName.c_str(), F_OK)) { 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(&mCfg), config_error_line(&mCfg), config_error_text(&mCfg)); + fprintf( + stderr, "%s:%d - %s\n", config_error_file(&mCfg), config_error_line(&mCfg), config_error_text(&mCfg)); return false; } } diff --git a/utils/ConfigBase/src/IConfigBase.cpp b/utils/ConfigBase/src/IConfigBase.cpp index 55086fba..de94df75 100644 --- a/utils/ConfigBase/src/IConfigBase.cpp +++ b/utils/ConfigBase/src/IConfigBase.cpp @@ -15,7 +15,10 @@ #include "IConfigBase.h" #include "ConfigBaseImpl.h" #include "ILog.h" +#include "StatusCode.h" #include +#include +#include bool IConfigBase::OpenConfigFile(void) { return false; diff --git a/utils/KeyControl/src/KeyControl.cpp b/utils/KeyControl/src/KeyControl.cpp index 01ab7e09..7573194a 100644 --- a/utils/KeyControl/src/KeyControl.cpp +++ b/utils/KeyControl/src/KeyControl.cpp @@ -14,6 +14,8 @@ */ #include "KeyControl.h" #include "ILog.h" +#include +#include constexpr long int KEY_PRESSING = 0; constexpr unsigned int NOT_A_HOLD_KEY_ACTION = 0; KeyControl::KeyControl() @@ -30,14 +32,17 @@ bool KeyControl::IsKeyPressing(void) } const std::string VKeyControl::GetKeyName(void) { + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return "undefine"; } unsigned int VKeyControl::GetStatusCheckPeriodMs(void) { + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return 0; } void VKeyControl::KeyEventTrigger(const std::string &keyName, const KeyEvent &event, const unsigned int &timeMs) { + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); } void KeyControl::Init(void) { diff --git a/utils/LedControl/src/LedControl.cpp b/utils/LedControl/src/LedControl.cpp index 3191ae7c..d4e8fa4a 100644 --- a/utils/LedControl/src/LedControl.cpp +++ b/utils/LedControl/src/LedControl.cpp @@ -14,7 +14,10 @@ */ #include "LedControl.h" #include "ILog.h" +#include "StatusCode.h" #include +#include +#include StatusCode VSingleControl::GetLedState(LedState &state) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); diff --git a/utils/LinuxApi/include/LinuxApi.h b/utils/LinuxApi/include/LinuxApi.h index 96f4568b..ceef5461 100644 --- a/utils/LinuxApi/include/LinuxApi.h +++ b/utils/LinuxApi/include/LinuxApi.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/utils/LinuxApi/src/LinuxApi.c b/utils/LinuxApi/src/LinuxApi.c index 754cf9c5..7fd4b4cd 100644 --- a/utils/LinuxApi/src/LinuxApi.c +++ b/utils/LinuxApi/src/LinuxApi.c @@ -13,11 +13,13 @@ * limitations under the License. */ #include "LinuxApi.h" -#include #include +#include #include #include +#include #include +#include #include #include #include diff --git a/utils/Log/src/Log.cpp b/utils/Log/src/Log.cpp index 0bc7938c..40ac0778 100644 --- a/utils/Log/src/Log.cpp +++ b/utils/Log/src/Log.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. @@ -13,21 +13,21 @@ * limitations under the License. */ #include "Log.h" +#include "ILog.h" #include "ILogCpp.h" #include #include -#include -#include +#include #include static void LogFree(ILog *object) { printf("log instance free.\n"); - if (object) - { + if (object) { free(object); } } -static int LogPrintf(ILog *object, const char *function, const int line, const enum LogType type, const char *format, ...) +static int LogPrintf(ILog *object, const char *function, const int line, const enum LogType type, const char *format, + ...) { // TODO: // LogTypeToString(type); @@ -40,8 +40,7 @@ static int LogPrintf(ILog *object, const char *function, const int line, const e va_start(vargs, format); int len = vsnprintf(buff + headLen, SEND_TRACE_BUFF_SIZE - headLen, format, vargs); va_end(vargs); - switch (type) - { + switch (type) { case LOG_TYPE_INFORMATION: ILogCpp::GetInstance()->InFo(buff); break; @@ -75,16 +74,13 @@ static void LogImplInit(Log *log) } void NewLog(Log **log) { - if (!log) - { + if (!log) { printf("STATUS_CODE_INVALID_PARAMENTER\n"); return; } - if (!(*log)) - { + if (!(*log)) { *log = (Log *)malloc(sizeof(Log)); - if (*log) - { + if (*log) { printf("NewLog succeed.\n"); NewILog((ILog **)log); LogImplInit(*log); diff --git a/utils/McuProtocol/src/LittleEndianHandle.cpp b/utils/McuProtocol/src/LittleEndianHandle.cpp index d6e848e0..f6d0691c 100644 --- a/utils/McuProtocol/src/LittleEndianHandle.cpp +++ b/utils/McuProtocol/src/LittleEndianHandle.cpp @@ -13,8 +13,9 @@ * limitations under the License. */ #include "LittleEndianHandle.h" -#include "ILog.h" #include "ModBusCRC16.h" +#include "ProtocolHandle.h" +#include #include #include LittleEndianHandle::LittleEndianHandle(const std::shared_ptr ¶m) : ProtocolHandle(param) diff --git a/utils/McuProtocol/src/McuProtocol.cpp b/utils/McuProtocol/src/McuProtocol.cpp index 55d6539a..481c96ee 100644 --- a/utils/McuProtocol/src/McuProtocol.cpp +++ b/utils/McuProtocol/src/McuProtocol.cpp @@ -15,7 +15,14 @@ #include "McuProtocol.h" #include "ILog.h" #include "ProtocolHandle.h" +#include "StatusCode.h" +#include +#include +#include +#include +#include #include +#include std::shared_ptr VProtocolBase::SharedFromThis(void) { return std::make_shared(); diff --git a/utils/McuProtocol/src/McuProtocolMakePtr.cpp b/utils/McuProtocol/src/McuProtocolMakePtr.cpp index a1c7625c..84506116 100644 --- a/utils/McuProtocol/src/McuProtocolMakePtr.cpp +++ b/utils/McuProtocol/src/McuProtocolMakePtr.cpp @@ -15,7 +15,10 @@ #include "McuProtocolMakePtr.h" #include "ILog.h" #include "LittleEndianHandle.h" -#include +#include "ProtocolHandle.h" +#include "StatusCode.h" +#include +#include std::shared_ptr &McuProtocolMakePtr::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/utils/McuProtocol/src/ProtocolHandle.cpp b/utils/McuProtocol/src/ProtocolHandle.cpp index ea453b48..bec0c575 100644 --- a/utils/McuProtocol/src/ProtocolHandle.cpp +++ b/utils/McuProtocol/src/ProtocolHandle.cpp @@ -17,7 +17,14 @@ #include "McuProtocol.h" #include "McuProtocolMakePtr.h" #include "ModBusCRC16.h" +#include "StatusCode.h" +#include +#include +#include +#include #include +#include +#include #include using std::placeholders::_1; // using std::placeholders::_2; diff --git a/utils/MediaAdapter/CMakeLists.txt b/utils/MediaAdapter/CMakeLists.txt index 48c919bd..02285eab 100644 --- a/utils/MediaAdapter/CMakeLists.txt +++ b/utils/MediaAdapter/CMakeLists.txt @@ -14,8 +14,6 @@ include_directories( # ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs # ) - - aux_source_directory(./src SRC_FILES) set(TARGET_NAME MediaAdapter) diff --git a/utils/MediaBase/CMakeLists.txt b/utils/MediaBase/CMakeLists.txt new file mode 100644 index 00000000..7c1e51d8 --- /dev/null +++ b/utils/MediaBase/CMakeLists.txt @@ -0,0 +1,68 @@ +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./src + ./include + # ${UTILS_SOURCE_PATH}/LinuxApi/include + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/ModBusCRC16/include + ${UTILS_SOURCE_PATH}/Log/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +aux_source_directory(./src SRC_FILES) + +set(TARGET_NAME MediaBase) +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} StatusCode Log) + +if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") +add_custom_target( + MediaBase_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/MediaBase +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + MediaBase_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/MediaBase +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make MediaBase_code_check + COMMAND make MediaBase_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +# build ffmpeg before make libMediaBase.a +add_custom_command( + OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg/lib/libavcodec.a + COMMAND echo "Did not found ffmpeg libs in output_files, now compile ffmpeg." + COMMAND make ffmpeg + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +add_custom_target( + compile_ffmpeg + DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg/lib/libavcodec.a +) +add_dependencies(${TARGET_NAME} compile_ffmpeg) + +define_file_name(${TARGET_NAME}) + +file(GLOB_RECURSE INSTALL_HEADER_FILES include/*.h) +install(FILES ${INSTALL_HEADER_FILES} DESTINATION include) \ No newline at end of file diff --git a/utils/MediaBase/include/MediaBase.h b/utils/MediaBase/include/MediaBase.h new file mode 100644 index 00000000..a5df302f --- /dev/null +++ b/utils/MediaBase/include/MediaBase.h @@ -0,0 +1,31 @@ +/* + * 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 MEDIA_BASE_H +#define MEDIA_BASE_H +#include "StatusCode.h" +#ifdef __cplusplus +extern "C" { +#endif +enum MediaHandleType +{ + MEDIA_HANDLE_TYPE_READ_H264 = 0, + MEDIA_HANDLE_TYPE_END +}; +void *ICreateMediaBase(const MediaHandleType type); +void IMediaBaseFree(void *object); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/utils/MediaBase/src/IMediaBase.cpp b/utils/MediaBase/src/IMediaBase.cpp new file mode 100644 index 00000000..5a36544d --- /dev/null +++ b/utils/MediaBase/src/IMediaBase.cpp @@ -0,0 +1,32 @@ +/* + * 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 "IMediaBase.h" +#include "ILog.h" +#include +static const char *MEDIA_BASE_NAME = "media_adapter"; +const char inline *GetMediaBaseModuleName(void) +{ + return MEDIA_BASE_NAME; +} +std::shared_ptr *NewIMediaBase(const MediaHandleType &type) +{ + LogInfo("Create the midia base object.\n"); + MeidaAdapter *impl = (MeidaAdapter *)malloc(sizeof(MeidaAdapter)); + MeidaAdapter tmp; + memcpy((void *)impl, (void *)&tmp, sizeof(MeidaAdapter)); + impl->mHeader.mCheckName = MEDIA_BASE_NAME; + impl->mIMediaBase = std::make_shared(); + return (std::shared_ptr *)(((char *)impl) + sizeof(MediaBaseHeader)); +} \ No newline at end of file diff --git a/utils/MediaBase/src/IMediaBase.h b/utils/MediaBase/src/IMediaBase.h new file mode 100644 index 00000000..092899eb --- /dev/null +++ b/utils/MediaBase/src/IMediaBase.h @@ -0,0 +1,36 @@ +/* + * 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 I_MEDIA_BASE_H +#define I_MEDIA_BASE_H +#include "MediaBase.h" +#include +class IMediaBase +{ +public: + IMediaBase() = default; + virtual ~IMediaBase() = default; +}; +typedef struct media_base_header +{ + const char *mCheckName; +} MediaBaseHeader; +typedef struct media_adapter +{ + MediaBaseHeader mHeader; + std::shared_ptr mIMediaBase; +} MeidaAdapter; +const char *GetMediaBaseModuleName(void); +std::shared_ptr *NewIMediaBase(const MediaHandleType &type); +#endif \ No newline at end of file diff --git a/utils/MediaBase/src/MediaBase.cpp b/utils/MediaBase/src/MediaBase.cpp new file mode 100644 index 00000000..9d41dc08 --- /dev/null +++ b/utils/MediaBase/src/MediaBase.cpp @@ -0,0 +1,40 @@ +/* + * 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 "MediaBase.h" +#include "ILog.h" +#include "IMediaBase.h" +void *ICreateMediaBase(const MediaHandleType type) +{ + return NewIMediaBase(type); +} +static bool ObjectCheck(void *object) +{ + if (nullptr == object) { + LogError("nullptr object!\n"); + return false; + } + if (*((const char **)(((char *)object) - sizeof(IMediaBase))) != GetMediaBaseModuleName()) { + LogError("Illegal object!\n"); + return false; + } + return true; +} +void IMediaBaseFree(void *object) +{ + if (ObjectCheck(object) == true) { + (*(std::shared_ptr *)object).reset(); + free(((char *)object) - sizeof(MediaBaseHeader)); + } +} \ No newline at end of file diff --git a/utils/MediaBase/src/MediaBaseImpl.cpp b/utils/MediaBase/src/MediaBaseImpl.cpp new file mode 100644 index 00000000..632636a8 --- /dev/null +++ b/utils/MediaBase/src/MediaBaseImpl.cpp @@ -0,0 +1,15 @@ +/* + * 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 "MediaBaseImpl.h" \ No newline at end of file diff --git a/utils/MediaBase/src/MediaBaseImpl.h b/utils/MediaBase/src/MediaBaseImpl.h new file mode 100644 index 00000000..39d2598a --- /dev/null +++ b/utils/MediaBase/src/MediaBaseImpl.h @@ -0,0 +1,24 @@ +/* + * 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 MEDIA_BASE_IMPL_H +#define MEDIA_BASE_IMPL_H +#include "IMediaBase.h" +class MediaBaseImpl : public IMediaBase +{ +public: + MediaBaseImpl() = default; + virtual ~MediaBaseImpl() = default; +}; +#endif \ No newline at end of file diff --git a/utils/Servers/src/curl_serve.c b/utils/Servers/src/curl_serve.c index 92ae9750..12b6bb63 100644 --- a/utils/Servers/src/curl_serve.c +++ b/utils/Servers/src/curl_serve.c @@ -13,6 +13,10 @@ * limitations under the License. */ #include "curl_serve.h" +#include "servers.h" +#include +#include +#include static ServerParam gCurlServe; void SetVerboseLog(LogFlag flag) { diff --git a/utils/Servers/src/ftp_servers.c b/utils/Servers/src/ftp_servers.c index fd5f43a0..5dcb54b5 100644 --- a/utils/Servers/src/ftp_servers.c +++ b/utils/Servers/src/ftp_servers.c @@ -15,11 +15,13 @@ #include "ftp_servers.h" #include "ILog.h" #include "curl_serve.h" +#include "servers.h" #include +#include +#include +#include #include #include -#include -#include struct FtpFile { const char *filename; diff --git a/utils/Servers/src/http_servers.c b/utils/Servers/src/http_servers.c index 99e88b50..fb1bd2c9 100644 --- a/utils/Servers/src/http_servers.c +++ b/utils/Servers/src/http_servers.c @@ -15,12 +15,15 @@ #include "http_servers.h" #include "ILog.h" #include "curl_serve.h" +#include "servers.h" #include +#include +#include +#include +#include #include #include #include -#include -#include static size_t write_cb(char *data, size_t n, size_t l, void *userp) { diff --git a/utils/Servers/src/smtp_servers.c b/utils/Servers/src/smtp_servers.c index 5052812f..6287bdec 100644 --- a/utils/Servers/src/smtp_servers.c +++ b/utils/Servers/src/smtp_servers.c @@ -15,7 +15,9 @@ #include "smtp_servers.h" #include "ILog.h" #include "curl_serve.h" +#include "servers.h" #include +#include #include #include #include diff --git a/utils/SharedData/src/ISharedData.cpp b/utils/SharedData/src/ISharedData.cpp index d5c18d32..0534b345 100644 --- a/utils/SharedData/src/ISharedData.cpp +++ b/utils/SharedData/src/ISharedData.cpp @@ -14,7 +14,11 @@ */ #include "ISharedData.h" #include "ILog.h" +#include "SharedData.h" #include "SharedDataImpl.h" // TODO: 互相包含,需要修改 +#include "StatusCode.h" +#include +#include #include void ISharedData::MakeSharedMemory(const unsigned int readableSize, const unsigned int writableSize) { diff --git a/utils/SharedData/src/SharedData.cpp b/utils/SharedData/src/SharedData.cpp index 211f204a..cc3d235e 100644 --- a/utils/SharedData/src/SharedData.cpp +++ b/utils/SharedData/src/SharedData.cpp @@ -15,6 +15,9 @@ #include "SharedData.h" #include "ILog.h" #include "ISharedData.h" +#include "StatusCode.h" +#include +#include static bool ObjectCheck(void *object) { if (nullptr == object) { diff --git a/utils/SharedData/src/SharedDataCode.c b/utils/SharedData/src/SharedDataCode.c index ea96da87..47b5be2a 100644 --- a/utils/SharedData/src/SharedDataCode.c +++ b/utils/SharedData/src/SharedDataCode.c @@ -14,6 +14,8 @@ */ #include "SharedDataCode.h" #include "ILog.h" +#include "SharedData.h" +#include "StatusCode.h" #include static const char *StatusCodeString[SHARED_DATA_CODE_END - STATUS_CODE_END + 1] = { "SHARED_DATA_CODE_INIT_FAILED", "SHARED_DATA_CODE_WRONG_PEER_PARAMETERS", "SHARED_DATA_CODE_END"}; diff --git a/utils/SharedData/src/SharedDataImpl.cpp b/utils/SharedData/src/SharedDataImpl.cpp index a3dbdaba..91227fbe 100644 --- a/utils/SharedData/src/SharedDataImpl.cpp +++ b/utils/SharedData/src/SharedDataImpl.cpp @@ -14,9 +14,11 @@ */ #include "SharedDataImpl.h" #include "ILog.h" +#include "SharedData.h" #include "SharedDataCode.h" +#include "SharedMemory.h" +#include "StatusCode.h" #include -static const char *SHARED_DATA_NAME = "shared_data"; constexpr short THERE_TWO_USER_DATA_HEADER = 2; SharedDataImpl::SharedDataImpl(const SHARER_NAME &sharerName, const char *path, const int &projectId) : SharedMemory(path, projectId), mSharerName(sharerName) diff --git a/utils/SharedData/src/SharedMemory.cpp b/utils/SharedData/src/SharedMemory.cpp index 0f18784f..d2295f59 100644 --- a/utils/SharedData/src/SharedMemory.cpp +++ b/utils/SharedData/src/SharedMemory.cpp @@ -15,13 +15,16 @@ #include "SharedMemory.h" #include "ILog.h" #include "LinuxApi.h" +#include "SharedData.h" #include "SharedDataCode.h" +#include "StatusCode.h" #include #include #include #include #include #include +#include #include constexpr int SHMGET_FAILED = -1; SharedMemory::SharedMemory(const char *path, const int &projectId) : mPath(path), mProjectId(projectId) diff --git a/utils/StatusCode/src/StatusCode.c b/utils/StatusCode/src/StatusCode.c index fa86750d..8cd7343c 100644 --- a/utils/StatusCode/src/StatusCode.c +++ b/utils/StatusCode/src/StatusCode.c @@ -14,7 +14,6 @@ */ #include "StatusCode.h" #include "ILog.h" -#include #include static const char *StatusCodeString[STATUS_CODE_END + 1] = {"STATUS_CODE_OK", "STATUS_CODE_NOT_OK", diff --git a/utils/TcpModule/src/ITcpClient.cpp b/utils/TcpModule/src/ITcpClient.cpp index 256ab402..397155e0 100644 --- a/utils/TcpModule/src/ITcpClient.cpp +++ b/utils/TcpModule/src/ITcpClient.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ #include "ITcpClient.h" -#include "ILog.h" #include "TcpModule.h" #include +#include void ITcpClient::Init(void) { } diff --git a/utils/TcpModule/src/ITcpServer.cpp b/utils/TcpModule/src/ITcpServer.cpp index a26c05c7..f34e78e1 100644 --- a/utils/TcpModule/src/ITcpServer.cpp +++ b/utils/TcpModule/src/ITcpServer.cpp @@ -16,6 +16,7 @@ #include "ILog.h" #include "TcpModule.h" #include +#include void ITcpClientAccept::Close(void) { } diff --git a/utils/TcpModule/src/TcpClientImpl.cpp b/utils/TcpModule/src/TcpClientImpl.cpp index 5d76d64e..346ed616 100644 --- a/utils/TcpModule/src/TcpClientImpl.cpp +++ b/utils/TcpModule/src/TcpClientImpl.cpp @@ -14,7 +14,15 @@ */ #include "TcpClientImpl.h" #include "ILog.h" +#include "ITcpClient.h" +#include "TcpModule.h" +#include "hloop.h" +#include #include +#include +#include +#include +#include static void on_message(hio_t *io, void *buf, int len) { LogInfo("onmessage: %.*s\n", len, (char *)buf); diff --git a/utils/TcpModule/src/TcpModule.cpp b/utils/TcpModule/src/TcpModule.cpp index 1cfa9dff..59fd681c 100644 --- a/utils/TcpModule/src/TcpModule.cpp +++ b/utils/TcpModule/src/TcpModule.cpp @@ -14,10 +14,13 @@ */ #include "TcpModule.h" #include "ILog.h" +#include "ITcpClient.h" #include "ITcpServer.h" -#include "TcpClientImpl.h" -#include "TcpModuleImpl.h" #include "TcpModuleMakePtr.h" +#include +#include +#include +#include static bool TcpServerObjectCheck(void *object) { if (nullptr == object) { diff --git a/utils/TcpModule/src/TcpModuleImpl.cpp b/utils/TcpModule/src/TcpModuleImpl.cpp index 08e20a87..6501855a 100644 --- a/utils/TcpModule/src/TcpModuleImpl.cpp +++ b/utils/TcpModule/src/TcpModuleImpl.cpp @@ -12,29 +12,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "TcpModuleImpl.h" -#include "ILog.h" -#include -// static const char *TCP_MODULE_NAME = "tcp_module"; -// const char *GetTcpModuleName(void) -// { -// return TCP_MODULE_NAME; -// } -// void *NewTcpModuleImpl(const TcpClientParam &tcpParam) -// { -// if (nullptr == tcpParam.mIp) { -// LogError("Parament error, nullptr == tcpParam.mIp\n"); -// return nullptr; -// } -// LogInfo("Create the tcp module object.\n"); -// TcpServer *impl = (TcpServer *)malloc(sizeof(TcpServer)); -// TcpServer tmp; -// memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer)); -// impl->mHeader.mCheckName = TCP_MODULE_NAME; -// impl->mTcpImpl = std::make_shared(tcpParam); -// return (void *)(((char *)impl) + sizeof(TcpModuleHeader)); -// } -// void *NewTcpServer(const TcpClientParam &tcpParam) -// { -// return nullptr; -// } \ No newline at end of file +// #include "TcpModuleImpl.h" \ No newline at end of file diff --git a/utils/TcpModule/src/TcpModuleImpl.h b/utils/TcpModule/src/TcpModuleImpl.h index 3320ea42..b8530544 100644 --- a/utils/TcpModule/src/TcpModuleImpl.h +++ b/utils/TcpModule/src/TcpModuleImpl.h @@ -14,39 +14,5 @@ */ #ifndef TCP_MODULE_IMPL_H #define TCP_MODULE_IMPL_H -#include "StatusCode.h" -#include "TcpModule.h" #include -// #define TCP_MODULE_INIT_NAME "UART" -// typedef struct tcp_module_header -// { -// const char *mCheckName; -// } TcpModuleHeader; -// class TcpModuleImpl -// { -// public: -// TcpModuleImpl(const TcpClientParam &uatrInfo); -// virtual ~TcpModuleImpl() = default; - -// private: -// const StatusCode SetConfig(void); - -// private: -// const TcpClientParam mUatrInfo; -// int mFd; -// }; -// TODO: There may be a CPU byte alignment bug. -// typedef struct tcp_server TcpServer; -// typedef struct tcp_server -// { -// TcpModuleHeader mHeader; -// std::shared_ptr mTcpImpl; -// } TcpServer; -// void *NewTcpModuleImpl(const TcpClientParam &tcpParam); -// void *NewTcpServer(const TcpClientParam &tcpParam); -// static inline TcpServer *TcpModuleImplConvert(void *object) -// { -// return ((TcpServer *)(((char *)object) - sizeof(TcpModuleHeader))); -// } -// const char *GetTcpModuleName(void); #endif \ No newline at end of file diff --git a/utils/TcpModule/src/TcpModuleMakePtr.cpp b/utils/TcpModule/src/TcpModuleMakePtr.cpp index 975d350f..235f4bee 100644 --- a/utils/TcpModule/src/TcpModuleMakePtr.cpp +++ b/utils/TcpModule/src/TcpModuleMakePtr.cpp @@ -13,9 +13,12 @@ * limitations under the License. */ #include "TcpModuleMakePtr.h" -#include "ILog.h" +#include "ITcpClient.h" +#include "ITcpServer.h" #include "TcpClientImpl.h" +#include "TcpModule.h" #include "TcpServerImpl.h" +#include std::shared_ptr &TcpModuleMakePtr::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/utils/TcpModule/src/TcpServerHandle.cpp b/utils/TcpModule/src/TcpServerHandle.cpp index 3006dc0f..3928fbae 100644 --- a/utils/TcpModule/src/TcpServerHandle.cpp +++ b/utils/TcpModule/src/TcpServerHandle.cpp @@ -14,6 +14,8 @@ */ #include "TcpServerHandle.h" #include "ILog.h" +#include "ITcpServer.h" +#include std::shared_ptr &TcpServerHandle::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/utils/TcpModule/src/TcpServerImpl.cpp b/utils/TcpModule/src/TcpServerImpl.cpp index 231a1c26..7455c03d 100644 --- a/utils/TcpModule/src/TcpServerImpl.cpp +++ b/utils/TcpModule/src/TcpServerImpl.cpp @@ -14,7 +14,16 @@ */ #include "TcpServerImpl.h" #include "ILog.h" -#include "TcpServerHandle.h" +#include "ITcpServer.h" +#include "TcpModule.h" +#include "hloop.h" +#include "hsocket.h" +#include +#include +#include +#include +#include +#include static void on_close(hio_t *io) { LogInfo("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io)); @@ -172,10 +181,8 @@ std::shared_ptr *TcpServerImpl::GetClient(hio_t *io) if (it != mClients.end()) { return it->second; } - else { - LogError("GetClient failed, client not exit.\n"); - return nullptr; - } + LogError("GetClient failed, client not exit.\n"); + return nullptr; } void TcpServerImpl::RemoveClient(hio_t *io) { diff --git a/utils/UartDevice/src/UartDevice.cpp b/utils/UartDevice/src/UartDevice.cpp index dae12799..44a4c3b2 100644 --- a/utils/UartDevice/src/UartDevice.cpp +++ b/utils/UartDevice/src/UartDevice.cpp @@ -16,6 +16,9 @@ #include "ILog.h" #include "StatusCode.h" #include "UartDeviceImpl.h" +#include +// #include + void *CreateUartDevice(const UartInfo info) { return NewUartDeviceImpl(info); diff --git a/utils/UartDevice/src/UartDeviceImpl.cpp b/utils/UartDevice/src/UartDeviceImpl.cpp index 419ccbdd..62f8b7c4 100644 --- a/utils/UartDevice/src/UartDeviceImpl.cpp +++ b/utils/UartDevice/src/UartDeviceImpl.cpp @@ -15,15 +15,21 @@ #include "UartDeviceImpl.h" #include "ILog.h" #include "LinuxApi.h" +#include "StatusCode.h" +#include "UartDevice.h" +#include +#include #include #include -#include #include +#include #include -#include +#include +// #include #include #include #include + constexpr int INVALID_FD = -1; static const char *UART_DEVICE_NAME = "uart_device"; const char *GetUartDeviceModuleName(void) diff --git a/utils/UpgradeBase/src/UpgradeBase.cpp b/utils/UpgradeBase/src/UpgradeBase.cpp index d79b2289..ec4b5f38 100644 --- a/utils/UpgradeBase/src/UpgradeBase.cpp +++ b/utils/UpgradeBase/src/UpgradeBase.cpp @@ -14,7 +14,7 @@ */ #include "UpgradeBase.h" #include "ILog.h" -#include "LinuxApi.h" +#include "StatusCode.h" #include #include #include diff --git a/utils/UpgradeTool/src/UpgradeTool.cpp b/utils/UpgradeTool/src/UpgradeTool.cpp index d84e188a..fb5bcbe4 100644 --- a/utils/UpgradeTool/src/UpgradeTool.cpp +++ b/utils/UpgradeTool/src/UpgradeTool.cpp @@ -18,14 +18,15 @@ #include "UpgradeBase.h" #include #include +#include #include -#include #include #include #include #include +#include #include -#include + std::shared_ptr &UpgradeTool::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); diff --git a/utils/WebServer/src/WebServer.cpp b/utils/WebServer/src/WebServer.cpp index d1cfdcc7..e20b982f 100644 --- a/utils/WebServer/src/WebServer.cpp +++ b/utils/WebServer/src/WebServer.cpp @@ -14,9 +14,16 @@ */ #include "WebServer.h" #include "ILog.h" +#include "StatusCode.h" #include "goahead.h" -#include "js.h" +#include "osdep.h" +#include #include +#include +#include +#include +#include + static int finished = 0; static HttpHandleCallback gHttpHandle = NULL; constexpr int UNKNOWN_LENGTH = -1;