From: xue <2144439972@qq.com> Date: Wed, 20 Aug 2025 08:46:28 +0000 (+0800) Subject: 优化wroksync流程 X-Git-Url: http://git.snicker.com.cn/css/static/gitweb.css?a=commitdiff_plain;h=9f377e6cb3a1fc64fae63c8f5f9de070d4b46c23;p=mirrors%2FFD230.git 优化wroksync流程 --- diff --git a/code/sdk/application/brandy/brandy_standard/service_init.c b/code/sdk/application/brandy/brandy_standard/service_init.c index 1330e45a9..ff910b0e0 100755 --- a/code/sdk/application/brandy/brandy_standard/service_init.c +++ b/code/sdk/application/brandy/brandy_standard/service_init.c @@ -75,6 +75,10 @@ #ifdef TCP_MANAGER_ENABLED #include "tcp_manager_at_cmd.h" #endif + +#ifdef SUPPORT_AT_WORK +#include "worksync_at_cmd.h" +#endif #ifdef SUPPORT_AT_BP #include "bp_at_cmd.h" #endif @@ -187,6 +191,12 @@ static void register_at_service(void) at_cmd_table_t *bp_table = get_bp_cmd_table(&bp_cmd_count); at_cmd_add_moudle(bp_table, bp_cmd_count); #endif + +#ifdef SUPPORT_AT_WORK + uint32_t worksync_cmd_count; + at_cmd_table_t *worksync_table = get_worksync_cmd_table(&worksync_cmd_count); + at_cmd_add_moudle(worksync_table, worksync_cmd_count); +#endif } #ifdef CONFIG_OTA_UPDATE_SUPPORT diff --git a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c index 6d38c3059..aad3fdffb 100755 --- a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c +++ b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c @@ -130,6 +130,10 @@ extern int tcp_manager_test_init(void); #include "bp_tcp_server.h" #endif +#ifdef ENABLE_WORK +#include "worksync_tcp_server.h" +#endif + #ifdef ENABLE_GYRO #include "gyro_service.h" #endif @@ -543,6 +547,10 @@ uapi_pm_remove_sleep_veto(PM_ID_DEBUG); uapi_bp_service_init(); uapi_bp_tcp_server_init(); #endif + + #ifdef ENABLE_WORK + uapi_worksync_tcp_server_init(); + #endif #endif #ifdef ENABLE_GYRO diff --git a/code/sdk/application/wearable/fd230app/CMakeLists.txt b/code/sdk/application/wearable/fd230app/CMakeLists.txt index 7852f4cd9..4fd2a7094 100644 --- a/code/sdk/application/wearable/fd230app/CMakeLists.txt +++ b/code/sdk/application/wearable/fd230app/CMakeLists.txt @@ -294,6 +294,24 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/unconnected/src/UnconnectedView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/unconnected/src/UnconnectedPresenter.cpp + #中移物联 + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/ChinaMobilelIOTView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/ChinaMobilelIOTPresenter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/ChinaMobilelIOTModel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/ChinaMobilelIOTFirstView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/DeviceBindingView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/FieldCheckinView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/PersonalInformationView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/WorkTaskView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/WorkTaskAdapter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/WorkTaskSettingItemView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/WorkTaskContentView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/chinamobilelIOT/src/FieldCheckinResultView.cpp + + #雷鸟 + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/thunderbird/src/ThunderBirdView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/thunderbird/src/ThunderBirdPresenter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bluetooth/src/BluetoothDeviceCaseListAdapter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bluetooth/src/BluetoothDeviceListView.cpp diff --git a/code/sdk/application/wearable/fd230app/nativelauncher/include/AppViewIDs.h b/code/sdk/application/wearable/fd230app/nativelauncher/include/AppViewIDs.h index 1d32f719c..bc5699b41 100644 --- a/code/sdk/application/wearable/fd230app/nativelauncher/include/AppViewIDs.h +++ b/code/sdk/application/wearable/fd230app/nativelauncher/include/AppViewIDs.h @@ -109,6 +109,8 @@ typedef enum : uint16_t VIEW_CANVAS_TEST, //中移物联 VIEW_CHINA_MOBILEL_IOT, + //雷鸟 + VIEW_THUNDER_BIRD, /* -------------------------------------------------------------------------- */ /* ----------------------------------- 训练 ----------------------------------- */ VIEW_TRAINING, // 训练 diff --git a/code/sdk/application/wearable/fd230app/nativelauncher/include/NativeLauncher.h b/code/sdk/application/wearable/fd230app/nativelauncher/include/NativeLauncher.h index 53fb1ad9e..0190fa511 100644 --- a/code/sdk/application/wearable/fd230app/nativelauncher/include/NativeLauncher.h +++ b/code/sdk/application/wearable/fd230app/nativelauncher/include/NativeLauncher.h @@ -79,6 +79,7 @@ namespace OHOS void InitFatigueLevelSlice(void); void InitUnconnectedSlice(void); void InitChinamobileIOTSlice(void); + void InitThunderBirdSlice(void); void InitCheckAbnormalSlice(void); void InitCheckInvalidSlice(void); void InitHeartResultSlice(void); diff --git a/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp b/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp index 3aefbb1ed..2bfe381f0 100644 --- a/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp +++ b/code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp @@ -127,6 +127,9 @@ /*未连接*/ #include "unconnected/include/UnconnectedPresenter.h" #include "unconnected/include/UnconnectedView.h" +/*雷鸟*/ +#include "thunderbird/include/ThunderBirdPresenter.h" +#include "thunderbird/include/ThunderBirdView.h" /*心率监测*/ #include "heartrate/include/HeartDetectionView.h" #include "heartrate/include/HeartDetectionPresenter.h" @@ -516,6 +519,8 @@ namespace OHOS {VIEW_CANVAS_TEST, &NativeLauncher::InitCanvasTestSlice}, /*中移物联*/ {VIEW_CHINA_MOBILEL_IOT, &NativeLauncher::InitChinamobileIOTSlice}, + /*雷鸟*/ + {VIEW_THUNDER_BIRD, &NativeLauncher::InitThunderBirdSlice}, /* -------------------------------------------------------------------------- */ /*智能助手*/ {VIEW_OFFLINEVOICE, &NativeLauncher::InitOfflineVoice}, @@ -1449,6 +1454,18 @@ namespace OHOS return; } NativeAbility::GetInstance().AddSliceProxy(VIEW_UNCONNECTED, unconnectedView); + } + // 雷鸟界面 + void NativeLauncher::InitThunderBirdSlice(void) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NativeLauncher::InitUnconnectedSlice"); + SliceProxy *thunderbirdView = new AbilitySliceProxy; + if (thunderbirdView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderbirdView is nullptr"); + return; + } + NativeAbility::GetInstance().AddSliceProxy(VIEW_THUNDER_BIRD, thunderbirdView); } // 心率监测界面 void NativeLauncher::InitHeartCheckSlice(void) diff --git a/code/sdk/application/wearable/fd230app/nativeui/applist/include/ApplistConfigModel.h b/code/sdk/application/wearable/fd230app/nativeui/applist/include/ApplistConfigModel.h index 874713cfe..5e5200ed6 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/applist/include/ApplistConfigModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/applist/include/ApplistConfigModel.h @@ -52,8 +52,9 @@ namespace OHOS {VIEW_MAIN_ALIPAY, PNG_APPLIST_ALIPAY_IMAGE_BIG, PNG_APPLIST_ALIPAY_IMAGE, PNG_APPLIST_DEFAULT_IMG, "支付宝", STR_ALIPAY, nullptr, "Z", "ALIPAY"}, #endif #if defined(CM_IOT) - {VIEW_CHINA_MOBILEL_IOT, PNG_APPLIST_CHINAMOBIELIOT_IMAGE_BIG, PNG_APPLIST_WORKWYNC_IMAGE, PNG_APPLIST_DEFAULT_IMG, "中移物联", STR_AI_FAMILY_MEALS, nullptr, "C", "China_Mobilel_IOT"}, + {VIEW_CHINA_MOBILEL_IOT, PNG_APPLIST_CHINAMOBIELIOT_IMAGE_BIG, PNG_APPLIST_WORKWYNC_IMAGE, PNG_APPLIST_DEFAULT_IMG, "中移物联", STR_WORKSYNC, nullptr, "C", "China_Mobilel_IOT"}, #endif + {VIEW_THUNDER_BIRD, PNG_APPLIST_MESSAGE_IMAGE_BIG, PNG_APPLIST_MESSAGE_IMAGE, PNG_APPLIST_DEFAULT_IMG, "雷鸟", STR_MESSAGE_NOTIFICATION, nullptr, "T", "THUNDERBIRD"}, {VIEW_MESSAGE, PNG_APPLIST_MESSAGE_IMAGE_BIG, PNG_APPLIST_MESSAGE_IMAGE, PNG_APPLIST_DEFAULT_IMG, "消息通知", STR_MESSAGE_NOTIFICATION, nullptr, "X", "MESSAGE_NOTIFICATION"}, {VIEW_COMPASS, PNG_APPLIST_COMPASS_IMAGE_BIG, PNG_APPLIST_COMPASS_IMAGE, PNG_APPLIST_DEFAULT_IMG, "指南针", STR_COMPASS, nullptr, "Z", "COMPASS"}, {VIEW_CALCULATOR, PNG_APPLIST_INFORMATION_IMAGE_BIG, PNG_APPLIST_INFORMATION_IMAGE, PNG_APPLIST_DEFAULT_IMG, "计算器", STR_CALCULATOR, nullptr, "J", "CALCULATOR"}, diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTFirstView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTFirstView.h new file mode 100644 index 000000000..19f302c9f --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTFirstView.h @@ -0,0 +1,41 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef CHINA_MOBILE_IOT_FIRST_VIEW_H +#define CHINA_MOBILE_IOT_FIRST_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +namespace OHOS +{ + static constexpr char * DEVICEBINDING = "devicebinding"; + static constexpr char * FIELDCHECKIN = "fielcheckin"; + static constexpr char * PERSONALINFORMATION = "personalinformation"; + static constexpr char * WORKTASK = "worktask"; + class ChinaMobilelIOTFirstView + { + + public: + ChinaMobilelIOTFirstView(); + ~ChinaMobilelIOTFirstView(); + static ChinaMobilelIOTFirstView *GetInstance(); + void InitImage(UIImageView *Image,const char *path,uint16_t x,uint16_t y,const char *id); + bool Initbackground(); + UIViewGroup * ChinaMobilelIOTFirstViewInit(); + void DeInit(); + + private: + UIViewGroup *group{nullptr}; + UIImageView *icon_1{nullptr}; + UIImageView *icon_2{nullptr}; + UIImageView *icon_3{nullptr}; + UIImageView *icon_4{nullptr}; + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTModel.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTModel.h new file mode 100644 index 000000000..0ad26cb03 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTModel.h @@ -0,0 +1,86 @@ +#ifndef CHINA_MOBILE_IOT_MODEL_H +#define CHINA_MOBILE_IOT_MODEL_H + +#include +#include +#include +#include +#include +#include "map" +#include "TaskItem.h" +#ifdef ENABLE_WORK +#include "worksync_tcp_server.h" +#endif +namespace OHOS +{ + struct DeviceBinding + { + // 用户名 + std::string userName; + // 品牌 + std::string brand; + // 型号 + std::string model; + // 标识码 + std::string identificationCode; + // 设备ID + std::string deviceId; + }; + struct PersonalInfo + { + // 姓名 + std::string name; + // 单位 + std::string unit; + // 部门 + std::string department; + // 手机号 + std::string phone; + // 注册时间 + std::string registerTime; + }; + + + class ChinaMobilelIOTModel + { + static const uint16_t SETTING_ITEM_COUNT = 10; + + public: + ChinaMobilelIOTModel(); + ~ChinaMobilelIOTModel(); + static ChinaMobilelIOTModel *GetInstance(); + std::string GetCurrentTimeStr(); + bool IsBindingInformation(); // 是否绑定 + bool IsCheckin(); // 是否打卡成功 + DeviceBinding GetBindingInformation(); // 获取绑定信息 + PersonalInfo GetPersonalInfo(); // 获取个人信息 + void InitTaskItem(); + uint8_t GetTaskListNum() const; + const TaskItem *GetTaskItems() const; + const char *GetAdress(); + int GetState(); + void Setlabel(const char *); // 任务详情界面标题 + const char *Getlabel(); + void Setcontent(const char *); // 任务详情界面内容 + const char *Getcontent(); + void Setcurrentview(int16_t); // 任务详情界面内容 + const int16_t Getcurrentview(); + void timer_callback_proc(); + void StopTimer(void); + void StartTimer(uint32_t interval = 1 * 1000); + #ifdef ENABLE_WORK + worksync_data_t worksync_resev_data = {0}; + #endif + + private: + TaskItem settings[SETTING_ITEM_COUNT] = {0, nullptr, nullptr, false}; + int usedLen; + bool btConnectStatus{false}; + const char *label; + const char *content; + int16_t currentview = 0; + int state; //状态 + }; + +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTModelC.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTModelC.h new file mode 100644 index 000000000..d5bdfc765 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTModelC.h @@ -0,0 +1,29 @@ +#ifndef CHINAMOBILEIOTC_H +#define CHINAMOBILEIOTC_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" +{ +#endif +#endif +#ifdef ENABLE_WORK +#include "worksync_tcp_server.h" +#endif +enum DataIndex { + DATA_OXYGEN = 0, // 0: 血氧 + DATA_HEART_RATE, // 1: 心率 + DATA_STEPS, // 2: 步数 + DATA_CALORIE, // 3: 卡路里 + DATA_MAX // 总数(用于边界检查) +}; + +void SetReproData(enum DataIndex Code, const char* Value); +const char *GetReproDataValue(enum DataIndex Code); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTPresenter.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTPresenter.h new file mode 100644 index 000000000..760443bca --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTPresenter.h @@ -0,0 +1,43 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:08 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-04-16 16:08:41 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTPresenter.h + */ + +#ifndef CHINA_MOBILE_IOT_PRESENTER_H +#define CHINA_MOBILE_IOT_PRESENTER_H + +#include "Presenter.h" +#include "View.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" + +namespace OHOS +{ + class ChinaMobilelIOTView; + class ChinaMobilelIOTPresenter : public Presenter, + public UIView::OnClickListener, + public RootView::OnKeyActListener, + public UIView::OnDragListener + { + public: + ChinaMobilelIOTPresenter(); + virtual ~ChinaMobilelIOTPresenter(); + + void OnStart() override; + void OnPause() override; + void OnResume() override; + void OnStop() override; + + static ChinaMobilelIOTPresenter *GetInstance(); + + private: + bool OnClick(UIView &view, const ClickEvent &event) override; + bool OnDrag(UIView &view, const DragEvent &event) override; + bool OnDragEnd(UIView &view, const DragEvent &event) override; + bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件 + }; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTView.h new file mode 100644 index 000000000..9c6fddb52 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/ChinaMobilelIOTView.h @@ -0,0 +1,67 @@ +#ifndef CHINA_MOBILEL_IOT_VIEW_H +#define CHINA_MOBILEL_IOT_VIEW_H + +#include "View.h" +#include "BaseView.h" +#include "components/ui_view_group.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTFirstView.h" +#include "chinamobilelIOT/include/DeviceBindingView.h" +#include "chinamobilelIOT/include/FieldCheckinView.h" +#include "chinamobilelIOT/include/FieldCheckinResultView.h" +#include "chinamobilelIOT/include/PersonalInformationView.h" +#include "chinamobilelIOT/include/WorkTaskView.h" +#include "chinamobilelIOT/include/WorkTaskContentView.h" + +namespace OHOS +{ + typedef enum : uint8_t + { + CHINAMOBILEIOTFIRSTVIEW = 0, // 首界面 + DEVICEBINDINGVIEW, // 设备绑定界面 + FIELDCHECKINVIEW, // 外勤打卡界面 + FIELDCHECKINRESULITVIEW, //打卡结果界面 + PERSONALINFORMATIONBVIEW, // 个人信息界面 + WORKTASKVIW, // 工作任务界面 + WORKTASKCENTENTVIEW, //任务详情界面 + MAX_VIEW, + } VIEWID; + + class ChinaMobilelIOTPresenter; + class ChinaMobilelIOTView : public View + { + public: + ChinaMobilelIOTView(); + virtual ~ChinaMobilelIOTView(); + static ChinaMobilelIOTView *GetInstance(void); + void OnStop() override; + void OnSetUpView() override; + void OnTearDownView() override; + void OnStart() override; + + bool ChangeChinaMobilelIOTFirstView(int16_t); + bool ChangeDeviceBindingView(int16_t); + bool ChangeFieldCheckinView(int16_t); + bool ChangeFieldCheckinResultView(int16_t); + bool ChangePersonalInformationView(int16_t); + bool ChangeWorkTaskView(int16_t); + bool ChangeWorkTaskContentView(int16_t); + + bool ClickFunc(int16_t interface); + void ChangeView(int16_t hideView, int16_t showView); + + private: + ChinaMobilelIOTFirstView *g_pChinaMobilelIOTFirstView{nullptr}; + DeviceBindingView *g_pDeviceBindingView{nullptr}; + FieldCheckinView *g_pFieldCheckinView{nullptr}; + PersonalInformationView *g_pPersonalInformationView{nullptr}; + WorkTaskView *g_pWorkTaskView{nullptr}; + WorkTaskContentView *g_pWorkTaskContentView{nullptr}; + FieldCheckinResultView *g_pFieldCheckinResultView{nullptr}; + + private: + void DeInit(); + UIViewGroup *group[MAX_VIEW]{nullptr}; + }; +} + +#endif // 血压主界面 \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/DeviceBindingView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/DeviceBindingView.h new file mode 100644 index 000000000..faa416bf4 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/DeviceBindingView.h @@ -0,0 +1,48 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef DEVICE_BINDING_VIEW_H +#define DEVICE_BINDING_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label_ext.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTModel.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/PersonalInformationView.h" +namespace OHOS +{ + class DeviceBindingView + { + + public: + DeviceBindingView(); + ~DeviceBindingView(); + static DeviceBindingView *GetInstance(); + UIViewGroup *DeviceBindingInit(); + void DeInit(); + bool Initunbinding(); + bool Initbindinged(); + + private: + UIViewGroup *group{nullptr}; + UIImageView *remind{nullptr}; + UILabelExt *bindinged{nullptr}; + UILabelExt *unbinding{nullptr}; + UILabelExt *Name{nullptr}; + UILabelExt *Brand{nullptr}; + UILabelExt *Model{nullptr}; + UILabelExt *SerialNumber{nullptr}; + UILabelExt *DeviceID{nullptr}; + bool IsBinding = false; + DeviceBinding data = {}; + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/FieldCheckinResultView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/FieldCheckinResultView.h new file mode 100644 index 000000000..2dd775152 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/FieldCheckinResultView.h @@ -0,0 +1,35 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef FIELD_CHECK_IN_RESULT_VIEW_H +#define FIELD_CHECK_IN_RESULT_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label_ext.h" +namespace OHOS +{ + class FieldCheckinResultView + { + + public: + FieldCheckinResultView(); + ~FieldCheckinResultView(); + static FieldCheckinResultView *GetInstance(); + UIViewGroup * FieldCheckinResultInit(); + void DeInit(); + + private: + UIViewGroup *group{nullptr}; + UIImageView *icon{nullptr}; + UILabelExt *result{nullptr}; + + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/FieldCheckinView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/FieldCheckinView.h new file mode 100644 index 000000000..478c42020 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/FieldCheckinView.h @@ -0,0 +1,45 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef FIELD_CHECK_IN_VIEW_H +#define FIELD_CHECK_IN_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label_ext.h" +#include "components/ui_label_button_ext.h" +namespace OHOS +{ + static constexpr char *CHEKINBUTTON = "checkinButton"; // 打卡按钮 + static constexpr char *REFRESHIMAGE = "refreshImage"; // 刷新 + class FieldCheckinView + { + + public: + FieldCheckinView(); + ~FieldCheckinView(); + static FieldCheckinView *GetInstance(); + void locationInit(); + UIViewGroup * FieldCheckinInit(); + void DeInit(); + void UpdateTimeText(const char *time); + + private: + UIViewGroup *group{nullptr}; + UILabelExt *address{nullptr}; + UILabelExt *timeLabel{nullptr}; + UILabelButtonExt *checkButton{nullptr}; + UIImageView *refresh{nullptr}; + UIImageView *circle1{nullptr}; + UIImageView *circle2{nullptr}; + UIImageView *circle3{nullptr}; + UIImageView *location{nullptr}; + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/PersonalInformationView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/PersonalInformationView.h new file mode 100644 index 000000000..0675c6376 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/PersonalInformationView.h @@ -0,0 +1,46 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef PERSONAL_INFORMATION_VIEW_H +#define PERSONAL_INFORMATION_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label_ext.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/PersonalInformationView.h" +namespace OHOS +{ + class PersonalInformationView + { + + public: + PersonalInformationView(); + ~PersonalInformationView(); + static PersonalInformationView *GetInstance(); + bool Initbackground(); + UIViewGroup *PersonalInformationInit(); + + void DeInit(); + + + private: + UIViewGroup *group{nullptr}; + UILabelExt *personalinformation{nullptr}; + UILabelExt *Name{nullptr}; + UILabelExt *unit{nullptr}; + UILabelExt *department{nullptr}; + UILabelExt *phone{nullptr}; + UILabelExt *registerTime{nullptr}; + PersonalInfo data = {}; + + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/TaskItem.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/TaskItem.h new file mode 100644 index 000000000..efc761cd3 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/TaskItem.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: TaskItem.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef WORK_TASK_ITEM_H +#define WORK_TASK_ITEM_H + +#include + +namespace OHOS { +typedef struct { + uint8_t id; + const char *label; + const char *content; + bool hasSecondMenu; +} TaskItem; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskAdapter.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskAdapter.h new file mode 100644 index 000000000..53491ce63 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskAdapter.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: WorkTaskAdapter.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef WORK_TASK_ADAPTER_H +#define WORK_TASK_ADAPTER_H + +#include +#include +#include "components/ui_list.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" +#include "components/abstract_adapter.h" +#include "wearable_log.h" +#include "UiConfig.h" +#include "WorkTaskSettingItemView.h" +#include "TaskItem.h" + +namespace OHOS { +class WorkTaskAdapter : public AbstractAdapter { +public: + explicit WorkTaskAdapter(); + ~WorkTaskAdapter() override; + + /* * + * @brief Sets the UIView adapter data, which is a TaskItem linked list. + * + * @param data Indicates the TaskItem linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(std::list &data); + + /* * + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCount(void) override; + + UIView *GetView(UIView *inView, int16_t index) override; + + void AddListItem(const TaskItem &item); + + void SetItemClickListener(UIView::OnClickListener *itemclicklistener) + { + itemClickListener = itemclicklistener; + } +private: + std::list listData; + UIView::OnClickListener *itemClickListener{nullptr}; +}; +} + +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskContentView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskContentView.h new file mode 100644 index 000000000..14d0d9770 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskContentView.h @@ -0,0 +1,35 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef WORK_TASK_CONTENT_VIEW_H +#define WORK_TASK_CONTENT_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label_ext.h" +namespace OHOS +{ + class WorkTaskContentView + { + + public: + WorkTaskContentView(); + ~WorkTaskContentView(); + static WorkTaskContentView *GetInstance(); + UIViewGroup * WorkTaskContentInit(); + void UpdateContent(); + void DeInit(); + + private: + UIViewGroup *group{nullptr}; + UILabelExt *title{nullptr}; + UILabelExt *content{nullptr}; + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskSettingItemView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskSettingItemView.h new file mode 100644 index 000000000..3c91359b6 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskSettingItemView.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: WorkTaskSettingItemView.h + * Author: + * Create: 2021-11-23 + */ + +#ifndef WORK_TASK_ITEM_VIEW_H +#define WORK_TASK_ITEM_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "components/ui_image_view.h" + +#include "UiConfig.h" +#include "WorkTaskAdapter.h" +#include "TaskItem.h" + +namespace OHOS { +class WorkTaskSettingItemView : public UIViewGroup { +public: + explicit WorkTaskSettingItemView(); + ~WorkTaskSettingItemView() override; + virtual void SetItemInfo(const TaskItem itemInfo); + virtual void SetUpChild(); + uint8_t GetTaskId(); + const char * GetTasklabel(); + const char * GetTaskcontent(); +private: + UIImageView sIcon; + UILabel sLabel; + UIImageView sNextImage; + TaskItem sItemInfo = {0,nullptr,nullptr, false }; +}; +} + +#endif diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskView.h b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskView.h new file mode 100644 index 000000000..03cf2cc90 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/include/WorkTaskView.h @@ -0,0 +1,44 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:37:15 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:30:17 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/include/ChinaMobilelIOTView.h + */ +#ifndef WORK_TASK_VIEW_H +#define WORK_TASK_VIEW_H + +#include "BaseView.h" +#include "View.h" +#include "components/ui_scroll_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label_ext.h" +#include "WorkTaskAdapter.h" + +#include "components/ui_list.h" +namespace OHOS +{ + class WorkTaskView + { + + public: + WorkTaskView(); + ~WorkTaskView(); + static WorkTaskView *GetInstance(); + UIViewGroup *WorkTaskInit(); + void AddWorkTaskItemToList(const TaskItem &item); + bool WorkTask(); + bool UnWorkTask(); + void DeInit(); + + private: + UIViewGroup *group{nullptr}; + WorkTaskAdapter *listAdapter{nullptr}; + UIScrollView *scrollView{nullptr}; + UIList *contentList{nullptr}; + UIView::OnDragListener *dragListener{nullptr}; + UIImageView *task{nullptr}; + UILabelExt *notask{nullptr}; + }; +} +#endif \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTFirstView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTFirstView.cpp index d4b12c8a4..920ee658d 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTFirstView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTFirstView.cpp @@ -42,6 +42,26 @@ namespace OHOS delete group; group = nullptr; } + if (icon_1 != nullptr) + { + delete icon_1; + icon_1 = nullptr; + } + if (icon_2 != nullptr) + { + delete icon_2; + icon_2 = nullptr; + } + if (icon_3 != nullptr) + { + delete icon_3; + icon_3 = nullptr; + } + if (icon_4 != nullptr) + { + delete icon_4; + icon_4 = nullptr; + } } void ChinaMobilelIOTFirstView::InitImage(UIImageView *Image,const char *path,uint16_t x,uint16_t y,const char *id) @@ -66,8 +86,8 @@ namespace OHOS bool ChinaMobilelIOTFirstView::Initbackground() { InitImage(icon_1,BINDPATH,59,97,DEVICEBINDING); - InitImage(icon_2,CHECKINPATH,243,97,FIELDCHECKIN); - InitImage(icon_3,PERSONALPATH,243,241,PERSONALINFORMATION); + InitImage(icon_3,PERSONALPATH,243,97,PERSONALINFORMATION); + InitImage(icon_2,CHECKINPATH,59,241,FIELDCHECKIN); InitImage(icon_4,TASKPATH,243,241,WORKTASK); return true; } diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTModel.cpp new file mode 100644 index 000000000..a41c3e797 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTModel.cpp @@ -0,0 +1,338 @@ +#include +#include "chinamobilelIOT/include/ChinaMobilelIOTModel.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTModelC.h" +#include "chinamobilelIOT/include/FieldCheckinView.h" +#include "wearable_log.h" +#include "custom_utils.h" +#include +#include +static char code[12]; // 数据标识 +static char Oxy_value[40]; // 血氧数据值 +static char heart_value[40]; // 心率数据值 +static char steps_value[40]; // 步数数据值 +static char calorie_value[40]; // 卡路里数据值 + +#ifdef __cplusplus +extern "C"{ +#endif + +// 设置数据值,根据不同的DataIndex存储到对应的数组 +void SetReproData(enum DataIndex Code, const char* Value) +{ + // 对所有数据类型进行处理 + switch (Code) + { + case DATA_OXYGEN: + memset(Oxy_value, 0, sizeof(Oxy_value)); + if (Value != nullptr) + { + // 注意:使用sizeof(Oxy_value)作为目标缓冲区大小,而非sizeof(Value) + strncpy(Oxy_value, Value, sizeof(Oxy_value) - 1); + } + break; + + case DATA_HEART_RATE: + memset(heart_value, 0, sizeof(heart_value)); + if (Value != nullptr) + { + strncpy(heart_value, Value, sizeof(heart_value) - 1); + } + break; + + case DATA_STEPS: + memset(steps_value, 0, sizeof(steps_value)); + if (Value != nullptr) + { + strncpy(steps_value, Value, sizeof(steps_value) - 1); + } + break; + + case DATA_CALORIE: + memset(calorie_value, 0, sizeof(calorie_value)); + if (Value != nullptr) + { + strncpy(calorie_value, Value, sizeof(calorie_value) - 1); + } + break; + + default: + // 处理无效索引 + break; + } + printf("value:%s",Value); +} + + +// 根据DataIndex返回对应的数据值 +const char *GetReproDataValue(enum DataIndex Code) +{ + switch (Code) + { + case DATA_OXYGEN: + return Oxy_value; + case DATA_HEART_RATE: + return heart_value; + case DATA_STEPS: + return steps_value; + case DATA_CALORIE: + return calorie_value; + default: + // 无效索引返回空指针或特定标识 + return ""; + } +} + +#ifdef __cplusplus +} +#endif +namespace OHOS +{ + + ChinaMobilelIOTModel::ChinaMobilelIOTModel() {} + ChinaMobilelIOTModel::~ChinaMobilelIOTModel() {} + ChinaMobilelIOTModel *ChinaMobilelIOTModel::GetInstance(void) + { + static ChinaMobilelIOTModel instance; + return &instance; + } + // 获取当前时间戳字符串 + std::string ChinaMobilelIOTModel::GetCurrentTimeStr() + { + uint32_t timeStamp = 0; + if (uapi_get_timestampe_ss(&timeStamp) != ERRCODE_SUCC) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp"); + return "----/--/-- \n --/--"; + } + // 将时间戳转换为 time_t 类型 + time_t rawtime = static_cast(timeStamp); + struct tm *timeinfo = localtime(&rawtime); + + if (timeinfo == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to convert time"); + return "----/--/-- \n --/--"; + } + + // 格式化时间为字符串 (HH:MM:SS format) + char buffer[20]; // 格式: HH:MM:SS + std::strftime(buffer, sizeof(buffer), "%H:%M:%S", timeinfo); + return std::string(buffer); + } + + bool ChinaMobilelIOTModel::IsBindingInformation() // 是否绑定 + { + #ifdef ENABLE_WORK + worksync_get_worksync_data(&worksync_resev_data); + if (worksync_resev_data.isBind == 1) + return true; + else + #endif + return false; + } + bool ChinaMobilelIOTModel::IsCheckin() // 是否打卡成功 + { + return true; + } + + DeviceBinding ChinaMobilelIOTModel::GetBindingInformation() // 获取绑定信息 + { + DeviceBinding deviceInfo; + #ifdef ENABLE_WORK + worksync_get_worksync_data(&worksync_resev_data); + + if (worksync_resev_data.isBind == 1) // 绑定 + { + deviceInfo.userName = worksync_resev_data.userName; + deviceInfo.brand = "海思鸿蒙手表"; + deviceInfo.model = "WATCH FIT 2"; + deviceInfo.identificationCode = "蓝牙连接"; + deviceInfo.deviceId = worksync_resev_data.deviceId; + } + #endif + return deviceInfo; + } + + PersonalInfo ChinaMobilelIOTModel::GetPersonalInfo() // 获取个人信息 + { + PersonalInfo info; + #ifdef ENABLE_WORK + worksync_get_worksync_data(&worksync_resev_data); + if (worksync_resev_data.isBind == 1) // 绑定 + { + info.name = worksync_resev_data.userName; + info.unit = worksync_resev_data.unitName; + info.department = worksync_resev_data.orgName; + info.phone = worksync_resev_data.telNo; + info.registerTime = worksync_resev_data.registerTime; + } + #endif + return info; + + } + + void ChinaMobilelIOTModel::InitTaskItem() + { + #ifdef ENABLE_WORK + worksync_get_worksync_data(&worksync_resev_data); + int index = 0; + for (index; index < worksync_resev_data.count; index++) + { + settings[index] = {index + 1, worksync_resev_data.task[index].title, worksync_resev_data.task[index].content, true}; + } + usedLen = index; + #endif + } + + const TaskItem *ChinaMobilelIOTModel::GetTaskItems() const + { + return settings; + } + + int ChinaMobilelIOTModel::GetState() // 是否打卡成功 + { + state = 0; + #ifdef ENABLE_WORK + worksync_get_worksync_data(&worksync_resev_data); + state = worksync_resev_data.state; + #endif + return state; + } + + const char *ChinaMobilelIOTModel::GetAdress() + { + #ifdef ENABLE_WORK + worksync_get_worksync_data(&worksync_resev_data); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "worksync_resev_data.address:%s", worksync_resev_data.address); + + return worksync_resev_data.address; + #else + return ""; + #endif + + } + + + uint8_t ChinaMobilelIOTModel::GetTaskListNum() const + { + return usedLen; + } + + void ChinaMobilelIOTModel::Setlabel(const char *lab) // 任务详情界面的初始化 + { + label = lab; + } + const char *ChinaMobilelIOTModel::Getlabel() + { + return label; + } + void ChinaMobilelIOTModel::Setcontent(const char *cont) + { + content = cont; + } + const char *ChinaMobilelIOTModel::Getcontent() + { + return content; + } + void ChinaMobilelIOTModel::Setcurrentview(int16_t View) // 当前界面,用返回主界面 + { + currentview = View; + } + const int16_t ChinaMobilelIOTModel::Getcurrentview() + { + return currentview; + } + + void ChinaMobilelIOTModel::timer_callback_proc() + { + FieldCheckinView *view = FieldCheckinView::GetInstance(); + if (view) + { + view->UpdateTimeText(GetCurrentTimeStr().c_str()); + } + } + + static osTimerId_t g_timer = nullptr; + /*定时器到期时的处理*/ + static void TimerCallbackProc(uint8_t data) + { + // 倒计时 + ChinaMobilelIOTModel::GetInstance()->timer_callback_proc(); + } + /* + * @brief 回调函数 + */ + static void TimerCallback(uint8_t data) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TimerCallback %d", data); + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(TimerCallbackProc, data)); + } + + /* + * @brief 开启定时器函数 + * @param interval 时间间隔,单位ms + */ + void ChinaMobilelIOTModel::StartTimer(uint32_t interval) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTModel::StartTimer"); + /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 + * ------------------------- */ + if (g_timer != nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!"); + return; + } + + /* --------------------------------- 2.创建定时器 + * -------------------------------- */ + g_timer = osTimerNew((osTimerFunc_t)TimerCallback, osTimerPeriodic, + nullptr, nullptr); + // 检查定时器创建是否成功 + if (g_timer == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!"); + return; + } + + /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 + * ---------------------------- */ + /* --------------------------------- 4.启动定时器 + * -------------------------------- */ + osStatus_t ret = osTimerStart(g_timer, interval); + /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 + * nullptr -------------------- */ + if (ret != osOK) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "osTimerDelete failed, ret = %lx!!", ret); + if (g_timer != nullptr) + { + ret = osTimerDelete(g_timer); + } + g_timer = nullptr; + return; + } + } + /* + * @brief 停止定时器 + */ + void ChinaMobilelIOTModel::StopTimer(void) + { + // 检查定时器是否存在 + if (g_timer != nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTModel::BP_StopTimer"); + osTimerStop(g_timer); + // 删除定时器并置为 nullptr + osStatus_t ret = osTimerDelete(g_timer); + if (ret != osOK) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "osTimerDelete failed, ret = %lx!!", ret); + } + g_timer = nullptr; + } + } + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTPresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTPresenter.cpp new file mode 100644 index 000000000..e89ab2e08 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTPresenter.cpp @@ -0,0 +1,191 @@ +/* + * @Author: luozheng 1732036298@qq.com + * @Date: 2024-04-16 14:36:45 + * @LastEditors: luozheng 1732036298@qq.com + * @LastEditTime: 2024-06-18 15:19:37 + * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/ChinaMobilelIOT/src/ChinaMobilelIOTPresenter.cpp + */ +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTModel.h" +#include "chinamobilelIOT/include/WorkTaskView.h" +#include "AppViewIDs.h" +#include "NativeAbility.h" +#include "common/key_code.h" +#include "map" +#include +namespace OHOS +{ + + // 当前Presenter属性实例化的内存指针 + static ChinaMobilelIOTPresenter *g_pChinaMobilelIOTPresenter = nullptr; + + ChinaMobilelIOTPresenter::ChinaMobilelIOTPresenter() + { + g_pChinaMobilelIOTPresenter = this; + } + + ChinaMobilelIOTPresenter::~ChinaMobilelIOTPresenter() + { + g_pChinaMobilelIOTPresenter = nullptr; + } + + ChinaMobilelIOTPresenter *ChinaMobilelIOTPresenter::GetInstance() + { + return g_pChinaMobilelIOTPresenter; + } + + void ChinaMobilelIOTPresenter::OnStart() + { + Presenter::OnStart(); + } + + void ChinaMobilelIOTPresenter::OnPause(void) + { + Presenter::OnPause(); + } + + void ChinaMobilelIOTPresenter::OnResume(void) + { + Presenter::OnResume(); + } + + void ChinaMobilelIOTPresenter::OnStop(void) + { + Presenter::OnStop(); + } + + bool ChinaMobilelIOTPresenter::OnClick(UIView &view, const ClickEvent &event) + { + WorkTaskSettingItemView *ItemView = static_cast(&view); + const TaskItem *itemInfo = ChinaMobilelIOTModel::GetInstance()->GetTaskItems(); + + std::string viewId = view.GetViewId(); + + std::map> viewIdMap = { + {DEVICEBINDING, {CHINAMOBILEIOTFIRSTVIEW, DEVICEBINDINGVIEW}}, // 首界面到设备绑定界面 + {FIELDCHECKIN, {CHINAMOBILEIOTFIRSTVIEW, FIELDCHECKINVIEW}}, // 首界面到外勤打卡界面 + {PERSONALINFORMATION, {CHINAMOBILEIOTFIRSTVIEW, PERSONALINFORMATIONBVIEW}}, // 首界面到个人信息界面 + {WORKTASK, {CHINAMOBILEIOTFIRSTVIEW, WORKTASKVIW}}, // 首界面到工作任务界面 + //{CHEKINBUTTON, {FIELDCHECKINVIEW, FIELDCHECKINRESULITVIEW}}, // 打卡界面到打卡结果界面 + + }; + auto it = viewIdMap.find(viewId); + if (it != viewIdMap.end()) + { + ChinaMobilelIOTView::GetInstance()->ChangeView(it->second.first, it->second.second); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(it->second.second); // 当前界面,用返回主界面 + + return true; + } + else if (strcmp(view.GetViewId(), CHEKINBUTTON) == 0) // 打卡界面到打卡结果界面 + { +#ifdef ENABLE_WORK + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_CHECK_IN, NULL, 0); + usleep(50000); +#endif + ChinaMobilelIOTView::GetInstance()->ChangeView(FIELDCHECKINVIEW, FIELDCHECKINRESULITVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(FIELDCHECKINRESULITVIEW); + } + else if (strcmp(view.GetViewId(), REFRESHIMAGE) == 0) // 点击打卡刷新界面 + { +#ifdef ENABLE_WORK + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_GEOLOCATION, NULL, 0); + usleep(50000); +#endif + ChinaMobilelIOTView::GetInstance()->ChangeView(FIELDCHECKINVIEW, FIELDCHECKINVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(FIELDCHECKINVIEW); + } + else if (ItemView->GetTaskId() != 0 && WorkTaskView::GetInstance()) // 工作任务界面到任务详情界面跳转逻辑 + { + uint8_t taskId = ItemView->GetTaskId(); + uint8_t arrayIndex = taskId - 1; // 将任务ID转换为数组索引(ID从1开始,数组从0开始) + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ItemView->GetTaskId():%d, arrayIndex:%d", taskId, arrayIndex); + + // 检查数组索引是否有效 + if (arrayIndex < ChinaMobilelIOTModel::GetInstance()->GetTaskListNum()) + { + ChinaMobilelIOTModel::GetInstance()->Setlabel(itemInfo[arrayIndex].label); + ChinaMobilelIOTModel::GetInstance()->Setcontent(itemInfo[arrayIndex].content); + } + else + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid array index: %d, task count: %d", + arrayIndex, ChinaMobilelIOTModel::GetInstance()->GetTaskListNum()); + } + + ChinaMobilelIOTView::GetInstance()->ChangeView(WORKTASKVIW, WORKTASKCENTENTVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(WORKTASKCENTENTVIEW); + } + + return true; + } + + bool ChinaMobilelIOTPresenter::OnDrag(UIView &view, const DragEvent &event) + { + UNUSED(view); + UNUSED(event); + return true; + } + + bool ChinaMobilelIOTPresenter::OnDragEnd(UIView &view, const DragEvent &event) + { + UNUSED(view); + if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT) + { + if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() == CHINAMOBILEIOTFIRSTVIEW) + { + NativeAbility::GetInstance().Back(); // 返回上一个slice + } + else if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() == FIELDCHECKINRESULITVIEW) // 打卡结果界面 + { + ChinaMobilelIOTView::GetInstance()->ChangeView(FIELDCHECKINRESULITVIEW, FIELDCHECKINVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(FIELDCHECKINVIEW); + } + else if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() == WORKTASKCENTENTVIEW) // 任务详情界面 + { + ChinaMobilelIOTView::GetInstance()->ChangeView(WORKTASKCENTENTVIEW, WORKTASKVIW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(WORKTASKVIW); + } + else if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() != CHINAMOBILEIOTFIRSTVIEW) // 其他界面 + { + ChinaMobilelIOTView::GetInstance()->ChangeView(ChinaMobilelIOTModel::GetInstance()->Getcurrentview(), CHINAMOBILEIOTFIRSTVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(CHINAMOBILEIOTFIRSTVIEW); + } + } + return true; + } + + bool ChinaMobilelIOTPresenter::OnKeyAct(UIView &view, const KeyEvent &event) // 增加按键事件 + { + UNUSED(view); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DisplayBrightnessPresenter::OnKeyAct"); + unsigned short keyID = event.GetKeyId(); + unsigned short keyState = event.GetState(); + // 如果是power键,且是亮屏状态,按键释放就返回上一级 + if (keyID == static_cast(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 1 && uapi_get_screen_state() == 0) + { + if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() == CHINAMOBILEIOTFIRSTVIEW) + { + NativeAbility::GetInstance().Back(); // 返回上一个slice + } + else if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() == FIELDCHECKINRESULITVIEW) // 打卡结果界面 + { + ChinaMobilelIOTView::GetInstance()->ChangeView(FIELDCHECKINRESULITVIEW, FIELDCHECKINVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(FIELDCHECKINVIEW); + } + else if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() == WORKTASKCENTENTVIEW) // 任务详情界面 + { + ChinaMobilelIOTView::GetInstance()->ChangeView(WORKTASKCENTENTVIEW, WORKTASKVIW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(WORKTASKVIW); + } + else if (ChinaMobilelIOTModel::GetInstance()->Getcurrentview() != CHINAMOBILEIOTFIRSTVIEW) // 其他界面 + { + ChinaMobilelIOTView::GetInstance()->ChangeView(ChinaMobilelIOTModel::GetInstance()->Getcurrentview(), CHINAMOBILEIOTFIRSTVIEW); + ChinaMobilelIOTModel::GetInstance()->Setcurrentview(CHINAMOBILEIOTFIRSTVIEW); + } + } + return true; + } +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTView.cpp new file mode 100644 index 000000000..89bbd6438 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/ChinaMobilelIOTView.cpp @@ -0,0 +1,364 @@ +/*** + * @Date: 2025-07-21 10:55:58 + * @LastEditors: maomao 2144439972@qq.com + * @LastEditTime: 2025-07-21 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/ChinaMobilelIOTView.cpp + */ + +#include "common/image_cache_manager.h" +#include "ui_resource_image.h" +#include +#include "components/ui_button.h" +#include "MainViewSample.h" +#include "components/ui_view_group.h" +#include "BPModel.h" + +#include "UiConfig.h" +#include "uicomponents/UIComponents.h" +#include "MainPresenterSample.h" + +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTModel.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTModelC.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "bloodoxygen/include/BloodOxygenModel.h" +#include "goal/include/goalmodel.h" +#include "heartrate/include/HeartModel.h" +#include "bloodpressure/include/BPModel.h" +#include "wearable_log.h" +namespace OHOS +{ + static ChinaMobilelIOTView *g_pChinaMobilelIOTView{nullptr}; + static int Isregister = 0; + + ChinaMobilelIOTView::ChinaMobilelIOTView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::ChinaMobilelIOTView"); + g_pChinaMobilelIOTView = this; + } + + ChinaMobilelIOTView::~ChinaMobilelIOTView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::~ChinaMobilelIOTView"); + DeInit(); + g_pChinaMobilelIOTView = nullptr; + } + + ChinaMobilelIOTView *ChinaMobilelIOTView::GetInstance() + { + return g_pChinaMobilelIOTView; + } + + void ChinaMobilelIOTView::DeInit() + { + if (g_pChinaMobilelIOTFirstView) + { + delete g_pChinaMobilelIOTFirstView; + g_pChinaMobilelIOTFirstView = nullptr; + } + if (g_pDeviceBindingView) + { + delete g_pDeviceBindingView; + g_pDeviceBindingView = nullptr; + } + if (g_pFieldCheckinView) + { + delete g_pFieldCheckinView; + g_pFieldCheckinView = nullptr; + } + if (g_pPersonalInformationView) + { + delete g_pPersonalInformationView; + g_pPersonalInformationView = nullptr; + } + if (g_pWorkTaskView) + { + delete g_pWorkTaskView; + g_pWorkTaskView = nullptr; + } + } + + void ChinaMobilelIOTView::OnStart() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::OnStart"); + View::OnStart(); + SetContainerView(new UIViewGroup()); + if (GetContainer() == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "container_ new fail!!"); + return; + } + container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + container_->SetDraggable(true); + container_->SetTouchable(true); + container_->SetOnDragListener(presenter_); + Isregister = ConfigModel::GetInstance()->get_configData_int(ConfigModel::CONFIGMODEL_ITEM_WORKSYNC_REGISTER); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Isregister:%d", Isregister); + if (Isregister == 0) // 如果没有注册 + { +#ifdef ENABLE_WORK + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_CHECK_IN, NULL, 0); // 注册 + usleep(80000); + // 通过Model获取worksync数据 + ChinaMobilelIOTModel *model = ChinaMobilelIOTModel::GetInstance(); + if (model != nullptr) + { + worksync_get_worksync_data(&model->worksync_resev_data); + if (model->worksync_resev_data.requestKey != NULL) + { + worksync_save_requestKey(model->worksync_resev_data.requestKey, strlen(model->worksync_resev_data.requestKey)); + worksync_save_deviceId(model->worksync_resev_data.deviceId, strlen(model->worksync_resev_data.deviceId)); + ConfigModel::GetInstance()->set_condigData_Int(ConfigModel::CONFIGMODEL_ITEM_WORKSYNC_REGISTER, 1); + } + } +#endif + } +#ifdef ENABLE_WORK + // 提前获取数据 + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_DEVICE, NULL, 0); + usleep(100000); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_PERSONAL, NULL, 0); + usleep(100000); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_TASK, NULL, 0); + usleep(100000); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_GEOLOCATION, NULL, 0); + usleep(10000); +#endif + + ChangeView(MAX_VIEW, CHINAMOBILEIOTFIRSTVIEW); + + SetReproData(DATA_OXYGEN, std::to_string(BloodOxygenModel::GetInstance()->GetSPO2data()).c_str()); // 获取最近一次检测血氧; + SetReproData(DATA_HEART_RATE, std::to_string(HeartModel::GetInstance()->GetHeartdata()).c_str()); // 获取最近一次检测心率; + SetReproData(DATA_STEPS, std::to_string(GoalModel::GetInstance().show_data_step_refresh()).c_str()); // 获取步数 + SetReproData(DATA_CALORIE, std::to_string(GoalModel::GetInstance().show_data_calories_refresh()).c_str()); // 获取卡路里 +#ifdef ENABLE_WORK + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_BATCH_DATA, NULL, 0); // 上传健康数据 +#endif + + // 增加按键监听 + RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::ChinaMobilelIOTPresenter::GetInstance(); + + RootView::GetInstance()->SetOnKeyActListener(keyactListener); + } + void ChinaMobilelIOTView::OnSetUpView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::OnSetUpView"); + View::OnSetUpView(); + Draw(); + } + void ChinaMobilelIOTView::OnTearDownView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::OnTearDownView"); + View::OnTearDownView(); + return; + } + + void ChinaMobilelIOTView::OnStop() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::OnStop"); + View::OnStop(); + if (container_ != nullptr) + { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + return; + } + + bool ChinaMobilelIOTView::ChangeChinaMobilelIOTFirstView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::ChangeUnderInitialCalibrationView"); + g_pChinaMobilelIOTFirstView = new ChinaMobilelIOTFirstView(); + if (g_pChinaMobilelIOTFirstView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pChinaMobilelIOTFirstView->ChinaMobilelIOTFirstViewInit(); + container_->Add(group[thisView]); + } + return true; + } + bool ChinaMobilelIOTView::ChangeDeviceBindingView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::ChangeSecUnderInitialCalibrationView"); + g_pDeviceBindingView = new DeviceBindingView(); + if (g_pDeviceBindingView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pDeviceBindingView->DeviceBindingInit(); + container_->Add(group[thisView]); + } + return true; + } + + bool ChinaMobilelIOTView::ChangeFieldCheckinView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::BPValueView"); + g_pFieldCheckinView = new FieldCheckinView(); + if (g_pFieldCheckinView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pFieldCheckinView->FieldCheckinInit(); + container_->Add(group[thisView]); + } + return true; + } + bool ChinaMobilelIOTView::ChangePersonalInformationView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::ChangeUnderInitialCalibrationView"); + g_pPersonalInformationView = new PersonalInformationView(); + if (g_pPersonalInformationView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pPersonalInformationView->PersonalInformationInit(); + container_->Add(group[thisView]); + } + return true; + } + + bool ChinaMobilelIOTView::ChangeWorkTaskView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::ChangeBPLastCalibrationTimeView"); + g_pWorkTaskView = new WorkTaskView(); + if (g_pWorkTaskView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pWorkTaskView->WorkTaskInit(); + container_->Add(group[thisView]); + } + return true; + } + bool ChinaMobilelIOTView::ChangeWorkTaskContentView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::ChangeBPLastCalibrationTimeView"); + g_pWorkTaskContentView = new WorkTaskContentView(); + if (g_pWorkTaskContentView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pWorkTaskContentView->WorkTaskContentInit(); + container_->Add(group[thisView]); + } + else + { + // 视图已存在,更新UI内容 + if (g_pWorkTaskContentView != nullptr) + { + g_pWorkTaskContentView->UpdateContent(); + } + } + return true; + } + bool ChinaMobilelIOTView::ChangeFieldCheckinResultView(int16_t thisView) + { + // 检查视图是否已初始化 + if (group[thisView] == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BloodPressureView::ChangeBPLastCalibrationTimeView"); + g_pFieldCheckinResultView = new FieldCheckinResultView(); + if (g_pFieldCheckinResultView == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BloodPressureView:: new scrollView[%d] fail", thisView); + return false; + } + // 初始化视图并添加到视图组 + group[thisView] = g_pFieldCheckinResultView->FieldCheckinResultInit(); + container_->Add(group[thisView]); + } + return true; + } + + /** + * 视图映射结构体 - 将视图ID映射到对应的视图切换函数 + */ + struct BPViewMapper + { + const int16_t viewId; // 视图ID + bool (ChinaMobilelIOTView::*func)(int16_t); // 对应的视图切换函数指针 + }; + + static const BPViewMapper ViewMapper[] = { + {CHINAMOBILEIOTFIRSTVIEW, &ChinaMobilelIOTView::ChangeChinaMobilelIOTFirstView}, + {DEVICEBINDINGVIEW, &ChinaMobilelIOTView::ChangeDeviceBindingView}, + {FIELDCHECKINVIEW, &ChinaMobilelIOTView::ChangeFieldCheckinView}, + {PERSONALINFORMATIONBVIEW, &ChinaMobilelIOTView::ChangePersonalInformationView}, + {WORKTASKVIW, &ChinaMobilelIOTView::ChangeWorkTaskView}, + {WORKTASKCENTENTVIEW, &ChinaMobilelIOTView::ChangeWorkTaskContentView}, + {FIELDCHECKINRESULITVIEW, &ChinaMobilelIOTView::ChangeFieldCheckinResultView}, + }; + + bool ChinaMobilelIOTView::ClickFunc(int16_t interface) + { + int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[0]); + + for (int i = 0; i < funcSize; i++) + { + if (interface == ViewMapper[i].viewId) + { + bool jug = (this->*(ViewMapper[i].func))(interface); + if (jug == false) + { + return false; + } + return true; + } + } + return false; + } + + void ChinaMobilelIOTView::ChangeView(int16_t hideView, int16_t showView) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView::ChangeView"); + if (hideView > MAX_VIEW) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChinaMobilelIOTView:: SystemViewId Overstep ones bounds"); + return; + } + if (hideView != MAX_VIEW) + { + if (group[hideView] == nullptr) + { + return; + } + group[hideView]->SetVisible(false); + } + ClickFunc(showView); + group[showView]->SetVisible(true); + container_->Invalidate(); + } +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/DeviceBindingView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/DeviceBindingView.cpp new file mode 100644 index 000000000..227c0c005 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/DeviceBindingView.cpp @@ -0,0 +1,164 @@ +/*** + * @Date: 2024-04-15 10:55:58 + * @LastEditors: Caisking 3449750381@qq.com + * @LastEditTime: 2024-07-31 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/DeviceBindingView.cpp + */ + +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "uicomponents/UIComponents.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/DeviceBindingView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTModel.h" +namespace OHOS +{ + static DeviceBindingView *g_pDeviceBindingView{nullptr}; + static const char *BPBACKPATH = "/user/res/ChinamobileIOT/remind.bin"; + + DeviceBindingView::DeviceBindingView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "DeviceBindingView::DeviceBindingView"); + g_pDeviceBindingView = this; + IsBinding = ChinaMobilelIOTModel::GetInstance()->IsBindingInformation(); + } + DeviceBindingView::~DeviceBindingView() + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DeviceBindingView::~DeviceBindingView"); + DeInit(); + g_pDeviceBindingView = nullptr; + } + DeviceBindingView *DeviceBindingView::GetInstance() + { + return g_pDeviceBindingView; + } + void DeviceBindingView::DeInit() + { + if (group) + { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (remind != nullptr) + { + delete remind; + remind = nullptr; + } + if (bindinged != nullptr) + { + delete bindinged; + bindinged = nullptr; + } + if (unbinding != nullptr) + { + delete unbinding; + unbinding = nullptr; + } + if (Name != nullptr) + { + delete Name; + Name = nullptr; + } + if (Brand != nullptr) + { + delete Brand; + Brand = nullptr; + } + if (Model != nullptr) + { + delete Model; + Model = nullptr; + } + if (SerialNumber != nullptr) + { + delete SerialNumber; + SerialNumber = nullptr; + } + if (DeviceID != nullptr) + { + delete DeviceID; + DeviceID = nullptr; + } + } + /*** + * @description: + * @return 未绑定 + */ + bool DeviceBindingView::Initunbinding() + { + InitLabelExt(unbinding, 103, 249, 261, 41, "titleLable", STR_DEVICE_UNBOUND, DEFAULT_VECTOR_FONT_FILENAME, 28); + unbinding->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + group->Add(unbinding); + remind = new UIImageView(); + remind->SetPosition(201, 175, 66, 66); + remind->SetAutoEnable(false); + remind->SetWidth(66); + remind->SetHeight(66); + remind->SetResizeMode(UIImageView::COVER); + remind->SetSrc(BPBACKPATH); + group->Add(remind); + + /*初始化检测时间*/ + group->Add(unbinding); + + return true; + } + /*** + * @description: + * @return 成功绑定 + */ + bool DeviceBindingView::Initbindinged() + { + InitLabelExt(bindinged, 157, 76, 153, 53, "resultremindLable", STR_DEVICE_BINDING, DEFAULT_VECTOR_FONT_FILENAME, 36); + InitLabel(Name, 103, 151, 261, 41, "resultremindLable", "", DEFAULT_VECTOR_FONT_FILENAME, 28); + InitLabelExt(Brand, 156, 217, 300, 35, "resultremindLable", STR_BRAND, DEFAULT_VECTOR_FONT_FILENAME, 24); + Brand->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_LEFT); + InitLabelExt(Model, 123, 263, 221, 35, "resultremindLable", STR_MODEL, DEFAULT_VECTOR_FONT_FILENAME, 24); + InitLabelExt(SerialNumber, 103, 309, 261, 35, "resultremindLable", STR_IDENTIFICATION, DEFAULT_VECTOR_FONT_FILENAME, 24); + InitLabelExt(DeviceID, 103, 355, 300, 35, "resultremindLable", STR_DEVICE_ID, DEFAULT_VECTOR_FONT_FILENAME, 24); + + data = ChinaMobilelIOTModel::GetInstance()->GetBindingInformation(); + + Name->SetText(data.userName.c_str()); + Brand->SetText(("品牌:" + data.brand).c_str()); + Model->SetText(("型号:" + data.model).c_str()); + SerialNumber->SetText(("标识码:" + data.identificationCode).c_str()); + DeviceID->SetText(("设备ID:" + data.deviceId).c_str()); + group->Add(bindinged); + group->Add(Name); + group->Add(Brand); + group->Add(Model); + group->Add(SerialNumber); + group->Add(DeviceID); + + return true; + } + /*** + * @description: + * @return 是否初始化成功 + */ + UIViewGroup *DeviceBindingView::DeviceBindingInit() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool DeviceBindingView::InitView()"); + group = new UIViewGroup(); + if (group == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::group null!"); + return nullptr; + } + group->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + if (IsBinding) + { + Initbindinged(); + } + else + { + Initunbinding(); + } + return group; + } + +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/FieldCheckinResultView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/FieldCheckinResultView.cpp new file mode 100644 index 000000000..f6a8be859 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/FieldCheckinResultView.cpp @@ -0,0 +1,97 @@ +/*** + * @Date: 2024-04-15 10:55:58 + * @LastEditors: Caisking 3449750381@qq.com + * @LastEditTime: 2024-07-31 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/FieldCheckinResultView.cpp + */ + +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "uicomponents/UIComponents.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/FieldCheckinResultView.h" +namespace OHOS +{ + static FieldCheckinResultView *g_pFieldCheckinResultView{nullptr}; + static const char *SUCESSPATH = "/user/res/ChinamobileIOT/success.bin"; + static const char *FAILPATH = "/user/res/ChinamobileIOT/faild.bin"; + + FieldCheckinResultView::FieldCheckinResultView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FieldCheckinResultView::FieldCheckinResultView"); + g_pFieldCheckinResultView = this; + } + FieldCheckinResultView::~FieldCheckinResultView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FieldCheckinResultView::~FieldCheckinResultView"); + DeInit(); + g_pFieldCheckinResultView = nullptr; + } + FieldCheckinResultView *FieldCheckinResultView::GetInstance() + { + return g_pFieldCheckinResultView; + } + void FieldCheckinResultView::DeInit() + { + if (group) + { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (icon != nullptr) + { + delete icon; + icon = nullptr; + } + if (result != nullptr) + { + delete result; + result = nullptr; + } + } + /*** + * @description: + * @return 是否初始化成功 + */ + UIViewGroup *FieldCheckinResultView::FieldCheckinResultInit() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool FieldCheckinResultView::InitView()"); + group = new UIViewGroup(); + if (group == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::group null!"); + return nullptr; + } + group->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + + if (ChinaMobilelIOTModel::GetInstance()->GetState() == 1) // 打卡是否成功 + { + icon = new UIImageView(); + icon->SetPosition(202, 172); + icon->SetSrc(SUCESSPATH); + icon->SetAutoEnable(false); + icon->SetWidth(64); + icon->SetHeight(64); + icon->SetResizeMode(UIImageView::COVER); + InitLabelExt(result, 103, 253, 261, 41, "titleLable", STR_PUNCH_SUCCESS, DEFAULT_VECTOR_FONT_FILENAME, 28); + } + else + { + icon = new UIImageView(); + icon->SetPosition(202, 172); + icon->SetSrc(FAILPATH); + icon->SetAutoEnable(false); + icon->SetWidth(64); + icon->SetHeight(64); + icon->SetResizeMode(UIImageView::COVER); + InitLabelExt(result, 103, 253, 261, 41, "titleLable", STR_PUNCH_FAILURE, DEFAULT_VECTOR_FONT_FILENAME, 28); + } + group->Add(icon); + group->Add(result); + return group; + } + +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/FieldCheckinView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/FieldCheckinView.cpp new file mode 100644 index 000000000..af1277c0e --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/FieldCheckinView.cpp @@ -0,0 +1,181 @@ +/*** + * @Date: 2024-04-15 10:55:58 + * @LastEditors: Caisking 3449750381@qq.com + * @LastEditTime: 2024-07-31 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/FieldCheckinView.cpp + */ + +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "uicomponents/UIComponents.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/FieldCheckinView.h" +namespace OHOS +{ + static FieldCheckinView *g_pFieldCheckinView{nullptr}; + static const char *REFRESHPATH = "/user/res/ChinamobileIOT/reposition.bin"; + static const char *CIRCLE1PATH = "/user/res/ChinamobileIOT/circle1.bin"; + static const char *CIRCLE2PATH = "/user/res/ChinamobileIOT/circle2.bin"; + static const char *CIRCLE3PATH = "/user/res/ChinamobileIOT/circle3.bin"; + static const char *LOCATIONPATH = "/user/res/ChinamobileIOT/dingwei.bin"; + + FieldCheckinView::FieldCheckinView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FieldCheckinView::FieldCheckinView"); + g_pFieldCheckinView = this; + ChinaMobilelIOTModel::GetInstance()->StartTimer(); + } + FieldCheckinView::~FieldCheckinView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FieldCheckinView::~FieldCheckinView"); + DeInit(); + g_pFieldCheckinView = nullptr; + ChinaMobilelIOTModel::GetInstance()->StopTimer(); + } + FieldCheckinView *FieldCheckinView::GetInstance() + { + return g_pFieldCheckinView; + } + void FieldCheckinView::DeInit() + { + if (group) + { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (address != nullptr) + { + delete address; + address = nullptr; + } + if (timeLabel != nullptr) + { + delete timeLabel; + timeLabel = nullptr; + } + if (checkButton != nullptr) + { + delete checkButton; + checkButton = nullptr; + } + if (refresh != nullptr) + { + delete refresh; + refresh = nullptr; + } + if (circle1 != nullptr) + { + delete circle1; + circle1 = nullptr; + } + if (circle2 != nullptr) + { + delete circle2; + circle2 = nullptr; + } + if (circle3 != nullptr) + { + delete circle3; + circle3 = nullptr; + } + if (location != nullptr) + { + delete location; + location = nullptr; + } + } + void FieldCheckinView::locationInit() + { + circle1 = new UIImageView(); + circle1->SetPosition(193, 91, 86, 86); + circle1->SetAutoEnable(false); + circle1->SetWidth(86); + circle1->SetHeight(86); + circle1->SetResizeMode(UIImageView::COVER); + circle1->SetSrc(CIRCLE1PATH); + + circle2 = new UIImageView(); + circle2->SetPosition(182, 80, 108, 108); + circle2->SetAutoEnable(false); + circle2->SetWidth(108); + circle2->SetHeight(108); + circle2->SetResizeMode(UIImageView::COVER); + circle2->SetSrc(CIRCLE2PATH); + + circle3 = new UIImageView(); + circle3->SetPosition(170, 68, 133, 133); + circle3->SetAutoEnable(false); + circle3->SetWidth(133); + circle3->SetHeight(133); + circle3->SetResizeMode(UIImageView::COVER); + circle3->SetSrc(CIRCLE3PATH); + + location = new UIImageView(); + location->SetPosition(213, 111, 48, 48); + location->SetAutoEnable(false); + location->SetWidth(48); + location->SetHeight(48); + location->SetResizeMode(UIImageView::COVER); + location->SetSrc(LOCATIONPATH); + + group->Add(circle3); + group->Add(circle2); + group->Add(circle1); + group->Add(location); + } + + /*** + * @description: + * @return 是否初始化成功 + */ + UIViewGroup *FieldCheckinView::FieldCheckinInit() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool FieldCheckinView::InitView()"); + group = new UIViewGroup(); + if (group == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::group null!"); + return nullptr; + } + group->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + InitLabel(address, 39, 200, 387, 63, "titleLable", "等待GPS定位中", DEFAULT_VECTOR_FONT_FILENAME, 28); + address->SetText(ChinaMobilelIOTModel::GetInstance()->GetAdress()); + InitLabel(timeLabel, 160, 256, 145, 53, "titleLable", "08:52:02", DEFAULT_VECTOR_FONT_FILENAME, 36); + timeLabel->SetText(ChinaMobilelIOTModel::GetInstance()->GetCurrentTimeStr().c_str()); // 每秒变化 + InitButtonExt(checkButton, 101, 326, 262, 72, "checkin", STR_PUNCH, 32); + checkButton->SetViewId(CHEKINBUTTON); + checkButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff3472fc); // 设置按键颜色 + checkButton->SetTextColor(Color::White()); + + // 设置按键监听 + UIView::OnClickListener *clickListener = (UIView::OnClickListener *)OHOS::ChinaMobilelIOTPresenter::GetInstance(); + checkButton->SetOnClickListener(clickListener); + InitImageView(refresh, 376, 347, 32, 32, "refresh", REFRESHPATH); + refresh->SetAutoEnable(false); + refresh->SetWidth(32); + refresh->SetHeight(32); + refresh->SetTouchable(true); + refresh->SetResizeMode(UIImageView::COVER); + refresh->SetViewId(REFRESHIMAGE); + // 设置按键监听 + UIView::OnClickListener *clickListener_1 = (UIView::OnClickListener *)OHOS::ChinaMobilelIOTPresenter::GetInstance(); + refresh->SetOnClickListener(clickListener_1); + + locationInit(); + group->Add(address); + group->Add(timeLabel); + group->Add(checkButton); + group->Add(refresh); + + return group; + } + + void FieldCheckinView::UpdateTimeText(const char *time) + { + timeLabel->SetText(time); // 每秒变化 + } + +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/PersonalInformationView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/PersonalInformationView.cpp new file mode 100644 index 000000000..db85df6c2 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/PersonalInformationView.cpp @@ -0,0 +1,118 @@ +/*** + * @Date: 2024-04-15 10:55:58 + * @LastEditors: Caisking 3449750381@qq.com + * @LastEditTime: 2024-07-31 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/PersonalInformationView.cpp + */ + +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "uicomponents/UIComponents.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/PersonalInformationView.h" +namespace OHOS +{ + static PersonalInformationView *g_pPersonalInformationView{nullptr}; + static const char *BPBACKPATH = "/user/res/BPCalibration/right.bin"; + + PersonalInformationView::PersonalInformationView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PersonalInformationView::PersonalInformationView"); + g_pPersonalInformationView = this; + data = ChinaMobilelIOTModel::GetInstance()->GetPersonalInfo(); + } + PersonalInformationView::~PersonalInformationView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "PersonalInformationView::~PersonalInformationView"); + DeInit(); + g_pPersonalInformationView = nullptr; + } + PersonalInformationView *PersonalInformationView::GetInstance() + { + return g_pPersonalInformationView; + } + void PersonalInformationView::DeInit() + { + if (group) + { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (personalinformation != nullptr) + { + delete personalinformation; + personalinformation = nullptr; + } + if (Name != nullptr) + { + delete Name; + Name = nullptr; + } + if (unit != nullptr) + { + delete unit; + unit = nullptr; + } + if (department != nullptr) + { + delete department; + department = nullptr; + } + if (phone != nullptr) + { + delete phone; + phone = nullptr; + } + if (registerTime != nullptr) + { + delete registerTime; + registerTime = nullptr; + } + } + bool PersonalInformationView::Initbackground() + { + InitLabelExt(personalinformation, 161, 69, 144, 53, "resultremindLable", STR_PROFILE, DEFAULT_VECTOR_FONT_FILENAME, 36); + InitLabel(Name, 103, 143, 261, 41, "resultremindLable", " ", DEFAULT_VECTOR_FONT_FILENAME, 28); + InitLabelExt(unit, 103, 207, 261, 35, "resultremindLable", STR_UNIT, DEFAULT_VECTOR_FONT_FILENAME, 24); + InitLabelExt(department, 103, 256, 261, 35, "resultremindLable", STR_DEPARTMENT, DEFAULT_VECTOR_FONT_FILENAME, 24); + InitLabelExt(phone, 86, 306, 294, 41, "resultremindLable", STR_PHONE_NUMBER, DEFAULT_VECTOR_FONT_FILENAME, 28); + InitLabelExt(registerTime, 74, 362, 318, 35, "resultremindLable", STR_REGISTER_TIME, DEFAULT_VECTOR_FONT_FILENAME, 24); + Name->SetText(data.name.c_str()); + unit->SetText(("单位:" + data.unit).c_str()); + department->SetText(("部门:" + data.department).c_str()); + phone->SetText(("手机号:" + data.phone).c_str()); + registerTime->SetText(("注册时间:" + data.registerTime).c_str()); + group->Add(personalinformation); + group->Add(Name); + group->Add(unit); + group->Add(department); + group->Add(phone); + group->Add(registerTime); + + return true; + } + /*** + * @description: + * @return 是否初始化成功 + */ + UIViewGroup *PersonalInformationView::PersonalInformationInit() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool PersonalInformationView::InitView()"); + group = new UIViewGroup(); + if (group == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::group null!"); + return nullptr; + } + group->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + if(Initbackground()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::Initbackground null!"); + } + return group; + } + +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskAdapter.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskAdapter.cpp new file mode 100644 index 000000000..92ec0a9a8 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskAdapter.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: WorkTaskAdapter.cpp + * Author: + * Create: 2021-11-23 + */ + +#include "chinamobilelIOT/include/WorkTaskAdapter.h" + +namespace OHOS { +WorkTaskAdapter::WorkTaskAdapter() {} + +WorkTaskAdapter::~WorkTaskAdapter() +{ + listData.clear(); +} + +uint16_t WorkTaskAdapter::GetCount(void) +{ + return listData.size(); +} + +void WorkTaskAdapter::SetData(std::list &data) +{ + if (!listData.empty()) { + listData.clear(); + } + std::list::iterator it; + for (it = data.begin(); it != data.end(); it++) { + listData.push_back(*it); + } +} + +UIView *WorkTaskAdapter::GetView(UIView *inView, int16_t index) +{ + if (listData.empty()) { + return nullptr; + } + if (index < 0) { + return nullptr; + } + size_t uindex = index; + if (uindex >= listData.size()) { + return nullptr; + } + + std::list::iterator it = listData.begin(); + for (int i = 0; i < index; i++) { + it++; + } + TaskItem itemData = *it; + WorkTaskSettingItemView *item = nullptr; + if (inView == nullptr) { + item = new WorkTaskSettingItemView(); + } else { + item = static_cast(inView); + } + + item->SetItemInfo(itemData); + item->SetOnClickListener(itemClickListener); + return item; +} + +void WorkTaskAdapter::AddListItem(const TaskItem &item) +{ + listData.push_back(item); +} +} // namespace OHOS diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskContentView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskContentView.cpp new file mode 100644 index 000000000..d86a8843c --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskContentView.cpp @@ -0,0 +1,94 @@ +/*** + * @Date: 2024-04-15 10:55:58 + * @LastEditors: Caisking 3449750381@qq.com + * @LastEditTime: 2024-07-31 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/WorkTaskContentView.cpp + */ + +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "uicomponents/UIComponents.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/WorkTaskContentView.h" +namespace OHOS +{ + static WorkTaskContentView *g_pWorkTaskContentView{nullptr}; + static const char *BPBACKPATH = "/user/res/BPCalibration/right.bin"; + + WorkTaskContentView::WorkTaskContentView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WorkTaskContentView::WorkTaskContentView"); + g_pWorkTaskContentView = this; + } + WorkTaskContentView::~WorkTaskContentView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WorkTaskContentView::~WorkTaskContentView"); + DeInit(); + g_pWorkTaskContentView = nullptr; + } + WorkTaskContentView *WorkTaskContentView::GetInstance() + { + return g_pWorkTaskContentView; + } + void WorkTaskContentView::DeInit() + { + if (group) + { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (title != nullptr) + { + delete title; + title = nullptr; + } + if (content != nullptr) + { + delete content; + content = nullptr; + } + + } + void WorkTaskContentView::UpdateContent() +{ + if (title != nullptr && content != nullptr) + { + const char *task_title = ChinaMobilelIOTModel::GetInstance()->Getlabel(); + const char *task_content = ChinaMobilelIOTModel::GetInstance()->Getcontent(); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateContent: title=%s, content=%s", + task_title ? task_title : "NULL", task_content ? task_content : "NULL"); + + title->SetText(task_title); + content->SetText(task_content); + } +} + /*** + * @description: + * @return 是否初始化成功 + */ + UIViewGroup *WorkTaskContentView::WorkTaskContentInit() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool WorkTaskContentView::InitView()"); + group = new UIViewGroup(); + if (group == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::group null!"); + return nullptr; + } + group->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + InitLabel(title, 103, 61, 261, 41, "resultremindLable", ChinaMobilelIOTModel::GetInstance()->Getlabel(), DEFAULT_VECTOR_FONT_FILENAME, 28); + InitLabel(content, 103, 121, 261, 284, "resultremindLable", ChinaMobilelIOTModel::GetInstance()->Getcontent(), DEFAULT_VECTOR_FONT_FILENAME, 28); + content->SetStyle(STYLE_LINE_HEIGHT, 40.54); + content->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + content->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + group->Add(title); + group->Add(content); + + return group; + } + +} diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskSettingItemView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskSettingItemView.cpp new file mode 100644 index 000000000..e4eb83abf --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskSettingItemView.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved. + * Description: WorkTaskSettingItemView.cpp + * Author: + * Create: 2021-11-23 + */ +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "chinamobilelIOT/include/WorkTaskSettingItemView.h" + +namespace OHOS { + static constexpr int16 SETTING_ICON_X = 20; + static constexpr int16 NUM_22 = 22; + static constexpr int16_t SETTING_ITEM_BUTTON_HEIGHT = 100; + static constexpr int16_t SETTING_ITEM_LABEL_WIDTH = 155; + static constexpr int16_t SETTING_ITEM_LABEL_HEIGHT = 100; + static constexpr int16 SETTING_ITEM_FONT_SIZE = 35; + static constexpr int16_t SETTINGS_RESIZE_SIZE = 100; + static constexpr int16_t SETTING_SICON_Y = 10; + static constexpr int16 NUMS_2 = 2; + static constexpr int16 NUMS_50 = 50; + static const char *TASKICONPATH = "/user/res/ChinamobileIOT/task.bin"; + + WorkTaskSettingItemView::WorkTaskSettingItemView() + { + SetPosition(0, 0, HORIZONTAL_RESOLUTION, SETTING_ITEM_BUTTON_HEIGHT); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + SetTouchable(true); + SetUpChild(); + + Add(&sIcon); + Add(&sLabel); + Add(&sNextImage); + } + + WorkTaskSettingItemView::~WorkTaskSettingItemView() + { + Remove(&sIcon); + Remove(&sLabel); + Remove(&sNextImage); + } + + void WorkTaskSettingItemView::SetItemInfo(const TaskItem itemInfo) + { + sItemInfo = itemInfo; + sIcon.SetSrc(TASKICONPATH); + sLabel.SetText(itemInfo.label); + sNextImage.SetVisible(itemInfo.hasSecondMenu); + } + + void WorkTaskSettingItemView::SetUpChild() + { + sIcon.SetPosition(0, SETTING_SICON_Y); + sIcon.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + sIcon.SetAutoEnable(false); + sIcon.SetWidth(90.64); + sIcon.SetHeight(90.64); + sIcon.SetResizeMode(UIImageView::COVER); + + sLabel.SetPosition(120, 0); + sLabel.Resize(SETTING_ITEM_LABEL_WIDTH, SETTING_ITEM_LABEL_HEIGHT); + sLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, SETTING_ITEM_FONT_SIZE); + sLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + sLabel.SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + sLabel.SetStyle(STYLE_TEXT_COLOR, Color::White().full); + sLabel.SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + sLabel.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + sNextImage.SetSrc(PNG_SETTING_NEXT_IMAGE); + sNextImage.SetPosition(LA_HORIZONTAL_RESOLUTION - 80, (SETTING_ITEM_HEIGHT - sNextImage.GetHeight()) / NUMS_2); + sNextImage.SetStyle(STYLE_IMAGE_OPA, OPA_OPAQUE); + } + uint8_t WorkTaskSettingItemView::GetTaskId() + { + return sItemInfo.id; + } + const char * WorkTaskSettingItemView::GetTasklabel() + { + return sItemInfo.label; + } + const char * WorkTaskSettingItemView::GetTaskcontent() + { + return sItemInfo.content; + } + + + + +} \ No newline at end of file diff --git a/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskView.cpp b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskView.cpp new file mode 100644 index 000000000..170485abf --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/chinamobilelIOT/src/WorkTaskView.cpp @@ -0,0 +1,190 @@ +/*** + * @Date: 2024-04-15 10:55:58 + * @LastEditors: Caisking 3449750381@qq.com + * @LastEditTime: 2024-07-31 14:36:25 + * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/bloodpressure/src/WorkTaskView.cpp + */ + +#include "ui_resource_image.h" +#include "UiConfig.h" +#include "wearable_log.h" +#include "uicomponents/UIComponents.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTView.h" +#include "chinamobilelIOT/include/ChinaMobilelIOTPresenter.h" +#include "chinamobilelIOT/include/WorkTaskView.h" +#include "chinamobilelIOT/include/WorkTaskAdapter.h" +namespace OHOS +{ + static WorkTaskView *g_pWorkTaskView{nullptr}; + static const char *TASKPATH = "/user/res/ChinamobileIOT/notask.bin"; + + static constexpr uint8_t SETTINGS_ITEM_FONT_SIZE = 40; + static constexpr int16_t SETTINGS_RESIZE_SIZE_WIDTH = 90.64; + static constexpr int16_t SETTINGS_RESIZE_SIZE_HEIGHT = 378.2; + static constexpr int16_t SETTING_LIST_POSITION_X = 79; // + static constexpr int16_t SETTING_LIST_POSITION_Y = 68; // + static constexpr int16_t SETTING_SCROLLBLANKSIZE = 100; + static constexpr int16 MAX_SCR_DIS = 1000; + static constexpr int16 LIST_POS = 20; + static constexpr int16 SNUM_2 = 2; + + WorkTaskView::WorkTaskView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WorkTaskView::WorkTaskView"); + g_pWorkTaskView = this; + } + WorkTaskView::~WorkTaskView() + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WorkTaskView::~WorkTaskView"); + DeInit(); + g_pWorkTaskView = nullptr; + } + WorkTaskView *WorkTaskView::GetInstance() + { + return g_pWorkTaskView; + } + void WorkTaskView::DeInit() + { + if (group) + { + group->RemoveAll(); + delete group; + group = nullptr; + } + if (listAdapter != nullptr) + { + delete listAdapter; + listAdapter = nullptr; + } + if (scrollView != nullptr) + { + delete scrollView; + scrollView = nullptr; + } + if (contentList != nullptr) + { + delete contentList; + contentList = nullptr; + } + if (dragListener != nullptr) + { + delete dragListener; + dragListener = nullptr; + } + if (task != nullptr) + { + delete task; + task = nullptr; + } + if (notask != nullptr) + { + delete notask; + notask = nullptr; + } + } + bool WorkTaskView::UnWorkTask() + { + task = new UIImageView(); + task->SetPosition(170, 152); + task->SetSrc(TASKPATH); + task->SetAutoEnable(false); + task->SetWidth(128); + task->SetHeight(128); + task->SetResizeMode(UIImageView::COVER); + + InitLabelExt(notask, 103, 273, 261, 41, "resultremindLable", STR_NO_TASK, DEFAULT_VECTOR_FONT_FILENAME, 24); + group->Add(task); + group->Add(notask); + return true; + } + bool WorkTaskView::WorkTask() + { + scrollView = new UIScrollView(); + if (scrollView == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::scrollView is nullptr"); + return false; + } + scrollView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + scrollView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + scrollView->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); + scrollView->SetThrowDrag(true); + + + contentList = new UIList(); + if (contentList == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::contentList is nullptr"); + return false; + } + contentList->SetPosition(79, 0); + contentList->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + contentList->SetScrollBlankSize(SETTING_SCROLLBLANKSIZE); + contentList->SetSelectPosition(HORIZONTAL_RESOLUTION / SNUM_2); // middle position + contentList->SetDraggable(true); + contentList->SetThrowDrag(false); + contentList->EnableAutoAlign(true); + contentList->SetMaxScrollDistance(MAX_SCR_DIS); + + dragListener = new ChinaMobilelIOTPresenter(); + if (dragListener == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView:: OnStart::new dragListener is nullptr"); + return false; + } + scrollView->SetOnDragListener(dragListener); + scrollView->SetYScrollBarVisible(true); + scrollView->Add(contentList); + contentList->SetAdapter(listAdapter); + group->Add(scrollView); + return true; + } + + /*** + * @description: + * @return 是否初始化成功 + */ + UIViewGroup *WorkTaskView::WorkTaskInit() + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "bool WorkTaskView::InitView()"); + group = new UIViewGroup(); + if (group == nullptr) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmPopUpView::group null!"); + return nullptr; + } + group->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); + listAdapter = new WorkTaskAdapter(); + if (listAdapter == nullptr) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::OnStart::listAdapter is nullptr"); + return nullptr; + } + listAdapter->SetItemClickListener(ChinaMobilelIOTPresenter::GetInstance()); + ChinaMobilelIOTModel::GetInstance()->InitTaskItem(); + const TaskItem *itemInfo = ChinaMobilelIOTModel::GetInstance()->GetTaskItems(); + if (ChinaMobilelIOTModel::GetInstance()->GetTaskListNum() == 0) + { + UnWorkTask(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool WorkTaskView::UnWorkTask()"); + } + else + { + for (uint8_t i = 0; i < ChinaMobilelIOTModel::GetInstance()->GetTaskListNum(); i++) + { + AddWorkTaskItemToList(itemInfo[i]); + } + WorkTask(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bool WorkTaskView::WorkTask()"); + } + + return group; + } + + void WorkTaskView::AddWorkTaskItemToList(const TaskItem &item) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingView::AddSettingItemToList"); + listAdapter->AddListItem(item); + } + +} diff --git a/code/sdk/build/config/target_config/brandy/config.py b/code/sdk/build/config/target_config/brandy/config.py index 597f9581b..11a9fcc1a 100755 --- a/code/sdk/build/config/target_config/brandy/config.py +++ b/code/sdk/build/config/target_config/brandy/config.py @@ -583,16 +583,18 @@ target = { '-:ROTARYENCODER_HX3507', '-:BOARD_FD230', 'BOARD_N9', - 'SUPPORT_GNSS', - 'DISABLE_UART_LOG', - 'CONFIG_GNSS_UART_WITH_FLOWCTRL', - 'DOWNLOAD_GNSS_SWITCH', + # 'SUPPORT_GNSS', + # 'DISABLE_UART_LOG', + # 'CONFIG_GNSS_UART_WITH_FLOWCTRL', + # 'DOWNLOAD_GNSS_SWITCH', 'TPTYPE_CST86XX', 'NANDFLASH_F35UQA', 'PPG_PAH8009', 'GYRO_SH5001', 'ROTARYENCODER_MIXO', 'ENABLE_GYRO', + 'ENABLE_WORK', + 'CM_IOT', ], 'ram_component': [ "gnss", @@ -600,7 +602,8 @@ target = { "pgnss_sample", #"ppg_sensor_gh3x2x", "ppg_sensor_pah8009", - #"bp_sensor", + # "bp_sensor", + 'worksync_sensor', "gyro", ], 'image_analysis': False, diff --git a/code/sdk/drivers/peripheral/CMakeLists.txt b/code/sdk/drivers/peripheral/CMakeLists.txt index b1a8bd229..a8d2c4914 100644 --- a/code/sdk/drivers/peripheral/CMakeLists.txt +++ b/code/sdk/drivers/peripheral/CMakeLists.txt @@ -22,4 +22,5 @@ add_subdirectory_if_exist(a5133) add_subdirectory_if_exist(entest) add_subdirectory_if_exist(gnss) add_subdirectory_if_exist(bp) -add_subdirectory_if_exist(gyro) \ No newline at end of file +add_subdirectory_if_exist(gyro) +add_subdirectory_if_exist(worksync) \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/config/include/ConfigModel.h b/code/sdk/drivers/peripheral/config/include/ConfigModel.h index 50a11661c..e70d85f95 100644 --- a/code/sdk/drivers/peripheral/config/include/ConfigModel.h +++ b/code/sdk/drivers/peripheral/config/include/ConfigModel.h @@ -160,6 +160,9 @@ namespace OHOS CONFIGMODEL_ITEM_BP_CALIBRATION_FIRST_TIME, //血压校准第一次校准 CONFIGMODEL_ITEM_BP_CALIBRATION_SECOND_TIME, //血压校准第二次校准 #endif + + CONFIGMODEL_ITEM_WORKSYNC_REGISTER, //中移物联注册判断 0为注册,1已注册 + CONFIGMODEL_ITEM_DEV_ID, CONFIGMODEL_ITEM_MAX, diff --git a/code/sdk/drivers/peripheral/worksync/CMakeLists.txt b/code/sdk/drivers/peripheral/worksync/CMakeLists.txt new file mode 100644 index 000000000..11fc39cc2 --- /dev/null +++ b/code/sdk/drivers/peripheral/worksync/CMakeLists.txt @@ -0,0 +1,46 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "worksync_sensor") + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/service/worksync_at_cmd.c + ${CMAKE_CURRENT_SOURCE_DIR}/service/worksync_tcp_server.c + +) + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/service/ + ${ROOT_DIR}/application/wearable/fd230app/nativeui/chinamobilelIOT/include +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES + TARGET_NAME="${TARGET_COMMAND}" + BUILD_TIME="${BUILD_TIME}" +) + +set(PUBLIC_DEFINES +SUPPORT_AT_WORK +ENABLE_WORK +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) +build_component() diff --git a/code/sdk/drivers/peripheral/worksync/service/worksync_at_cmd.c b/code/sdk/drivers/peripheral/worksync/service/worksync_at_cmd.c new file mode 100644 index 000000000..245603995 --- /dev/null +++ b/code/sdk/drivers/peripheral/worksync/service/worksync_at_cmd.c @@ -0,0 +1,145 @@ +/* + * @Author: penglei 1624952103@qq.com + * @Date: 2024-12-23 15:11:01 + * @LastEditors: penglei 1624952103@qq.com + * @LastEditTime: 2025-07-02 16:34:24 + * @FilePath: /sdk615/code/sdk/zhihui/drivers/worksync/HP4570/service/worksync_at_cmd.c + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +#include "at_cmd_api.h" +#include "pm_control.h" +#include "debug_print.h" +#include "custom_utils.h" +#include "worksync_tcp_server.h" + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define WORKSYNC_MAX_ARGC 8 +#define WORKSYNC_MAX_ARGV_LEN 64 + +#define WORKSYNC_SUCCESS 0 +#define WORKSYNC_FAILED (-1) + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[WORKSYNC_MAX_ARGC][WORKSYNC_MAX_ARGV_LEN], uint32_t *argc) +{ + uint32_t pos = 0; + *argc = 0; + + for (uint32_t i = 0; i < paraLen; i++) + { + if ((para[i] == ' ' || para[i] == '\n') && pos != 0) + { + argv[*argc][pos] = '\0'; + *argc += 1; + pos = 0; + if (*argc >= WORKSYNC_MAX_ARGC) + { + return WORKSYNC_FAILED; + } + } + else + { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= WORKSYNC_MAX_ARGV_LEN) + { + return WORKSYNC_FAILED; + } + } + } + if (pos != 0) + { + *argc += 1; + } + + return WORKSYNC_SUCCESS; +} + +static uint8_t g_worksync_test_started = 0; + +static uint32_t worksync_sign(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + + tcp_worksync_sign_up(); + + return ERRCODE_SUCC; +} + +static uint32_t worksync_get_active_code(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + + // get_active_code(); + + return ERRCODE_SUCC; +} + +static uint32_t worksync_login(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_SERVER_INIT, NULL, 0); + return ERRCODE_SUCC; +} + +static uint32_t worksync_register(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 注册 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_REGISTER, NULL, 0); + return ERRCODE_SUCC; +} +static uint32_t worksync_device(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 获取设备信息 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_DEVICE, NULL, 0); + return ERRCODE_SUCC; +} +static uint32_t worksync_personal(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 获取个人信息 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_PERSONAL, NULL, 0); + return ERRCODE_SUCC; +} +static uint32_t worksync_task(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 获取任务列表 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_TASK, NULL, 0); + return ERRCODE_SUCC; +} +static uint32_t worksync_adress(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 获取地理位置 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_GET_GEOLOCATION, NULL, 0); + return ERRCODE_SUCC; +} +static uint32_t worksync_checkin(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 打卡 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_CHECK_IN, NULL, 0); + return ERRCODE_SUCC; +} +static uint32_t worksync_batch_data(uint8_t *para, uint32_t paraLen, char *strCommonCmd) // 多数据上报 +{ + UNUSED(strCommonCmd); + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_BATCH_DATA, NULL, 0); + return ERRCODE_SUCC; +} + +static const at_cmd_table_t g_worksync_cmd[] = { + {(char *)"AT^WORKSYNCSIGN", worksync_sign, (char *)"1"}, + {(char *)"AT^WORKSYNCACTIVE", worksync_get_active_code, (char *)"1"}, + {(char *)"AT^WORKSYNCLOGIN", worksync_login, (char *)"1"}, + {(char *)"AT^WORKSYNCREGISTER", worksync_register, (char *)"1"}, + {(char *)"AT^WORKSYNCDEVICE", worksync_device, (char *)"1"}, + {(char *)"AT^WORKSYNCPERSONAL", worksync_personal, (char *)"1"}, + {(char *)"AT^WORKSYNCTASK", worksync_task, (char *)"1"}, + {(char *)"AT^WORKSYNCADRESS", worksync_adress, (char *)"1"}, + {(char *)"AT^WORKSYNCCKEKIN", worksync_checkin, (char *)"1"}, + {(char *)"AT^WORKSYNCDATAS", worksync_batch_data, (char *)"1"}, +}; + +at_cmd_table_t *get_worksync_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_worksync_cmd); + return (at_cmd_table_t *)g_worksync_cmd; +} diff --git a/code/sdk/drivers/peripheral/worksync/service/worksync_at_cmd.h b/code/sdk/drivers/peripheral/worksync/service/worksync_at_cmd.h new file mode 100644 index 000000000..af038642d --- /dev/null +++ b/code/sdk/drivers/peripheral/worksync/service/worksync_at_cmd.h @@ -0,0 +1,40 @@ +/* + * @Author: penglei 1624952103@qq.com + * @Date: 2024-12-18 10:23:22 + * @LastEditors: penglei 1624952103@qq.com + * @LastEditTime: 2025-01-16 15:07:33 + * @FilePath: /sdk615/code/sdk/drivers/peripheral/rotary_encoder/hx3509/hx3509_at_cmd.h + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +/** + * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n + * + * Description: Provides at cmd register func \n + * Author: @CompanyNameTag \n + * History: \n + * 2022-07-20, Create file. \n + */ +#ifndef WORKSYNC_AT_PROCESS_H +#define WORKSYNC_AT_PROCESS_H + +#include +#include +#include "errcode.h" +#include "soc_osal.h" +#include "at_cmd_api.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +at_cmd_table_t *get_worksync_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/worksync/service/worksync_tcp_server.c b/code/sdk/drivers/peripheral/worksync/service/worksync_tcp_server.c new file mode 100644 index 000000000..3d19de9d7 --- /dev/null +++ b/code/sdk/drivers/peripheral/worksync/service/worksync_tcp_server.c @@ -0,0 +1,2828 @@ +#include "pinctrl.h" +#include "debug_print.h" +#include "rtc.h" +#include "timer.h" +#include "systick.h" + +#include "tcxo.h" + +#include "cmsis_os2.h" +#include "input_app.h" +#include "custom_utils.h" +#include "worksync_tcp_server.h" +#include "custom_runtime.h" +#include +#include "lwip/ip.h" +#include "lwip/netif.h" +#include "lwip/init.h" +#include "lwip/inet_chksum.h" +#include "ChinaMobilelIOTModelC.h" +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include +#include +// #include +#include "lwip/inet.h" +#include "lwip/ip_addr.h" +#include "pm_definition.h" +#include "mbedtls/md5.h" +#include "mbedtls/base64.h" +#include "cJSON.h" +#include "md.h" +#if defined(SUPPORT_GNSS) +#include "gnss_ctl.h" +#include "NMEA0183.h" +#endif + +#define BID "hu4kZYyYMGO" +#define KEY "tcUpJpeGpsIBXvjG" + +#define SERVER_HOST "iot.socket.thisiot.com" +#define SERVER_PORT 9999 +// 6a0f3a4f7a5f1d9a4b7b8e5c6d7a8f9b +// 89b67780ac2e2d554f25df8acfabae4f +#define APP_ID "190818B2968A5005" +#define APP_KEY "528c9b9ebf074d588b1f01c2c2d25f8d" +#define NAME "海思鸿蒙血压手表" +#define URL_HEADER "http://47.93.37.47:8080/techwrist_api" + +#define REGISTER_URL "/iot/v1/register" +#define DEVICE_URL "/iot/v1/device/info" +#define USER_URL "/iot/v1/user/info" +#define TASK_URL "/iot/v1/task/list" +#define ADRESS_URL "/iot/v1/address" +#define GEO_URL "/iot/v1/clock/geo" +#define DATA_URL "/iot/v1/push/data" +#define DATAS_URL "/iot/v1/push/datas" +#define LOGIN_URL "/entrance/user/login" +#define ACTIVE_URL "/sinklib/activation" +#define CREATE_URL "/health/synthesis/create" +// #define MAX_CNT 16 * 5 * 60 +#define MAX_CNT 16 * 5 * 50 + +static uint32_t timestamp; // 当前时间戳 +static char sign[256] = {0}; +static char request_sign[256] = {0}; + +static unsigned long g_app_queue = 0xFFFFFFFF; + +static char *rx_buffer = NULL; + +static int *tcp_data = NULL; +static int tcp_data_cnt = 0; + +static int g_listen_sock = -1; +static volatile int g_socket_connected = 0; + +static uint8_t LK_STATUS = 0; +static uint8_t WORKSYNC_GET_STATUS = 0; + +static worksync_data_t worksync_data = {0}; + +static char *imei = NULL; + +static uint8_t worksync_measure_type = 0; + +// 激活码 zzzm3K72zxRRLPX2utu5vMZcM269/8/7ZGOHVvONFt7WPAlQT++RJjzzrHj5v5DdlnmeELWI1FUPVJb96/5mOA== + +#define WORKSYNC_ACTIVE_CODE_FILE "/user/system/worksync_active_code.bin" +#define WORKSYNC_REQUEST_CODE_FILE "/user/system/worksync_request_code.bin" +#define WORKSYNC_TOKEN_FILE "/user/system/worksync_token.bin" +#define WROKWNYC_DEVICEID_FILE "/user/system/wrokwnyc_deviceId.bin" +#define WROKWNYC_REQURESTKEY_FILE "/user/system/wrokwnyc_requestKey.bin" + +struct worksync_ipaddr_t +{ + osSemaphoreId_t dns_done_sem; + ip_addr_t ip; +}; + +// 检查socket连接状态 +static int check_socket_connection(void) +{ + if (g_listen_sock < 0 || !g_socket_connected) + { + return 0; + } + + // 检查socket是否仍然有效 + int error = 0; + socklen_t len = sizeof(error); + if (lwip_getsockopt(g_listen_sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) + { + return 0; + } + + return (error == 0); +} + +void worksync_set_measure_type(uint8_t type) +{ + worksync_measure_type = type; +} +void worksync_get_worksync_data(worksync_data_t *data) // 获取数据 +{ + if (data == NULL) + return; + + memcpy_s(data, sizeof(worksync_data_t), &worksync_data, sizeof(worksync_data_t)); +} + +static void worksync_save_request_code(char *reqeust_code, int len) +{ + if (reqeust_code == NULL || len == 0) + return; + + FILE *file = fopen(WORKSYNC_REQUEST_CODE_FILE, "w"); + if (!file) + { + printf("%s open failed\n", WORKSYNC_REQUEST_CODE_FILE); + return; + } + + size_t bytes_written = fwrite(reqeust_code, 1, len, file); + if (bytes_written != len) + printf(" %s fwrite failed\n", WORKSYNC_REQUEST_CODE_FILE); + else + printf("reqeust_code: %s fwrite succed\n", reqeust_code); + + fclose(file); +} + +static void worksync_save_active_code(char *active_code, int len) +{ + if (active_code == NULL || len == 0) + return; + + FILE *file = fopen(WORKSYNC_ACTIVE_CODE_FILE, "w"); + if (!file) + { + printf("%s open failed\n", WORKSYNC_ACTIVE_CODE_FILE); + return; + } + + size_t bytes_written = fwrite(active_code, 1, len, file); + if (bytes_written != len) + printf(" %s fwrite failed\n", WORKSYNC_ACTIVE_CODE_FILE); + else + printf("active_code: %s fwrite succed\n", active_code); + + fclose(file); +} + +static void worksync_get_active_code(char *active_code, int len) +{ + if (active_code == NULL || len == 0) + { + printf("active_code is NULL or len == 0\n"); + return; + } + + char *buffer = (char *)malloc(len); + if (buffer == NULL) + return; + + FILE *file = fopen(WORKSYNC_ACTIVE_CODE_FILE, "r"); + if (!file) + { + printf("open failed: %s\n", WORKSYNC_ACTIVE_CODE_FILE); + return; + } + + memset(buffer, 0, len); + + size_t bytes_read = fread(buffer, 1, len - 1, file); + if (bytes_read > 0) + { + buffer[bytes_read] = '\0'; + printf("active code: %s\n", buffer); + } + else + printf("read active code failed\n"); + + memcpy_s(active_code, bytes_read, buffer, bytes_read); + + free(buffer); + fclose(file); +} + +static void worksync_get_request_code(char *request_code, int len) +{ + if (request_code == NULL || len == 0) + { + printf("request_code is NULL or len == 0\n"); + return; + } + + char *buffer = (char *)malloc(len); + if (buffer == NULL) + return; + + FILE *file = fopen(WORKSYNC_REQUEST_CODE_FILE, "r"); + if (!file) + { + printf("open failed: %s\n", WORKSYNC_REQUEST_CODE_FILE); + return; + } + + // 初始化缓冲区 + memset(buffer, 0, len); + + // 安全读取文件内容(最多len-1字节,留一个位置给\0) + size_t bytes_read = fread(buffer, 1, len - 1, file); + if (bytes_read > 0) + { + buffer[bytes_read] = '\0'; + printf("active code: %s\n", buffer); + } + else + printf("read active code failed\n"); + + memcpy_s(request_code, bytes_read, buffer, bytes_read); + + free(buffer); + fclose(file); +} + +static void worksync_get_token(char *token, int len) +{ + if (token == NULL || len == 0) + { + printf("token is NULL or len == 0\n"); + return; + } + + char *buffer = (char *)malloc(len); + if (buffer == NULL) + return; + + FILE *file = fopen(WORKSYNC_TOKEN_FILE, "r"); + if (!file) + { + printf("open failed: %s\n", WORKSYNC_TOKEN_FILE); + return; + } + + // 初始化缓冲区 + memset(buffer, 0, len); + + // 安全读取文件内容(最多len-1字节,留一个位置给\0) + size_t bytes_read = fread(buffer, 1, len - 1, file); + if (bytes_read > 0) + { + buffer[bytes_read] = '\0'; + printf("worksync_get_token: %s\n", buffer); + } + else + printf("read token failed\n"); + + memcpy_s(token, bytes_read, buffer, bytes_read); + + free(buffer); + fclose(file); +} + +static void worksync_save_token(char *token, int len) +{ + if (token == NULL || len == 0) + return; + + FILE *file = fopen(WORKSYNC_TOKEN_FILE, "w"); + if (!file) + { + printf("%s open failed\n", WORKSYNC_TOKEN_FILE); + return; + } + + size_t bytes_written = fwrite(token, 1, len, file); + if (bytes_written != len) + printf(" %s fwrite failed\n", WORKSYNC_TOKEN_FILE); + else + printf("token: %s fwrite succed\n", token); + + fclose(file); +} + +void worksync_save_deviceId(char *deviceId, int len) // save_deviceId +{ + if (deviceId == NULL || len == 0) + return; + + FILE *file = fopen(WROKWNYC_DEVICEID_FILE, "w"); + if (!file) + { + printf("%s open failed\n", WROKWNYC_DEVICEID_FILE); + return; + } + + size_t bytes_written = fwrite(deviceId, 1, len, file); + if (bytes_written != len) + printf(" %s fwrite failed\n", WROKWNYC_DEVICEID_FILE); + else + printf("deviceId: %s fwrite succed\n", deviceId); + + fclose(file); +} + +void worksync_get_wrokwnyc_deviceId(char *deviceId, int len) // get_deviceId +{ + if (deviceId == NULL || len == 0) + { + printf("deviceId is NULL or len == 0\n"); + return; + } + + char *buffer = (char *)malloc(len); + if (buffer == NULL) + return; + + FILE *file = fopen(WROKWNYC_DEVICEID_FILE, "r"); + if (!file) + { + printf("open failed: %s\n", WROKWNYC_DEVICEID_FILE); + return; + } + + // 初始化缓冲区 + memset(buffer, 0, len); + + // 安全读取文件内容(最多len-1字节,留一个位置给\0) + size_t bytes_read = fread(buffer, 1, len - 1, file); + if (bytes_read > 0) + { + buffer[bytes_read] = '\0'; + printf("deviceId: %s\n", buffer); + } + else + printf("read deviceId failed\n"); + + memcpy_s(deviceId, bytes_read, buffer, bytes_read); + + free(buffer); + fclose(file); +} + +void worksync_save_requestKey(char *requestKey, int len) // save_requestKey +{ + if (requestKey == NULL || len == 0) + return; + + FILE *file = fopen(WROKWNYC_REQURESTKEY_FILE, "w"); + if (!file) + { + printf("%s open failed\n", WROKWNYC_REQURESTKEY_FILE); + return; + } + + size_t bytes_written = fwrite(requestKey, 1, len, file); + if (bytes_written != len) + printf(" %s fwrite failed\n", WROKWNYC_REQURESTKEY_FILE); + else + printf("requestKey: %s fwrite succed\n", requestKey); + + fclose(file); +} + +void worksync_get_wrokwnyc_requestKey(char *requestKey, int len) // get_requestKey +{ + if (requestKey == NULL || len == 0) + { + printf("requestKey is NULL or len == 0\n"); + return; + } + + char *buffer = (char *)malloc(len); + if (buffer == NULL) + return; + + FILE *file = fopen(WROKWNYC_REQURESTKEY_FILE, "r"); + if (!file) + { + printf("open failed: %s\n", WROKWNYC_REQURESTKEY_FILE); + return; + } + + // 初始化缓冲区 + memset(buffer, 0, len); + + // 安全读取文件内容(最多len-1字节,留一个位置给\0) + size_t bytes_read = fread(buffer, 1, len - 1, file); + if (bytes_read > 0) + { + buffer[bytes_read] = '\0'; + printf("requestKey: %s\n", buffer); + } + else + printf("read requestKey failed\n"); + + memcpy_s(requestKey, bytes_read, buffer, bytes_read); + + free(buffer); + fclose(file); +} + +static void dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) +{ + struct worksync_ipaddr_t *ip_sem = (struct worksync_ipaddr_t *)arg; + char ip_str[20] = {0}; + + if (ipaddr == NULL) + { + printf("DNS解析失败,IP地址为空\n"); + if (ip_sem && ip_sem->dns_done_sem) + { + (void)osSemaphoreRelease(ip_sem->dns_done_sem); + } + return; + } + + printf("hostname: %s, ", hostname); + + // 处理IPv4地址(现在ip4是包含addr成员的结构体) + if (IP_IS_V4(ipaddr)) + { + u32_t ip_num = ipaddr->u_addr.ip4.addr; // 直接获取32位地址 + + // 分解为4字节打印 + u8_t byte0 = (ip_num >> 24) & 0xFF; + u8_t byte1 = (ip_num >> 16) & 0xFF; + u8_t byte2 = (ip_num >> 8) & 0xFF; + u8_t byte3 = ip_num & 0xFF; + // printf("IPv4: %d.%d.%d.%d\n", byte0, byte1, byte2, byte3); + + // 转换为struct in_addr(已为网络字节序) + struct in_addr ipv4_addr; + ipv4_addr.s_addr = ip_num; + inet_ntop(AF_INET, &ipv4_addr, ip_str, sizeof(ip_str)); + printf("ip: %s\n", ip_str); + } + + // 复制IP地址到上下文 + if (ipaddr->u_addr.ip4.addr != 0) + { + memcpy(&(ip_sem->ip), ipaddr, sizeof(ip_addr_t)); + } + + if (ip_sem && ip_sem->dns_done_sem) + { + (void)osSemaphoreRelease(ip_sem->dns_done_sem); + } +} + +int worksync_tcp_socket_init(void) +{ + uint8_t cnt = pm_veto_get_id_cnt(PM_ID_CAT1); + if (cnt == 0) + { + uapi_pm_add_sleep_veto(PM_ID_CAT1); + } + + struct sockaddr_in server_addr; + struct worksync_ipaddr_t ip_sem = {0}; // 定义信号量结构 + int listen_socket = -1; + + // 创建信号量 + ip_sem.dns_done_sem = osSemaphoreNew(1, 0, NULL); + if (ip_sem.dns_done_sem == NULL) + { + printf("Failed to create semaphore\n"); + goto FAILED; + } + + // 解析域名 + dns_gethostbyname(SERVER_HOST, &(ip_sem.ip), dns_found, &ip_sem); + + // 等待 DNS 解析完成,增加超时时间 + if (osSemaphoreAcquire(ip_sem.dns_done_sem, 10000) != osOK) + { + printf("DNS resolution timeout\n"); + goto FAILED; + } + + // 检查IP地址是否有效 + if (ip_sem.ip.u_addr.ip4.addr == 0) + { + printf("Invalid IP address after DNS resolution\n"); + goto FAILED; + } + + memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4); + + // 创建套接字 + listen_socket = lwip_socket(AF_INET, SOCK_STREAM, 0); + if (listen_socket < 0) + { + int err = errno; + printf("socket create errno: %d, reason: %s\n", err, strerror(err)); + goto FAILED; + } + + int opt = 1; + + // 设置socket选项 + if (lwip_setsockopt(listen_socket, SOL_SOCKET, SO_KEEPALIVE, (const void *)&opt, sizeof(opt)) < 0) + { + printf("Failed to set SO_KEEPALIVE\n"); + } + if (lwip_setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)) < 0) + { + printf("Failed to set SO_REUSEADDR\n"); + } + + // 设置连接超时 + struct timeval timeout; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + if (lwip_setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) + { + printf("Failed to set SO_RCVTIMEO\n"); + } + if (lwip_setsockopt(listen_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) + { + printf("Failed to set SO_SNDTIMEO\n"); + } + + // 设置服务器地址 + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(SERVER_PORT); + + // 连接服务器 + if (connect(listen_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) + { + printf("server_addr.sin_addr.s_addr:%d\n", server_addr.sin_addr.s_addr); + int err = errno; + printf("connect failed, errno: %d, reason: %s\n", err, strerror(err)); + msleep(100); + goto FAILED; + } + + cnt = pm_veto_get_id_cnt(PM_ID_CAT1); + if (cnt == 1) + { + uapi_pm_remove_sleep_veto(PM_ID_CAT1); + } + + printf("socket init succed\n"); + osSemaphoreDelete(ip_sem.dns_done_sem); // 释放信号量 + + // 设置连接状态 + g_socket_connected = 1; + + return listen_socket; + +FAILED: + if (listen_socket >= 0) + { + lwip_close(listen_socket); + listen_socket = -1; + } + if (ip_sem.dns_done_sem != NULL) + { + osSemaphoreDelete(ip_sem.dns_done_sem); + ip_sem.dns_done_sem = NULL; + } + + // 重置连接状态 + g_socket_connected = 0; + + cnt = pm_veto_get_id_cnt(PM_ID_CAT1); + if (cnt == 1) + { + uapi_pm_remove_sleep_veto(PM_ID_CAT1); + } + return -1; +} + +void tcp_recv_worksync_data_handler(const char *input, int input_len) // 解析接受的数据 +{ + if (input_len < 2 || input[0] != '[' || input[input_len - 1] != ']') + { + printf("解析失败: 格式错误(缺少方括号)\n"); + return; + } + + const char *data = input + 1; + size_t data_len = input_len - 2; + + const char *comma1 = memchr(data, ',', data_len); + const char *comma2 = comma1 ? memchr(comma1 + 1, ',', data_len - (comma1 - data + 1)) : NULL; + + const char *star1 = memchr(data, '*', data_len); + const char *star2 = star1 ? memchr(star1 + 1, '*', data_len - (star1 - data + 1)) : NULL; + const char *star3 = star2 ? memchr(star2 + 1, '*', data_len - (star2 - data + 1)) : NULL; + + if (!star1 || !star2 || !star3) + { + printf("解析失败: 头部格式错误(缺少星号分隔符)\n"); + return; + } + + const char *bid = data; + const char *imei = star1 + 1; + const char *len_str = star2 + 1; + const char *cmd = star3 + 1; + + size_t bid_len = star1 - data; + size_t imei_len = star2 - (star1 + 1); + size_t len_str_len = star3 - (star2 + 1); + size_t cmd_len = data_len - (star3 - data + 1); + + // 打印头部解析结果 + // printf("BID: %.*s\n", (int)bid_len, bid); + // printf("IMEI: %.*s\n", (int)imei_len, imei); + // printf("内容长度: %.*s\n", (int)len_str_len, len_str); + // printf("指令: %.*s\n", (int)cmd_len, cmd); + + // 验证IMEI长度(假设为15位) + if (imei_len != 15) + { + printf("解析失败: IMEI长度应为15位,实际: %zu位\n", imei_len); + return; + } + + uint32_t content_len = 0; + sscanf(len_str, "%x", &content_len); + printf("解析后的内容长度: %u\n", content_len); + + if (comma1 && comma2) + { + size_t status_len = comma2 - (comma1 + 1); + size_t base64_len = data_len - (comma2 - data + 1); + + printf("状态码: %.*s\n", (int)status_len, comma1 + 1); + + if (strncmp(comma1 + 1, "200", status_len) != 0) + { + printf("解析失败: 状态码必须为200,实际: %.*s\n", (int)status_len, comma1 + 1); + return; + } + + size_t decoded_len = (base64_len * 3) / 4 + 1; + unsigned char *decoded_data = malloc(decoded_len); + if (!decoded_data) + { + printf("解析失败: 内存分配失败\n"); + return; + } + + size_t actual_decoded_len = 0; + int ret = mbedtls_base64_decode(decoded_data, decoded_len, &actual_decoded_len, (const unsigned char *)(comma2 + 1), base64_len); + + if (ret != 0) + { + printf("解析失败: Base64解码失败 (错误码: %d)\n", ret); + free(decoded_data); + return; + } + decoded_data[actual_decoded_len] = '\0'; + + cJSON *json_data = cJSON_Parse((const char *)decoded_data); + free(decoded_data); + + if (!json_data) + { + printf("解析失败: JSON解析失败,原始数据: %s\n", decoded_data); + return; + } + + printf("JSON数据: %s\n", cJSON_Print(json_data)); + + cJSON *success = cJSON_GetObjectItem(json_data, "success"); + cJSON *message = cJSON_GetObjectItem(json_data, "message"); + cJSON *code = cJSON_GetObjectItem(json_data, "code"); + cJSON *timestamp = cJSON_GetObjectItem(json_data, "timestamp"); + cJSON *result = cJSON_GetObjectItem(json_data, "result"); + cJSON *appId = cJSON_GetObjectItem(result, "appId"); + cJSON *timestamp_sigin = cJSON_GetObjectItem(result, "timestamp"); + cJSON *sign = cJSON_GetObjectItem(result, "sign"); + cJSON *isBind = cJSON_GetObjectItem(result, "isBind"); + cJSON *requestKey = cJSON_GetObjectItem(result, "requestKey"); // 后续设备请求Key + cJSON *count = cJSON_GetObjectItem(result, "count"); // 任务条数 + cJSON *unitName = cJSON_GetObjectItem(result, "unitName"); // 单位名 + cJSON *userName = cJSON_GetObjectItem(result, "userName"); // 用户名 + cJSON *orgName = cJSON_GetObjectItem(result, "orgName"); // 部门名 + cJSON *telNo = cJSON_GetObjectItem(result, "telNo"); // 电话 + cJSON *registerTime = cJSON_GetObjectItem(result, "registerTime"); // 注册时间 + cJSON *firmName = cJSON_GetObjectItem(result, "firmName"); // 品牌名 + cJSON *deviceId = cJSON_GetObjectItem(result, "deviceId"); // 设备号 + cJSON *serialNumber = cJSON_GetObjectItem(result, "serialNumber"); // 注册时的序列号 + cJSON *address = cJSON_GetObjectItem(result, "address"); // 地址 + cJSON *tasks = cJSON_GetObjectItem(result, "tasks"); + + if (result && strcmp(code->valuestring, "200") != 0) + { + worksync_data.state = 1; // 获取成功 + if (success) + { + printf("结果: %s\n", message->valuestring); + } + + if (appId && timestamp && sign && isBind) // 打卡,上报数据 + { + memcpy_s(worksync_data.appId, sizeof(worksync_data.appId), appId->valuestring, strlen(appId->valuestring)); + printf("appId: %s\n", worksync_data.appId); + + worksync_data.timestamp = timestamp->valuedouble; + printf("timestamp: %lld\n", worksync_data.timestamp); + + memcpy_s(worksync_data.sign, sizeof(worksync_data.sign), sign->valuestring, strlen(sign->valuestring)); + printf("sign: %s\n", worksync_data.sign); + + worksync_data.isBind = isBind->valueint; + printf("isBind: %d\n", worksync_data.isBind); + printf("check_in,report success\n"); + + } + + if (requestKey && deviceId) // 设备注册 + { + printf("requestKey: %d\n", requestKey->valuestring); + memcpy_s(worksync_data.requestKey, sizeof(worksync_data.requestKey), requestKey->valuestring, strlen(requestKey->valuestring)); + + printf("deviceId: %d\n", deviceId->valuestring); + memcpy_s(worksync_data.deviceId, sizeof(worksync_data.deviceId), deviceId->valuestring, strlen(deviceId->valuestring)); + + worksync_save_requestKey(requestKey->valuestring, strlen(requestKey->valuestring)); + worksync_save_deviceId(deviceId->valuestring, strlen(deviceId->valuestring)); + } + + if (firmName && userName && orgName && serialNumber && deviceId) // 设备信息 + { + + memcpy_s(worksync_data.firmName, sizeof(worksync_data.firmName), firmName->valuestring, strlen(firmName->valuestring)); + printf("firmName: %s\n", firmName->valuestring); + + memcpy_s(worksync_data.userName, sizeof(worksync_data.userName), userName->valuestring, strlen(userName->valuestring)); + printf("firmName: %s\n", firmName->valuestring); + + printf("orgName: %s\n", orgName->valuestring); + memcpy_s(worksync_data.orgName, sizeof(worksync_data.orgName), orgName->valuestring, strlen(orgName->valuestring)); + + printf("serialNumber: %s\n", serialNumber->valuestring); + memcpy_s(worksync_data.serialNumber, sizeof(worksync_data.serialNumber), serialNumber->valuestring, strlen(serialNumber->valuestring)); + + printf("deviceId: %s\n", deviceId->valuestring); + memcpy_s(worksync_data.deviceId, sizeof(worksync_data.deviceId), deviceId->valuestring, strlen(deviceId->valuestring)); + } + + if (unitName && userName && orgName && telNo && registerTime) // 个人信息 + { + printf("unitName: %s\n", unitName->valuestring); + memcpy_s(worksync_data.unitName, sizeof(worksync_data.unitName), unitName->valuestring, strlen(unitName->valuestring)); + + printf("userName: %s\n", userName->valuestring); + memcpy_s(worksync_data.userName, sizeof(worksync_data.userName), userName->valuestring, strlen(userName->valuestring)); + + printf("orgName: %s\n", orgName->valuestring); + memcpy_s(worksync_data.orgName, sizeof(worksync_data.orgName), orgName->valuestring, strlen(orgName->valuestring)); + + printf("telNo: %s\n", telNo->valuestring); + memcpy_s(worksync_data.telNo, sizeof(worksync_data.telNo), telNo->valuestring, strlen(telNo->valuestring)); + + printf("registerTime: %s\n", registerTime->valuestring); + memcpy_s(worksync_data.registerTime, sizeof(worksync_data.registerTime), registerTime->valuestring, strlen(registerTime->valuestring)); + } + if (tasks && count) // 任务 + { + worksync_data.count = count->valueint; + printf("tasks 数组长度: %d\n", worksync_data.count); + + for (int i = 0; i < worksync_data.count; i++) + { + cJSON *task_item = cJSON_GetArrayItem(tasks, i); + if (task_item && cJSON_IsObject(task_item)) + { + cJSON *title = cJSON_GetObjectItem(task_item, "title"); + cJSON *content = cJSON_GetObjectItem(task_item, "content"); + cJSON *id = cJSON_GetObjectItem(task_item, "id"); + + printf("任务[%d]\n", i); + if (title && cJSON_IsString(title)) + { + printf("title: %s\n", title->valuestring); + memcpy_s(worksync_data.task[i].title, sizeof(worksync_data.task[i].title), title->valuestring, strlen(title->valuestring)); + } + if (content && cJSON_IsString(content)) + { + printf("content: %s\n", content->valuestring); + memcpy_s(worksync_data.task[i].content, sizeof(worksync_data.task[i].content), content->valuestring, strlen(content->valuestring)); + } + if (id && cJSON_IsString(id)) + { + printf("id: %s\n", id->valuestring); + memcpy_s(worksync_data.task[i].id, sizeof(worksync_data.task[i].id), id->valuestring, strlen(id->valuestring)); + } + } + } + } + if (address) // 地理位置 + { + memcpy_s(worksync_data.address, sizeof(worksync_data.address), address->valuestring, strlen(address->valuestring)); + printf("address: %s\n", worksync_data.address); + } + } + else + { + worksync_data.state = 0; // 获取失败 + printf("失败\n"); + } + + cJSON_Delete(json_data); + } + else + { + // 无逗号或只有一个逗号,仅处理指令 + // printf("格式: 仅指令,无状态码和Base64内容\n"); + printf("指令处理: %.*s\n", (int)cmd_len, cmd); + + // 这里可以添加仅处理指令的逻辑 + // worksync_handle_command(cmd, cmd_len); // 假设存在指令处理函数 + if (strstr(cmd, "LK") != NULL) + { + printf("LK succed\n"); + LK_STATUS = 1; + } + } +} + +static int tcp_send(int listen_socket, const char *data, size_t size) +{ + if (data == NULL || size == 0) + return -1; + + uint8_t retry = 0; + while (listen_socket < 0 && retry < 5) + { + retry++; + LOS_Msleep(2000); + } + + if (listen_socket < 0) + { + printf("listen_socket < 0 \n"); + return -1; + } + + int ret = 0; + + // const char *buffer = (const char *)data; + const char *buffer = (const char *)malloc(size); + if (buffer == NULL) + return -1; + + memcpy_s(buffer, size, (const char *)data, size); + // printf("size : %d\n",size); + // printf("strlen(buffer) : %d\n",strlen(buffer)); + // printf("buffer : %s\n",buffer); + + size_t total_sent = 0; + + while (total_sent < size) + { + ssize_t sent = lwip_send(listen_socket, buffer + total_sent, size - total_sent, 0); + if (sent < 0) + { + printf("errno : %d\n", errno); + // 处理错误情况 + if (errno == EINTR) + { + PRINT("被信号中断,继续尝试\n"); + ret = -1; + continue; + } + else if (errno == EAGAIN || errno == EWOULDBLOCK) + { + PRINT("非阻塞模式下暂时无法发送,可选择等待或返回\n"); + ret = -1; + goto FAILED; + } + else if (errno == ENETUNREACH) + { + PRINT("网络不可达,检查路由或远程主机状态\n"); + ret = -1; + goto FAILED; + } + else + { + PRINT("其他错误(如连接断开)\n"); + ret = -1; + goto FAILED; + } + } + + total_sent += sent; + } + printf("tcp send succed size : %d\n", total_sent); + ret = 0; +FAILED: + + if (buffer != NULL) + { + free(buffer); + buffer = NULL; + } + return ret; +} + +static int active_md5_sign(const char *data, int data_len, char *md5_str) +{ + char md5_buf[16] = {0}; + + char *code_str = (const char *)malloc(data_len); + if (md5_str == NULL) + return -1; + + memcpy_s(code_str, data_len, data, data_len); + mbedtls_md5_context ctx; + + // 初始化MD5上下文 + mbedtls_md5_init(&ctx); + + // 开始计算MD5哈希 + mbedtls_md5_starts(&ctx); + // 更新要计算哈希的数据 + mbedtls_md5_update(&ctx, (const unsigned char *)code_str, data_len); + + // 完成哈希计算 + mbedtls_md5_finish(&ctx, (unsigned char *)md5_buf); + + // printf("md5_buf\r\n"); + // for (int i = 0; i < 16; i++) { + // printf("%02X\n", (uint8_t)md5_buf[i]); + // } + // printf("md5_buf end\r\n"); + + // 清理MD5上下文 + mbedtls_md5_free(&ctx); + for (int i = 0; i < 16; i++) + sprintf(&md5_str[i * 2], "%02x", (uint8_t)md5_buf[i]); + + md5_str[32] = '\0'; + + free(code_str); + + return 0; +} + +static void calculate_md5(const char *input, char *md5_str) +{ + mbedtls_md5_context md5; + unsigned char md5_digest[16] = {0}; + int i; + + // printf("input:%s\n",input); + + mbedtls_md5_init(&md5); + mbedtls_md5_starts(&md5); + mbedtls_md5_update(&md5, (const unsigned char *)input, strlen(input)); + mbedtls_md5_finish(&md5, md5_digest); + mbedtls_md5_free(&md5); + + // 转换为十六进制字符串 + for (i = 0; i < 16; i++) + { + sprintf(md5_str + i * 2, "%02x", md5_digest[i]); + } + md5_str[32] = '\0'; // 确保字符串终止 +} + +int tcp_worksync_sign_up(void) +{ + int ret = 0; + char len_str[5] = {0}; + sprintf(len_str, "%04x", 2); + + // 获取IMEI + if (imei == NULL) + { + + imei = uapi_dev_runtime_get_cat1_imei(); + + if (imei == NULL || strlen(imei) == 0) + { + LOS_Msleep(2000); + imei = uapi_dev_runtime_get_cat1_imei(); + } + + if (imei == NULL || strlen(imei) == 0) + { + printf("IMEI get failed\n"); + ret = -1; + goto FAILED; + } + } + // printf("imei:%s\n", imei); + + // 精确计算head_str长度:BID + * + IMEI + * + len_str + * + LK + \0 + int head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("LK") + 1; + char *head_str = (char *)malloc(head_len); + if (head_str == NULL) + { + printf("tcp_worksync_sign_up head_str malloc failed\n"); + ret = -1; + goto FAILED; + } + + snprintf(head_str, head_len, "%s*%s*%s*LK", BID, imei, len_str); + head_len = strlen(head_str); // 重新计算实际长度 + + char md5_str[33] = {0}; // MD5为32字符+1终止符 + + // 计算code_str长度:head_str + KEY + \0 + int code_len = head_len + strlen(KEY) + 1; + char *code_str = (char *)malloc(code_len); + if (code_str == NULL) + { + printf("code_str malloc failed\n"); + ret = -1; + goto FAILED; + } + + snprintf(code_str, code_len, "%s%s", head_str, KEY); + code_len = strlen(code_str); + + if (active_md5_sign(code_str, code_len, md5_str) != 0) + { + printf("active_md5_sign failed\n"); + ret = -1; + goto FAILED; + } + + // 计算send_str长度:[ + md5_str + head_str + ] + \0 + int send_len = 1 + strlen(md5_str) + strlen(head_str) + 1 + 1; + char *send_str = (char *)malloc(send_len); + if (send_str == NULL) + { + printf("send_str malloc failed\n"); + ret = -1; + goto FAILED; + } + + snprintf(send_str, send_len, "[%s%s]", md5_str, head_str); + send_len = strlen(send_str); + + // 打印调试信息 + // printf("md5_str:%s\n", md5_str); + // printf("md5_len:%zu\n", strlen(md5_str)); + // printf("head_len:%d\n", head_len); + // printf("head_str:%s\n", head_str); + // printf("send_len : %d\n", send_len); + printf("send_str : %s\n", send_str); + + // 发送数据 + ret = tcp_send(g_listen_sock, send_str, send_len); + if (ret != 0) + { + printf("tcp_send failed\n"); + goto FAILED; + } + +FAILED: + // 释放资源 + if (head_str != NULL) + { + free(head_str); + head_str = NULL; + } + if (code_str != NULL) + { + free(code_str); + code_str = NULL; + } + if (send_str != NULL) + { + free(send_str); + send_str = NULL; + } + + return ret; +} + +/** + * 计算cnt个int数据转换为字符串并添加逗号后的Base64编码长度 + * @param cnt int数据个数 + * @return Base64编码后的长度,失败返回-1 + */ +static int calculate_base64_length(int cnt) +{ + if (cnt <= 0) + return -1; + + // 1. 计算int数组转换为字符串的最大可能长度 + // int的最大字符串长度:11个字符(如"-2147483648") + // 每个int后加一个逗号(最后一个int除外) + int str_length = cnt * 11 + (cnt - 1); + + // 2. 计算Base64编码长度 + // Base64编码规则:每3字节明文→4字节编码,不足3字节用'='填充 + int base64_length = (str_length * 4 + 2) / 3; + + // 3. 确保编码长度足够容纳终止符 + base64_length += 1; // 预留终止符空间 + + return base64_length; +} + +int worksync_tcp_login(void) +{ + int ret = -1; + char *data_str = NULL; + int data_len = 0; + char *encode_str = NULL; + int encode_len = 0; + char *head_str = NULL; + int head_len = 0; + char *code_str = NULL; + int code_len = 0; + char *send_str = NULL; + int send_len = 0; + uint32_t output_len = 0; + int temp_len = 0; + + char len_str[5] = {0}; + char md5_str[33] = {0}; + // char json_data[1024] = {0}; + + char *json_data = (char *)malloc(512); + if (json_data == NULL) + goto FAILED; + + memset(json_data, 0, 512); + + char birthday[32] = {0}; + snprintf(birthday, 32, "%d-%d-%d", 2002, 1, 10); + + // 构建JSON数据 + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "{\"app_key\":\"%s\",", APP_KEY); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"account_type\":\"%d\",", 1); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"account\":\"%s\",", "1624952103@qq.com"); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"name\":\"%s\",", "penglei"); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"password\":\"%s\",", "12345678"); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"gender\":\"%d\",", 1); // 性别['1': 男, '2': 女, '3':未知] + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"birthday\":\"%s\",", birthday); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"height\":\"%d\",", 173); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, "\"weight\":\"%d\"}", 100); + + if (temp_len > 512) + goto FAILED; + + printf("temp_len:%d\n", temp_len); + printf("json_data : %s\n", json_data); + printf("json_data_len : %d\n", strlen(json_data)); + + // encode_len = (temp_len * 4 + 2) / 3 + 1; + encode_len = temp_len * 2; + encode_str = (char *)malloc(encode_len); + if (encode_str == NULL) + { + printf("encode_str 分配失败\n"); + goto FAILED; + } + memset(encode_str, 0, encode_len); + + // 执行Base64编码 + mbedtls_base64_encode((unsigned char *)encode_str, encode_len, &output_len, + (const unsigned char *)json_data, strlen(json_data)); + + printf("Base64编码后长度: %d, 输出长度: %d\n", encode_len, (int)output_len); + // 确保Base64编码字符串以NULL结尾 + encode_str[output_len] = '\0'; + printf("encode_str: %s\n", encode_str); + + // 构建content部分 + data_len = 1 + strlen("POST") + 1 + strlen(URL_HEADER) + strlen(LOGIN_URL) + 1 + 1 + output_len + 1; + data_str = (char *)malloc(data_len); + if (data_str == NULL) + { + printf("data_str 分配失败\n"); + goto FAILED; + } + memset(data_str, 0, data_len); + snprintf(data_str, data_len, ",POST,%s%s,,%s", URL_HEADER, LOGIN_URL, encode_str); + + // 计算数据长度并格式化为16进制 + data_len = strlen(data_str); + sprintf(len_str, "%04x", data_len + 8); + + // 计算head_str长度 + head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + // head_len = strlen(BID) + 1 + 15 + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + head_str = (char *)malloc(head_len); + if (head_str == NULL) + { + printf("head_str 分配失败\n"); + goto FAILED; + } + snprintf(head_str, head_len, "%s*%s*%s*TCP_HTTP", BID, imei, len_str); + // snprintf(head_str, head_len, "%s*864430010001091*%s*TCP_HTTP", BID, len_str); + + head_len = strlen(head_str); + + // 计算MD5 + code_len = head_len + strlen(KEY) + 1; + code_str = (char *)malloc(code_len); + if (code_str == NULL) + { + printf("code_str 分配失败\n"); + goto FAILED; + } + snprintf(code_str, code_len, "%s%s", head_str, KEY); + printf("code_str:%s\n", code_str); + printf("code_len:%d\n", code_len); + + calculate_md5(code_str, md5_str); + if (strlen(md5_str) == 0) + { + printf("MD5签名失败\n"); + goto FAILED; + } + // if (active_md5_sign(code_str, code_len, md5_str) != 0) { + // printf("MD5签名失败\n"); + // goto FAILED; + // } + + // 构建发送字符串 + send_len = 1 + strlen(md5_str) + head_len + data_len + 1 + 1; // [ + md5 + head + data + ] + \0 + printf("计算的send_len : %d\n", send_len); + send_str = (char *)malloc(send_len); + if (send_str == NULL) + { + printf("send_str 分配失败\n"); + goto FAILED; + } + snprintf(send_str, send_len, "[%s%s%s]", md5_str, head_str, data_str); + send_len = strlen(send_str); + printf("实际send_len : %d\n", send_len); + + // printf("md5_str:%s\n", md5_str); + // printf("md5_len:%zu\n", strlen(md5_str)); + // printf("head_len:%d\n", head_len); + // printf("head_str:%s\n", head_str); + // printf("data_len:%d\n", data_len); + // printf("data_str:%s\n", data_str); + // printf("send_len : %d\n", send_len); + // printf("send_str : %s\n", send_str); + + // 发送数据 + tcp_send(g_listen_sock, send_str, send_len); + + ret = 0; // 成功 + +FAILED: + if (json_data != NULL) + { + free(json_data); + json_data = NULL; + } + if (send_str != NULL) + { + free(send_str); + send_str = NULL; + } + if (code_str != NULL) + { + free(code_str); + code_str = NULL; + } + if (head_str != NULL) + { + free(head_str); + head_str = NULL; + } + if (data_str != NULL) + { + free(data_str); + data_str = NULL; + } + if (encode_str != NULL) + { + free(encode_str); + encode_str = NULL; + } + + return ret; +} + +unsigned char *compute_hmac_sha256(const char *str_to_sign) +{ + if (str_to_sign == NULL) + { + fprintf(stderr, "Error: str_to_sign is NULL\n"); + return NULL; + } + + // 输出缓冲区 + unsigned char *hmac_result = malloc(32); + if (hmac_result == NULL) + return NULL; + size_t hmac_len = 32; + + // 获取 SHA-256 算法信息 + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (md_info == NULL) + { + fprintf(stderr, "Failed to get SHA-256 algorithm\n"); + goto error; + } + + // 使用标准 HMAC 计算 API + int ret = mbedtls_md_hmac( + md_info, // 算法信息 + (const unsigned char *)APP_KEY, // 密钥 + strlen(APP_KEY), // 密钥长度 + (const unsigned char *)str_to_sign, // 待签名数据 + strlen(str_to_sign), // 数据长度 + hmac_result // 输出结果 + ); + + if (ret != 0) + { + fprintf(stderr, "HMAC calculation failed: %d\n", ret); + goto error; + } + + // 调试输出 + printf("HMAC-SHA256 result (hex): "); + for (int i = 0; i < hmac_len; i++) + { + printf("%02x", hmac_result[i]); + } + printf("\n"); + + return hmac_result; // 成功时返回计算结果 + +error: + if (hmac_result) + { + // mbedtls_zeroize(hmac_result, hmac_len); // 清除敏感数据 + free(hmac_result); + } + return NULL; +} +unsigned char *compute_hmac_sha256_request(const char *str_to_sign, char *key) +{ + if (str_to_sign == NULL) + { + fprintf(stderr, "Error: str_to_sign is NULL\n"); + return NULL; + } + + // 输出缓冲区 + unsigned char *hmac_result = malloc(32); + if (hmac_result == NULL) + return NULL; + size_t hmac_len = 32; + + // 获取 SHA-256 算法信息 + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (md_info == NULL) + { + fprintf(stderr, "Failed to get SHA-256 algorithm\n"); + goto error; + } + + // 使用标准 HMAC 计算 API + int ret = mbedtls_md_hmac( + md_info, // 算法信息 + (const unsigned char *)key, // 密钥 + strlen(key), // 密钥长度 + (const unsigned char *)str_to_sign, // 待签名数据 + strlen(str_to_sign), // 数据长度 + hmac_result // 输出结果 + ); + + if (ret != 0) + { + fprintf(stderr, "HMAC calculation failed: %d\n", ret); + goto error; + } + + // 调试输出 + printf("HMAC-SHA256 result (hex): "); + for (int i = 0; i < hmac_len; i++) + { + printf("%02x", hmac_result[i]); + } + printf("\n"); + + return hmac_result; // 成功时返回计算结果 + +error: + if (hmac_result) + { + // mbedtls_zeroize(hmac_result, hmac_len); // 清除敏感数据 + free(hmac_result); + } + return NULL; +} +int worksync_tcp_Operation(OperationType type) // 发送数据 +{ + int ret = -1; + char *data_str = NULL; + int data_len = 0; + char *encode_str = NULL; + int encode_len = 0; + char *head_str = NULL; + int head_len = 0; + char *code_str = NULL; + int code_len = 0; + char *send_str = NULL; + int send_len = 0; + uint32_t output_len = 0; + int temp_len = 0; + + char len_str[5] = {0}; + char md5_str[33] = {0}; + char deviceId[17] = {0}; // 16+1 + char request_key[33] = {0}; // 32+1 + unsigned char *sign_acpp; + // char json_data[1024] = {0}; + float longitude; + float latitude; + char Longitude[32]; // 足够大的缓冲区 + char Latitude[32]; + char geo_data[64]; + +#if defined(SUPPORT_GNSS) + gps_data_t send_gps_data = {0}; + gps_data_t *gps_data = getPGPSGlobaldata(); + + if (gps_data == NULL) + { + PRINT("gps_data == NULL \n"); + } + + // 判断是否为第一次定位并复制GPS数据 + if (gps_data->last_gps_time_ms > 0) + { + memcpy_s(&send_gps_data, sizeof(gps_data_t), gps_data, sizeof(gps_data_t)); + } + + // 判断是否定位成功并设置连接状态 + bool isGpsConnected = (send_gps_data.status > 1); + if (isGpsConnected) + { + longitude = send_gps_data.location.lng; + latitude = send_gps_data.location.lat; + snprintf(Longitude, sizeof(Longitude), "%f", longitude); + snprintf(Latitude, sizeof(Latitude), "%f", latitude); + snprintf(geo_data, sizeof(geo_data), "%s,%s", Longitude, Latitude); + } + else + { + printf("GpsConnected error"); + } +#endif + + char *json_data = (char *)malloc(512); + if (json_data == NULL) + goto FAILED; + + memset(json_data, 0, 512); + if (uapi_get_timestampe_ss(×tamp) != ERRCODE_SUCC) // 当前时间戳 + { + printf("Failed to get timestamp\n"); + goto FAILED; + } + // printf("timestampss:%d\n", timestamp); + uint64_t multiplied = (uint64_t)timestamp * 1000; + // printf("multiplied:%lld\n", multiplied); + + worksync_get_wrokwnyc_requestKey(request_key, sizeof(request_key)); // 读取request_key + worksync_get_wrokwnyc_deviceId(deviceId, sizeof(deviceId)); // 读取deviceId + printf("request_key:%s\n", request_key); + printf("deviceId:%s\n", deviceId); + sprintf(request_sign, "%s%s%lld", APP_ID, request_key, multiplied); // 拼接后的请求sign + // printf("sign:%s\n", sign); + unsigned char *request_sign_acpp = compute_hmac_sha256_request(request_sign, request_key); // 加密后的请求sign + if (request_sign_acpp == NULL) + { + printf("request_sign_acpp == NULL\n"); + goto FAILED; + } + char hex_requestsignature[65]; // 32*2 + 1 + for (int i = 0; i < 32; i++) + { + sprintf(&hex_requestsignature[i * 2], "%02x", request_sign_acpp[i]); // 请求合并的sign + } + hex_requestsignature[64] = '\0'; + + printf("hex_signature:%s \n", hex_requestsignature); + + char url[256] = {0}; + + switch (type) + { + // 设备注册场景 + case DEVICE_REGISTER: + { + if (imei == NULL) + { + imei = uapi_dev_runtime_get_cat1_imei(); + if (imei == NULL || strlen(imei) == 0) + { + LOS_Msleep(2000); + imei = uapi_dev_runtime_get_cat1_imei(); + } + if (imei == NULL || strlen(imei) == 0) + { + printf("IMEI get failed\n"); + ret = -1; + goto FAILED; + } + } + sprintf(sign, "%s%s%lld", APP_ID, APP_KEY, multiplied); // 拼接后的注册sign + // printf("sign:%s\n", sign); + sign_acpp = compute_hmac_sha256(sign); // 加密后的注册sign + if (sign_acpp == NULL) + { + printf("sign_acpp == NULL\n"); + goto FAILED; + } + char hex_signature[65]; // 32*2 + 1 + for (int i = 0; i < 32; i++) + { + sprintf(&hex_signature[i * 2], "%02x", sign_acpp[i]); // 注册合并的sign + } + hex_signature[64] = '\0'; + + printf("hex_signature:%s \n", hex_signature); + + uint8_t btaddr[6] = {0}; + uint8_t btaddr_str[64] = {0}; + uint32_t len = 6; + ret = uapi_get_nv_btaddr((uint8_t *)btaddr, &len); + sprintf((char *)btaddr_str, "%02X%02X%02X%02X%02X%02X", btaddr[0], btaddr[1], btaddr[2], btaddr[3], btaddr[4], btaddr[5]); + + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"imei\":\"%s\",", imei); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"serialNumber\":\"%s\",", imei); // 序列号(若不存在与imei相同即可) + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceModel\":\"%s\",", " "); // 设备型号(允许为空) + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceNo\":\"%s\",", "15576208806"); // 设备4G卡手机号码 + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"systemSoftwareVersion\":\"%s\",", "OpenHarmony 3.2"); // 系统版本信息 + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"bluetoothMac\":\"%s\",", (char *)btaddr_str); // 蓝牙mac地址 + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"wifiMac\":\"%s\",", (char *)btaddr_str); // wifi mac地址 + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\"}", hex_signature); + strcpy(url, REGISTER_URL); + break; + } + + // 获取设备信息场景 + case GET_DEVICE_INFO: + { + if (imei == NULL) + { + imei = uapi_dev_runtime_get_cat1_imei(); + if (imei == NULL || strlen(imei) == 0) + { + LOS_Msleep(2000); + imei = uapi_dev_runtime_get_cat1_imei(); + } + if (imei == NULL || strlen(imei) == 0) + { + printf("IMEI get failed\n"); + ret = -1; + goto FAILED; + } + } + printf("imei:%s",imei); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\"}", hex_requestsignature); + strcpy(url, DEVICE_URL); + break; + } + + // 获取个人信息场景 + case GET_PERSONAL_INFO: + { + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\"}", hex_requestsignature); + strcpy(url, USER_URL); + break; + } + + // 获取任务列表场景 + case GET_TASK_LIST: + { + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\"}", hex_requestsignature); + strcpy(url, TASK_URL); + break; + } + + // 获取地理位置场景(带经纬度) + case GET_GEOLOCATION: + { + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\",", hex_requestsignature); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"longitude\":\"%s\",", Longitude); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"latitude\":\"%s\"}", Latitude); + strcpy(url, ADRESS_URL); + break; + } + + // 打卡场景 + case CHECK_IN: + { + worksync_data.state = 0; // 清空打卡数据,用于判断打卡结果 + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\",", hex_requestsignature); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"longitude\":\"%s\",", Longitude); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"latitude\":\"%s\"}", Latitude); + strcpy(url, GEO_URL); + break; + } + case SINGLE_DATA_REPORT: + { + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\",", hex_requestsignature); + // temp_len += snprintf(json_data + temp_len, 512 - temp_len, + // "\"code\":\"%s\",", code); + // temp_len += snprintf(json_data + temp_len, 512 - temp_len, + // "\"value\":\"%s\"}", value); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"collectTime\":\"%lld\"}", multiplied); + strcpy(url, DATA_URL); + break; + } + + case BATCH_DATA_REPORT: + { + char *heart_rate = GetReproDataValue(DATA_HEART_RATE); + char *oxygen = GetReproDataValue(DATA_OXYGEN); + char *calorie = GetReproDataValue(DATA_CALORIE); + char *steps = GetReproDataValue(DATA_STEPS); + + // 检查数据有效性 + if (heart_rate == NULL) + heart_rate = "0"; + if (oxygen == NULL) + oxygen = "0"; + if (calorie == NULL) + calorie = "0.0"; + if (steps == NULL) + steps = "0"; +#if defined(SUPPORT_GNSS) + if (geo_data == NULL) + geo_data = "0,0"; +#endif + + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",\"deviceId\":\"%s\",\"timestamp\":%lld,\"datas\":[", + APP_ID, deviceId, multiplied); + + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"code\":\"%s\",\"value\":\"%s\",\"collectTime\":%lld},", + "heart_rate", heart_rate, multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"code\":\"%s\",\"value\":\"%s\",\"collectTime\":%lld},", + "oxygen", oxygen, multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"code\":\"%s\",\"value\":\"%s\",\"collectTime\":%lld},", + "calorie", calorie, multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"code\":\"%s\",\"value\":\"%s\",\"collectTime\":%lld}", + "steps", steps, multiplied); +#if defined(SUPPORT_GNSS) + if (geo_data != NULL) + { + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + ",{\"code\":\"%s\",\"value\":\"%s\",\"collectTime\":%lld}", + "geo_data", geo_data, multiplied); + } +#endif + + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "],\"sign\":\"%s\"}", hex_requestsignature); + strcpy(url, DATAS_URL); + break; + } + } + + if (temp_len > 512) + goto FAILED; + + printf("temp_len:%d\n", temp_len); + printf("json_data : %s\n", json_data); + printf("json_data_len : %d\n", strlen(json_data)); + + // encode_len = (temp_len * 4 + 2) / 3 + 1; + encode_len = temp_len * 2; + encode_str = (char *)malloc(encode_len); + if (encode_str == NULL) + { + printf("encode_str 分配失败\n"); + goto FAILED; + } + memset(encode_str, 0, encode_len); + + // 执行Base64编码 + mbedtls_base64_encode((unsigned char *)encode_str, encode_len, &output_len, + (const unsigned char *)json_data, strlen(json_data)); + + printf("Base64编码后长度: %d, 输出长度: %d\n", encode_len, (int)output_len); + // 确保Base64编码字符串以NULL结尾 + encode_str[output_len] = '\0'; + printf("encode_str: %s\n", encode_str); + + // 构建content部分 + data_len = 1 + strlen("POST") + 1 + strlen(URL_HEADER) + strlen(url) + 1 + 1 + output_len + 1; + data_str = (char *)malloc(data_len); + if (data_str == NULL) + { + printf("data_str 分配失败\n"); + goto FAILED; + } + memset(data_str, 0, data_len); + snprintf(data_str, data_len, ",POST,%s%s,,%s", URL_HEADER, url, encode_str); + + // 计算数据长度并格式化为16进制 + data_len = strlen(data_str); + sprintf(len_str, "%04x", data_len + 8); + + // 计算head_str长度 + head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + // head_len = strlen(BID) + 1 + 15 + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + head_str = (char *)malloc(head_len); + if (head_str == NULL) + { + printf("head_str 分配失败\n"); + goto FAILED; + } + snprintf(head_str, head_len, "%s*%s*%s*TCP_HTTP", BID, imei, len_str); + // snprintf(head_str, head_len, "%s*864430010001091*%s*TCP_HTTP", BID, len_str); + + head_len = strlen(head_str); + + // 计算MD5 + code_len = head_len + strlen(KEY) + 1; + code_str = (char *)malloc(code_len); + if (code_str == NULL) + { + printf("code_str 分配失败\n"); + goto FAILED; + } + snprintf(code_str, code_len, "%s%s", head_str, KEY); + printf("code_str:%s\n", code_str); + printf("code_len:%d\n", code_len); + + calculate_md5(code_str, md5_str); + if (strlen(md5_str) == 0) + { + printf("MD5签名失败\n"); + goto FAILED; + } + // if (active_md5_sign(code_str, code_len, md5_str) != 0) { + // printf("MD5签名失败\n"); + // goto FAILED; + // } + + // 构建发送字符串 + send_len = 1 + strlen(md5_str) + head_len + data_len + 1 + 1; // [ + md5 + head + data + ] + \0 + printf("计算的send_len : %d\n", send_len); + send_str = (char *)malloc(send_len); + if (send_str == NULL) + { + printf("send_str 分配失败\n"); + goto FAILED; + } + snprintf(send_str, send_len, "[%s%s%s]", md5_str, head_str, data_str); + send_len = strlen(send_str); + printf("实际send_len : %d\n", send_len); + + // printf("md5_str:%s\n", md5_str); + // printf("md5_len:%zu\n", strlen(md5_str)); + // printf("head_len:%d\n", head_len); + // printf("head_str:%s\n", head_str); + // printf("data_len:%d\n", data_len); + // printf("data_str:%s\n", data_str); + printf("send_len : %d\n", send_len); + printf("send_str : %s\n", send_str); + + // 发送数据 + tcp_send(g_listen_sock, send_str, send_len); + + ret = 0; // 成功 + +FAILED: + if (sign_acpp != NULL) + { + free(sign_acpp); + sign_acpp = NULL; + } + if (request_sign_acpp != NULL) + { + free(request_sign_acpp); + request_sign_acpp = NULL; + } + if (json_data != NULL) + { + free(json_data); + json_data = NULL; + } + if (send_str != NULL) + { + free(send_str); + send_str = NULL; + } + if (code_str != NULL) + { + free(code_str); + code_str = NULL; + } + if (head_str != NULL) + { + free(head_str); + head_str = NULL; + } + if (data_str != NULL) + { + free(data_str); + data_str = NULL; + } + if (encode_str != NULL) + { + free(encode_str); + encode_str = NULL; + } + + return ret; +} + +void worksync_check_active_code(char *active_code) +{ + char buffer[128] = {0}; + int buffer_size = 128; + FILE *file = fopen(WORKSYNC_ACTIVE_CODE_FILE, "r"); + if (file) + { + memset(buffer, 0, buffer_size); + size_t bytes_read = fread(buffer, 1, buffer_size - 1, file); + if (bytes_read > 0) + { + buffer[bytes_read] = '\0'; + fclose(file); + printf("成功读取文件内容\n"); + memcpy_s(active_code, bytes_read, buffer, bytes_read); + return; + } + else + { + printf("文件为空\n"); + fclose(file); + } + } + else + { + printf("无法打开文件读取(可能不存在): %s\n", WORKSYNC_ACTIVE_CODE_FILE); + } + + fclose(file); +} + +int worksync_tcp_Operation_data(char *type, char *value) // 单数据上报 +{ + int ret = -1; + char *data_str = NULL; + int data_len = 0; + char *encode_str = NULL; + int encode_len = 0; + char *head_str = NULL; + int head_len = 0; + char *code_str = NULL; + int code_len = 0; + char *send_str = NULL; + int send_len = 0; + uint32_t output_len = 0; + int temp_len = 0; + + char len_str[5] = {0}; + char md5_str[33] = {0}; + char deviceId[17] = {0}; // 16+1 + char request_key[33] = {0}; // 32+1 + unsigned char *sign_acpp; + + char *json_data = (char *)malloc(512); + if (json_data == NULL) + goto FAILED; + + memset(json_data, 0, 512); + if (uapi_get_timestampe_ss(×tamp) != ERRCODE_SUCC) // 当前时间戳 + { + printf("Failed to get timestamp\n"); + goto FAILED; + } + // printf("timestampss:%d\n", timestamp); + uint64_t multiplied = (uint64_t)timestamp * 1000; // 毫秒级 + // printf("multiplied:%lld\n", multiplied); + + worksync_get_wrokwnyc_requestKey(request_key, sizeof(request_key)); // 读取request_key + worksync_get_wrokwnyc_deviceId(deviceId, sizeof(deviceId)); // 读取deviceId + printf("request_key:%s\n", request_key); + printf("deviceId:%s\n", deviceId); + sprintf(request_sign, "%s%s%lld", APP_ID, request_key, multiplied); // 拼接后的请求sign + // printf("sign:%s\n", sign); + unsigned char *request_sign_acpp = compute_hmac_sha256_request(request_sign, request_key); // 加密后的请求sign + if (request_sign_acpp == NULL) + { + printf("request_sign_acpp == NULL\n"); + goto FAILED; + } + char hex_requestsignature[65]; // 32*2 + 1 + for (int i = 0; i < 32; i++) + { + sprintf(&hex_requestsignature[i * 2], "%02x", request_sign_acpp[i]); // 请求合并的sign + } + hex_requestsignature[64] = '\0'; + + printf("hex_signature:%s \n", hex_requestsignature); + + char url[256] = {0}; + + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",", APP_ID); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"deviceId\":\"%s\",", deviceId); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"timestamp\":\"%lld\",", multiplied); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"sign\":\"%s\",", hex_requestsignature); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"code\":\"%s\",", type); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"value\":\"%s\"}", value); + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "\"collectTime\":\"%lld\"}", multiplied); + strcpy(url, DATA_URL); + + if (temp_len > 512) + goto FAILED; + + printf("temp_len:%d\n", temp_len); + printf("json_data : %s\n", json_data); + printf("json_data_len : %d\n", strlen(json_data)); + + // encode_len = (temp_len * 4 + 2) / 3 + 1; + encode_len = temp_len * 2; + encode_str = (char *)malloc(encode_len); + if (encode_str == NULL) + { + printf("encode_str 分配失败\n"); + goto FAILED; + } + memset(encode_str, 0, encode_len); + + // 执行Base64编码 + mbedtls_base64_encode((unsigned char *)encode_str, encode_len, &output_len, + (const unsigned char *)json_data, strlen(json_data)); + + printf("Base64编码后长度: %d, 输出长度: %d\n", encode_len, (int)output_len); + // 确保Base64编码字符串以NULL结尾 + encode_str[output_len] = '\0'; + printf("encode_str: %s\n", encode_str); + + // 构建content部分 + data_len = 1 + strlen("POST") + 1 + strlen(URL_HEADER) + strlen(url) + 1 + 1 + output_len + 1; + data_str = (char *)malloc(data_len); + if (data_str == NULL) + { + printf("data_str 分配失败\n"); + goto FAILED; + } + memset(data_str, 0, data_len); + snprintf(data_str, data_len, ",POST,%s%s,,%s", URL_HEADER, url, encode_str); + + // 计算数据长度并格式化为16进制 + data_len = strlen(data_str); + sprintf(len_str, "%04x", data_len + 8); + + // 计算head_str长度 + head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + // head_len = strlen(BID) + 1 + 15 + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + head_str = (char *)malloc(head_len); + if (head_str == NULL) + { + printf("head_str 分配失败\n"); + goto FAILED; + } + snprintf(head_str, head_len, "%s*%s*%s*TCP_HTTP", BID, imei, len_str); + // snprintf(head_str, head_len, "%s*864430010001091*%s*TCP_HTTP", BID, len_str); + + head_len = strlen(head_str); + + // 计算MD5 + code_len = head_len + strlen(KEY) + 1; + code_str = (char *)malloc(code_len); + if (code_str == NULL) + { + printf("code_str 分配失败\n"); + goto FAILED; + } + snprintf(code_str, code_len, "%s%s", head_str, KEY); + printf("code_str:%s\n", code_str); + printf("code_len:%d\n", code_len); + + calculate_md5(code_str, md5_str); + if (strlen(md5_str) == 0) + { + printf("MD5签名失败\n"); + goto FAILED; + } + // if (active_md5_sign(code_str, code_len, md5_str) != 0) { + // printf("MD5签名失败\n"); + // goto FAILED; + // } + + // 构建发送字符串 + send_len = 1 + strlen(md5_str) + head_len + data_len + 1 + 1; // [ + md5 + head + data + ] + \0 + printf("计算的send_len : %d\n", send_len); + send_str = (char *)malloc(send_len); + if (send_str == NULL) + { + printf("send_str 分配失败\n"); + goto FAILED; + } + snprintf(send_str, send_len, "[%s%s%s]", md5_str, head_str, data_str); + send_len = strlen(send_str); + printf("实际send_len : %d\n", send_len); + + // printf("md5_str:%s\n", md5_str); + // printf("md5_len:%zu\n", strlen(md5_str)); + // printf("head_len:%d\n", head_len); + // printf("head_str:%s\n", head_str); + // printf("data_len:%d\n", data_len); + // printf("data_str:%s\n", data_str); + printf("send_len : %d\n", send_len); + printf("send_str : %s\n", send_str); + + // 发送数据 + tcp_send(g_listen_sock, send_str, send_len); + + ret = 0; // 成功 + +FAILED: + if (sign_acpp != NULL) + { + free(sign_acpp); + sign_acpp = NULL; + } + if (request_sign_acpp != NULL) + { + free(request_sign_acpp); + request_sign_acpp = NULL; + } + if (json_data != NULL) + { + free(json_data); + json_data = NULL; + } + if (send_str != NULL) + { + free(send_str); + send_str = NULL; + } + if (code_str != NULL) + { + free(code_str); + code_str = NULL; + } + if (head_str != NULL) + { + free(head_str); + head_str = NULL; + } + if (data_str != NULL) + { + free(data_str); + data_str = NULL; + } + if (encode_str != NULL) + { + free(encode_str); + encode_str = NULL; + } + + return ret; +} + +int worksync_tcp_Operation_datas(reprotdata *data, int len) // 批量数据上报 +{ + int ret = -1; + char *data_str = NULL; + int data_len = 0; + char *encode_str = NULL; + int encode_len = 0; + char *head_str = NULL; + int head_len = 0; + char *code_str = NULL; + int code_len = 0; + char *send_str = NULL; + int send_len = 0; + uint32_t output_len = 0; + int temp_len = 0; + + char len_str[5] = {0}; + char md5_str[33] = {0}; + char deviceId[17] = {0}; // 16+1 + char request_key[33] = {0}; // 32+1 + unsigned char *sign_acpp; + // char json_data[1024] = {0}; + + char *json_data = (char *)malloc(512); + if (json_data == NULL) + goto FAILED; + + memset(json_data, 0, 512); + if (uapi_get_timestampe_ss(×tamp) != ERRCODE_SUCC) // 当前时间戳 + { + printf("Failed to get timestamp\n"); + goto FAILED; + } + // printf("timestampss:%d\n", timestamp); + uint64_t multiplied = (uint64_t)timestamp * 1000; + // printf("multiplied:%lld\n", multiplied); + + worksync_get_wrokwnyc_requestKey(request_key, sizeof(request_key)); // 读取request_key + worksync_get_wrokwnyc_deviceId(deviceId, sizeof(deviceId)); // 读取deviceId + printf("request_key:%s\n", request_key); + printf("deviceId:%s\n", deviceId); + sprintf(request_sign, "%s%s%lld", APP_ID, request_key, multiplied); // 拼接后的请求sign + // printf("sign:%s\n", sign); + unsigned char *request_sign_acpp = compute_hmac_sha256_request(request_sign, request_key); // 加密后的请求sign + if (request_sign_acpp == NULL) + { + printf("request_sign_acpp == NULL\n"); + goto FAILED; + } + char hex_requestsignature[65]; // 32*2 + 1 + for (int i = 0; i < 32; i++) + { + sprintf(&hex_requestsignature[i * 2], "%02x", request_sign_acpp[i]); // 请求合并的sign + } + hex_requestsignature[64] = '\0'; + + printf("hex_signature:%s \n", hex_requestsignature); + + char url[256] = {0}; + + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"appId\":\"%s\",\"deviceId\":\"%s\",\"timestamp\":%lld,\"datas\":[", + APP_ID, deviceId, multiplied); + for (int i = 0; i < len; i++) + { + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + "{\"code\":\"%s\",\"value\":\"%s\",\"collectTime\":%lld}", + data[i].code, data[i].value, multiplied); + } + temp_len += snprintf(json_data + temp_len, 512 - temp_len, + ",\"sign\":\"%s\"}", hex_requestsignature); + strcpy(url, DATAS_URL); + + if (temp_len > 512) + goto FAILED; + + printf("temp_len:%d\n", temp_len); + printf("json_data : %s\n", json_data); + printf("json_data_len : %d\n", strlen(json_data)); + + // encode_len = (temp_len * 4 + 2) / 3 + 1; + encode_len = temp_len * 2; + encode_str = (char *)malloc(encode_len); + if (encode_str == NULL) + { + printf("encode_str 分配失败\n"); + goto FAILED; + } + memset(encode_str, 0, encode_len); + + // 执行Base64编码 + mbedtls_base64_encode((unsigned char *)encode_str, encode_len, &output_len, + (const unsigned char *)json_data, strlen(json_data)); + + printf("Base64编码后长度: %d, 输出长度: %d\n", encode_len, (int)output_len); + // 确保Base64编码字符串以NULL结尾 + encode_str[output_len] = '\0'; + printf("encode_str: %s\n", encode_str); + + // 构建content部分 + data_len = 1 + strlen("POST") + 1 + strlen(URL_HEADER) + strlen(url) + 1 + 1 + output_len + 1; + data_str = (char *)malloc(data_len); + if (data_str == NULL) + { + printf("data_str 分配失败\n"); + goto FAILED; + } + memset(data_str, 0, data_len); + snprintf(data_str, data_len, ",POST,%s%s,,%s", URL_HEADER, url, encode_str); + + // 计算数据长度并格式化为16进制 + data_len = strlen(data_str); + sprintf(len_str, "%04x", data_len + 8); + + // 计算head_str长度 + head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + // head_len = strlen(BID) + 1 + 15 + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1; + head_str = (char *)malloc(head_len); + if (head_str == NULL) + { + printf("head_str 分配失败\n"); + goto FAILED; + } + snprintf(head_str, head_len, "%s*%s*%s*TCP_HTTP", BID, imei, len_str); + // snprintf(head_str, head_len, "%s*864430010001091*%s*TCP_HTTP", BID, len_str); + + head_len = strlen(head_str); + + // 计算MD5 + code_len = head_len + strlen(KEY) + 1; + code_str = (char *)malloc(code_len); + if (code_str == NULL) + { + printf("code_str 分配失败\n"); + goto FAILED; + } + snprintf(code_str, code_len, "%s%s", head_str, KEY); + printf("code_str:%s\n", code_str); + printf("code_len:%d\n", code_len); + + calculate_md5(code_str, md5_str); + if (strlen(md5_str) == 0) + { + printf("MD5签名失败\n"); + goto FAILED; + } + // if (active_md5_sign(code_str, code_len, md5_str) != 0) { + // printf("MD5签名失败\n"); + // goto FAILED; + // } + + // 构建发送字符串 + send_len = 1 + strlen(md5_str) + head_len + data_len + 1 + 1; // [ + md5 + head + data + ] + \0 + printf("计算的send_len : %d\n", send_len); + send_str = (char *)malloc(send_len); + if (send_str == NULL) + { + printf("send_str 分配失败\n"); + goto FAILED; + } + snprintf(send_str, send_len, "[%s%s%s]", md5_str, head_str, data_str); + send_len = strlen(send_str); + printf("实际send_len : %d\n", send_len); + + // printf("md5_str:%s\n", md5_str); + // printf("md5_len:%zu\n", strlen(md5_str)); + // printf("head_len:%d\n", head_len); + // printf("head_str:%s\n", head_str); + // printf("data_len:%d\n", data_len); + // printf("data_str:%s\n", data_str); + printf("send_len : %d\n", send_len); + printf("send_str : %s\n", send_str); + + // 发送数据 + tcp_send(g_listen_sock, send_str, send_len); + + ret = 0; // 成功 + +FAILED: + if (sign_acpp != NULL) + { + free(sign_acpp); + sign_acpp = NULL; + } + if (request_sign_acpp != NULL) + { + free(request_sign_acpp); + request_sign_acpp = NULL; + } + if (json_data != NULL) + { + free(json_data); + json_data = NULL; + } + if (send_str != NULL) + { + free(send_str); + send_str = NULL; + } + if (code_str != NULL) + { + free(code_str); + code_str = NULL; + } + if (head_str != NULL) + { + free(head_str); + head_str = NULL; + } + if (data_str != NULL) + { + free(data_str); + data_str = NULL; + } + if (encode_str != NULL) + { + free(encode_str); + encode_str = NULL; + } + + return ret; +} +void worksync_tcp_data_clean(void) +{ + memset(&worksync_data, 0, sizeof(worksync_data)); + if (tcp_data != NULL) + { + free(tcp_data); + tcp_data = NULL; + tcp_data_cnt = 0; + } + // if (g_listen_sock >= 0) + // { + // lwip_close(g_listen_sock); + // g_listen_sock = -1; + // } + WORKSYNC_GET_STATUS = 0; +} + +void do_worksync_tcp_server_send_data(int cmd, int *data, uint32_t len) +{ + if ((data == NULL || len == 0) && cmd == WORKSYNC_TCP_SERVICE_CMD_SEND_DATA) + return; + + errcode_t ret; + worksync_tcp_data_mail_t send_data = {0}; + send_data.cmd = cmd; + if (len && data) + { + send_data.len = len; + send_data.data = (int *)malloc(len * sizeof(int)); + if (send_data.data == NULL) + { + PRINT("malloc failed\n"); + return; + } + memcpy_s(send_data.data, len * sizeof(int), data, len * sizeof(int)); + } + + uint32_t send_len = sizeof(send_data); + + ret = osal_msg_queue_write_copy(g_app_queue, (void *)&send_data, + send_len, 0); + if (ret != OSAL_SUCCESS) + { + PRINT("Error worksync Check MSG 0x send failed! err=0x%x! \r\n", ret); + } + + // if(send_data.data != NULL) + // free(send_data.data); +} + +// unsigned char buf[14100] = {0}; // 算法库计算过程中所需要的缓存 + +// int activate_algorithm(const unsigned char req_code[], const unsigned int req_code_len,const unsigned char key_code[], const unsigned int key_code_len); +void worksync_activate_algorithm(void) +{ +#if 0 + char req_code[128] = {0}; + char active_code[128] = {0}; + worksync_get_request_code(req_code,128); + worksync_get_active_code(active_code,128); + if(strlen(req_code) == 0 || strlen(active_code) == 0) + { + printf("read req_code or active_code failed\n"); + return; + } + int ret = activate_algorithm((const unsigned char*)req_code,strlen(req_code),(const unsigned char*)active_code,strlen(active_code)); + printf("activate_algorithm ret : %d\n",ret); + if(ret == 1) + { + printf("activate_algorithm succed\n"); + } + ret = init_algorithm(buf, 8000); + printf("init_algorithm ret:%d\n",ret); + if(ret == 0) + { + printf("init_algorithm succed\n"); + } +#endif +} + +static void worksync_tcp_deinit(void) +{ + printf("worksync_tcp_deinit \n"); + if (g_listen_sock >= 0) + { + lwip_close(g_listen_sock); + g_listen_sock = -1; + } +} + +int worksync_tcp_init(void) +{ + + if (tcp_worksync_sign_up() != 0) + { + printf("tcp_worksync_sign_up failed\n"); + return -1; + } + + // if(LK_STATUS == 0 ) + // { + // printf("LK failed\n"); + // return -1; + // } + return 0; +} + +static void tcp_data_handler(int *data, int len) +{ + if (tcp_data == NULL) + { + tcp_data = (int *)malloc(MAX_CNT * sizeof(int)); + if (tcp_data == NULL) + { + PRINT("malloc failed\n"); + return; + } + } + + if (LK_STATUS != 1 && g_listen_sock > 0) + { + worksync_tcp_init(); + } + + if (tcp_data_cnt >= MAX_CNT) + { + return; + // printf("tcp_data_cnt : %d\n",tcp_data_cnt); + // worksync_stop(); + // for(int i = 0; i < tcp_data_cnt; i ++) + // { + // printf("data[%d]:%d\n",i,tcp_data[i]); + // } + // memset((void*)tcp_data,0,MAX_CNT * sizeof(int)); + // LOS_Msleep(1000); + + // if(LK_STATUS == 1) + // { + // upload_worksync_data(tcp_data,tcp_data_cnt); + // // do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_WORKSYNC_TEST, NULL, 0); + // } + + // else + // printf("NOT LK\n"); + + // LOS_Msleep(2000); + // worksync_tcp_data_clean(); + } + else + { + printf("tcp_data_cnt:%d\n", tcp_data_cnt); + memcpy_s(tcp_data + tcp_data_cnt, (MAX_CNT - tcp_data_cnt) * sizeof(int), data, len * sizeof(int)); + + // for(int i = tcp_data_cnt; i < tcp_data_cnt+len; i ++) + // { + // printf("222data[%d]:%d\n",i,tcp_data[i]); + // } + + tcp_data_cnt += len; + } +} + +static void worksync_tcp_server_send_task(void const *arg) +{ + printf("worksync_tcp_server_send_task begin\n"); + unused(arg); + errcode_t ret; + + worksync_tcp_data_mail_t mail = {0}; + uint32_t msgsize = sizeof(worksync_tcp_data_mail_t); + + while (1) + { + ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize, + OSAL_MSGQ_WAIT_FOREVER); + if (ret != OSAL_SUCCESS) + { + continue; + } + + if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_SEND_DATA) + { + tcp_data_handler((int *)mail.data, mail.len); + if (mail.data != NULL) + { + free(mail.data); + } + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_SERVER_INIT) + { + worksync_tcp_init(); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_SERVER_DEINIT) + { + worksync_tcp_deinit(); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_DATA_UPLOAD) + { + // upload_worksync_data(); + worksync_tcp_data_clean(); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_REGISTER) // 注册 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_REGISTER\n"); + worksync_tcp_Operation(DEVICE_REGISTER); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_GET_DEVICE) // 获取设备信息 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_GET_DEVICE\n"); + worksync_tcp_Operation(GET_DEVICE_INFO); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_GET_PERSONAL) // 获取个人信息 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_GET_PERSONAL\n"); + worksync_tcp_Operation(GET_PERSONAL_INFO); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_GET_TASK) // 获取任务列表 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_GET_TASK\n"); + worksync_tcp_Operation(GET_TASK_LIST); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_GET_GEOLOCATION) // 获取地理位置 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_GET_GEOLOCATION\n"); + worksync_tcp_Operation(GET_GEOLOCATION); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_CHECK_IN) // 打卡 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_CHECK_IN\n"); + worksync_tcp_Operation(CHECK_IN); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_SINGAL_DATA) // 单数据上报 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_SINGAL_DATA\n"); + worksync_tcp_Operation(SINGLE_DATA_REPORT); + } + else if (mail.cmd == WORKSYNC_TCP_SERVICE_CMD_BATCH_DATA) // 多数据上报 + { + printf("cmd = WORKSYNC_TCP_SERVICE_CMD_BATCH_DATA\n"); + worksync_tcp_Operation(BATCH_DATA_REPORT); + } + } +} + +void worksync_tcp_server_recv_task(void *pvParameters) +{ + // 使用堆内存而不是栈内存,避免栈溢出 + char *rx_buffer = (char *)malloc(2048); + if (rx_buffer == NULL) + { + PRINT("rx_buffer malloc failed\n"); + return; + } + + while (1) + { + // if(!uapi_dev_runtime_get_worksync_status_flag()) + // { + // LOS_Msleep(1000); + // continue; + // } + if (!uapi_cat1_get_power_stat()) + { + PRINT("wating cat1 power on\n"); + LOS_Msleep(2000); + continue; + } + if (g_listen_sock < 0) + { + g_listen_sock = worksync_tcp_socket_init(); + if (g_listen_sock < 0) + { + PRINT("wating tcp socket init\n"); + LOS_Msleep(1000); + continue; + } + else + do_worksync_tcp_server_send_data(WORKSYNC_TCP_SERVICE_CMD_SERVER_INIT, NULL, 0); + } + + // if (tcp_socket_init() != 0) + // { + // PRINT("wating tcp socket init\n"); + // LOS_Msleep(100); + // continue; + // } + + // PRINT("tcp socket init succed\n"); + + // get_active_code(); + // if(tcp_sign_up() != 0) + // { + // LOS_Msleep(1000); + // continue; + // } + + // printf("tcp_sign_up\n"); + + // 检查socket是否有效 + if (g_listen_sock < 0) + { + PRINT("invalid socket, retrying...\n"); + LOS_Msleep(2000); + continue; + } + + // 检查网络连接状态 + if (!uapi_cat1_get_power_stat()) + { + PRINT("waiting cat1 power on\n"); + LOS_Msleep(2000); + continue; + } + + // 检查socket连接状态 + if (!check_socket_connection()) + { + PRINT("socket connection lost, reinitializing...\n"); + if (g_listen_sock >= 0) + { + lwip_close(g_listen_sock); + g_listen_sock = -1; + } + g_socket_connected = 0; + LOS_Msleep(1000); + continue; + } + + // 接收数据 + memset(rx_buffer, 0, 2048); + int len = recv(g_listen_sock, rx_buffer, 2048 - 1, 0); + if (len > 0) + { + rx_buffer[len] = '\0'; + printf("Received %d bytes: %s\n", len, rx_buffer); + // 可能存在粘包: 多个以[]包裹的帧 + char *cursor = rx_buffer; + while (cursor < rx_buffer + len) + { + // 找到下一帧的起始'[' + char *start = strchr(cursor, '['); + if (start == NULL) + { + break; + } + // 找到对应的']' + char *end = strchr(start, ']'); + if (end == NULL) + { + // 不完整帧,留待下次 + break; + } + int frame_len = (int)(end - start + 1); + tcp_recv_worksync_data_handler(start, frame_len); + cursor = end + 1; + } + // 解析数据 + + // tcp_data_parse(rx_buffer, len); + } + else if (len < 0) + { + // 处理接收错误 + int err = errno; + PRINT("recv error, errno: %d, reason: %s\n", err, strerror(err)); + + // 如果是连接断开,重新初始化socket + if (err == ECONNRESET || err == ENOTCONN || err == EPIPE) + { + PRINT("Connection lost, reinitializing socket...\n"); + if (g_listen_sock >= 0) + { + lwip_close(g_listen_sock); + g_listen_sock = -1; + } + g_socket_connected = 0; + } + + LOS_Msleep(2000); + continue; + } + + // 关闭客户端连接 + // close(g_listen_sock); + } + + // 清理资源 + if (rx_buffer != NULL) + { + free(rx_buffer); + rx_buffer = NULL; + } + + // 关闭监听套接字 + // close(g_listen_sock); +} + +void create_worksync_tcp_queue(void) +{ + + if (osal_msg_queue_create("worksync_tcp_service_queue", 24, &g_app_queue, + 0, sizeof(worksync_tcp_data_mail_t)) != ERRCODE_SUCC) + { + PRINT("[worksync][service] app create mail fail\n"); + } +} + +#define WORKSYNC_TCP_BOARD_TASK_SIZE 0x2000 +errcode_t uapi_worksync_tcp_server_init(void) +{ + PRINT("uapi_worksync_tcp_server_init !\r\n"); + + app_task_definition_t taskcfg = {0}; + taskcfg.create_queue_handle = create_worksync_tcp_queue; + taskcfg.attr.name = "worksync_tcp_server_send_task"; + taskcfg.attr.priority = osPriorityNormal; + taskcfg.attr.stack_size = WORKSYNC_TCP_BOARD_TASK_SIZE; + taskcfg.func = worksync_tcp_server_send_task; + taskcfg.use_mem = USE_EXTEND_MEM; + + errcode_t ret = uapi_create_osThread_custom(&taskcfg); + if (ret != ERRCODE_SUCC) + { + PRINT("create worksync_send_service failed %d!\r\n", ret); + return ERRCODE_FAIL; + } + + memset(&taskcfg, 0, sizeof(taskcfg)); + + taskcfg.create_queue_handle = NULL; + taskcfg.attr.name = "worksync_tcp_server_recv_task"; + taskcfg.attr.priority = osPriorityNormal1; + taskcfg.attr.stack_size = WORKSYNC_TCP_BOARD_TASK_SIZE; + taskcfg.func = worksync_tcp_server_recv_task; + taskcfg.use_mem = USE_EXTEND_MEM; + + ret = uapi_create_osThread_custom(&taskcfg); + if (ret != ERRCODE_SUCC) + { + PRINT("create worksync_recv_service failed %d!\r\n", ret); + return ERRCODE_FAIL; + } + + // g_worksync_service_timer = osTimerNew((osTimerFunc_t)worksync_service_check_timer_callback, osTimerPeriodic, NULL, NULL); + + return ERRCODE_SUCC; +} diff --git a/code/sdk/drivers/peripheral/worksync/service/worksync_tcp_server.h b/code/sdk/drivers/peripheral/worksync/service/worksync_tcp_server.h new file mode 100644 index 000000000..e42600905 --- /dev/null +++ b/code/sdk/drivers/peripheral/worksync/service/worksync_tcp_server.h @@ -0,0 +1,119 @@ +/* + * @Author: penglei 1624952103@qq.com + * @Date: 2025-02-14 10:30:32 + * @LastEditors: penglei 1624952103@qq.com + * @LastEditTime: 2025-07-07 16:10:14 + * @FilePath: /sdk615/code/sdk/zhihui/drivers/worksync/service/worksync_ble_service.h + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ + +#ifndef _WORKSYNC_TCP_SERVER_H_ +#define _WORKSYNC_TCP_SERVER_H_ + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#include "stdint.h" +#include "errcode.h" + +typedef struct { + int cmd; + int *data; + uint32_t len; +} worksync_tcp_data_mail_t; + +typedef enum { + DEVICE_REGISTER, // 设备注册 + GET_DEVICE_INFO, // 获取设备信息 + GET_PERSONAL_INFO, // 获取个人信息 + GET_TASK_LIST, // 获取任务列表 + GET_GEOLOCATION, // 获取地理位置 + CHECK_IN, // 打卡 + SINGLE_DATA_REPORT, // 单体数据上报 + BATCH_DATA_REPORT // 批量数据上报 +} OperationType; + + +typedef struct +{ + char title[20]; + char content[255]; + char id[20]; +}task; + +typedef struct { + char code[12]; // 数据标识 + char value[40]; // 数据值 +}reprotdata; + +#pragma pack(1) +typedef struct +{ + char appId[20]; // 应用ID,长度16+1 + long long timestamp; // 时间戳,数值类型 + char sign[65]; // 签名,长度64+1 + char requestKey[40]; // 请求密钥,长度32+1 + char deviceId[20]; // 设备ID,长度16+1 unitName + char firmName[20]; // 品牌名 + char unitName[20]; // 单位名 + char userName[20]; // 用户名 + char orgName[20]; // 部门名 + char serialNumber[20]; + bool isBind; + char telNo[20]; + char registerTime[20]; + char address[60]; + task task[20]; //任务列表 + int count; + int state; //状态 + +} worksync_data_t; +#pragma pack() + + +#define WORKSYNC_TCP_SERVICE_CMD_DATA_UPLOAD 0x1 +#define WORKSYNC_TCP_SERVICE_CMD_SERVER_INIT 0x2 +#define WORKSYNC_TCP_SERVICE_CMD_SERVER_DEINIT 0x3 +#define WORKSYNC_TCP_SERVICE_CMD_SEND_DATA 0x4 +#define WORKSYNC_TCP_SERVICE_CMD_REGISTER 0x5 +#define WORKSYNC_TCP_SERVICE_CMD_GET_DEVICE 0x6 +#define WORKSYNC_TCP_SERVICE_CMD_GET_PERSONAL 0x7 +#define WORKSYNC_TCP_SERVICE_CMD_GET_TASK 0x8 +#define WORKSYNC_TCP_SERVICE_CMD_GET_GEOLOCATION 0x9 +#define WORKSYNC_TCP_SERVICE_CMD_CHECK_IN 0xA +#define WORKSYNC_TCP_SERVICE_CMD_SINGAL_DATA 0xB +#define WORKSYNC_TCP_SERVICE_CMD_BATCH_DATA 0xC + +void worksync_save_deviceId(char *deviceId, int len); // save_deviceId +void worksync_get_wrokwnyc_deviceId(char *deviceId, int len); // get_deviceId +void worksync_save_requestKey(char *requestKey, int len); // save_requestKey +void worksync_get_wrokwnyc_requestKey(char *requestKey, int len); // get_requestKey + +void do_worksync_tcp_server_send_data(int cmd,int *data,uint32_t len); +void tcp_recv_worksync_data_handler(const char *input, int input_len) ; +void worksync_tcp_data_clean(void); +void test_algorithm(void); +int tcp_worksync_sign_up(void); +int worksync_tcp_login(void); +void worksync_check_active_code(char *active_code); +int worksync_tcp_Operation(OperationType); +int worksync_tcp_Operation_data(char *type, char *value); +int worksync_tcp_Operation_datas(reprotdata *data, int len); +void worksync_activate_algorithm(void); +void worksync_get_worksync_data(worksync_data_t *data); +void worksync_set_measure_type(uint8_t type); + +void worksync_set_adjust_data(int sworksync,int dworksync); +int worksync_tcp_init(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file