--- /dev/null
+#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 <dirent.h>
+#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 <lwip/netdb.h>
+#include <errno.h>
+// #include <netinet/in.h>
+#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;
+}