From b41dca605d8c6e1bb3a20b05bcf3b5601ab84747 Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Mon, 1 Sep 2025 11:49:57 +0800 Subject: [PATCH] =?utf8?q?1.=E9=9B=B7=E9=B8=9F=E5=8D=8F=E8=AE=AE=E8=AE=BE?= =?utf8?q?=E5=A4=87=E7=AB=AFat=E6=9C=8D=E5=8A=A1=E6=90=AD=E5=BB=BA?= =?utf8?q?=EF=BC=8C=E7=9B=AE=E5=89=8D=E6=98=AF=E6=B5=8B=E8=AF=95=E9=98=B6?= =?utf8?q?=E6=AE=B5=EF=BC=8C=E6=9C=8D=E5=8A=A1=E9=BB=98=E8=AE=A4=E4=B8=8D?= =?utf8?q?=E5=BC=80=E5=90=AF=202.=E9=9B=B7=E9=B8=9F=E5=8D=8F=E8=AE=AE?= =?utf8?q?=E9=AA=8C=E8=AF=81=EF=BC=9A1.=E8=8E=B7=E5=8F=96=E8=AE=BE?= =?utf8?q?=E5=A4=87Token=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=B7=B2=E9=AA=8C?= =?utf8?q?=E8=AF=81=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt | 2 + .../zhihui/leiniao/imsl_ln/leiniao_api_at.c | 190 ++------- code/sdk/zhihui/leiniao/imsl_ln/ln_api.c | 373 ++++++++++++++++++ code/sdk/zhihui/leiniao/imsl_ln/ln_api.h | 38 ++ 4 files changed, 440 insertions(+), 163 deletions(-) create mode 100644 code/sdk/zhihui/leiniao/imsl_ln/ln_api.c create mode 100644 code/sdk/zhihui/leiniao/imsl_ln/ln_api.h diff --git a/code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt b/code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt index 158fde846..c165ad435 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt +++ b/code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt @@ -8,6 +8,7 @@ set(COMPONENT_NAME "thunderbird_toys") set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/imsl_system_adapter.c ${CMAKE_CURRENT_SOURCE_DIR}/leiniao_api_at.c + ${CMAKE_CURRENT_SOURCE_DIR}/ln_api.c ) # 公共头文件路径(供其他模块引用) @@ -16,6 +17,7 @@ set(PUBLIC_HEADER ${ROOT_DIR}/zhihui/4g/cat1Service/include/ ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include + ${ROOT_DIR}/open_source/openharmony/third_party/cJSON/ ) diff --git a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c index 5810130ad..c3c4ab5f1 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c @@ -10,14 +10,13 @@ #include #include "imsl_vad.h" #include "media_thread_adapt.h" -#include "http_client.h" -#include "cat1_pub_api.h" +#include "ln_api.h" #define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) #define VAD_MAX_ARGC 8 #define VAD_MAX_ARGV_LEN 64 #define LN_MAX_ARGC 8 -#define LN_MAX_ARGV_LEN 256 +#define LN_MAX_ARGV_LEN 512 #define VAD_FAILED (-1) #define VAD_SUCCESS (0) @@ -465,164 +464,6 @@ static uint32_t vad_cleanup(uint8_t *para, uint32_t paraLen, char *strCommonCmd) return ERRCODE_SUCC; } -/* - * 中文说明:打印签名预览,便于 PC 侧用 curl 验证。 - * 用法:AT^LN_SIGN_PREVIEW=DEVICE_001,123456... - */ -/* 构建签名原始字符串(示例版):按约定拼接关键字段 */ -static void ln_build_sign_data_c(const char *deviceId, const char *iccid, const char *timestampMs, const char *nonce, - char *out_buf, size_t out_buf_size) -{ - if (out_buf == NULL || out_buf_size == 0) - { - return; - } - /* 具体拼接规则以雷鸟后台要求为准;这里采用常见的 key=value&key=value 形式 */ - (void)snprintf(out_buf, out_buf_size, - "deviceId=%s&deviceIccid=%s×tampMs=%s&nonce=%s", - (deviceId ? deviceId : ""), (iccid ? iccid : ""), - (timestampMs ? timestampMs : ""), (nonce ? nonce : "")); -} - -/* 计算签名(占位实现):真实实现应为 HMAC-SHA256(signData, secret) 输出16进制 */ -static void ln_build_signature_hex_c(const char *sign_data, const char *secret, - char *out_hex, size_t out_hex_size) -{ - (void)sign_data; - (void)secret; - if (out_hex == NULL || out_hex_size == 0) - { - return; - } - /* TODO: 接入实际加密库后替换此占位实现 */ - (void)snprintf(out_hex, out_hex_size, "%s", "0000000000000000000000000000000000000000000000000000000000000000"); -} - -static uint32_t ln_sign_preview(uint8_t *para, uint32_t paraLen, char *strCommonCmd) -{ - (void)strCommonCmd; - uint8_t argv[VAD_MAX_ARGC][VAD_MAX_ARGV_LEN] = {0}; - uint32_t argc = 0; - if (ConvertCmdToParam(para, paraLen, argv, &argc) != 0 || argc != 2) - { - printf("用法: AT^LN_SIGN_PREVIEW=,\n"); - return ERRCODE_FAIL; - } - const char *deviceId = (const char *)argv[0]; - const char *iccid = (const char *)argv[1]; - - /* 注意:示例中时间戳应替换为真实毫秒时间戳,nonce 应为随机字符串 */ - char ts[32]; - (void)snprintf(ts, sizeof(ts), "%llu", (unsigned long long)0ULL); - const char *nonce = "nonce"; - const char *signSecret = "vDdXVXgPUEUM6_piUjz5AEhMvYTSFzQdPaN-ogKnSus="; - - char signData[256] = {0}; - ln_build_sign_data_c(deviceId, iccid, ts, nonce, signData, sizeof(signData)); - char signature_hex[128] = {0}; - ln_build_signature_hex_c(signData, signSecret, signature_hex, sizeof(signature_hex)); - - printf("signData: %s\n", signData); - printf("signature(hex): %s\n", signature_hex); - printf("timestamp(ms): %s, nonce: %s\n", ts, nonce); - return ERRCODE_SUCC; -} - -/* HTTP 回调:下载结果 */ -static void ln_http_result(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err) -{ - (void)arg; - printf("HTTP结束: result=%d, bodyLen=%u, http=%u, err=%d\n", (int)httpc_result, (unsigned)rx_content_len, (unsigned)srv_res, (int)err); - // 通讯结束:允许 CAT1 休眠 - cat1_api_remove_cat1_vote(); - cat1_api_keep_wakeup(0); - cat1_api_wakeup_cat1(0); - cat1_api_disable_cat1_cmd(0); -} - -/* HTTP 回调:收到响应头 */ -static err_t ln_http_headers(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len) -{ - (void)connection; - (void)arg; - (void)hdr; - printf("HTTP头: hdr_len=%u content_len=%u\n", (unsigned)hdr_len, (unsigned)content_len); - return 0; -} - -/* HTTP 回调:接收到 body 数据(增量打印前 512 字节以内) */ -static err_t ln_http_body(httpc_state_t *connection, u32_t rx_len, u32_t rx_total_len) -{ - (void)connection; - (void)rx_len; - printf("HTTP body 收到: total=%u\n", (unsigned)rx_total_len); - return 0; -} - -/* - * 中文说明:获取设备 Token 的 AT 指令。 - * 用法:AT^LN_GET_TOKEN=, - * 步骤: - * 1) 生成 timestamp(毫秒)、nonce(随机) 和签名 signature - * 2) 唤醒 CAT1,发起 HTTP GET(当前走 80 端口便于调试;TLS 需另行使能) - * 3) 串口打印 HTTP 状态码与 body 接收进度 - */ -static uint32_t ln_get_token(uint8_t *para, uint32_t paraLen, char *strCommonCmd) -{ - (void)strCommonCmd; - uint8_t argv[VAD_MAX_ARGC][VAD_MAX_ARGV_LEN] = {0}; - uint32_t argc = 0; - if (ConvertCmdToParam(para, paraLen, argv, &argc) != 0 || argc != 2) - { - printf("用法: AT^LN_GET_TOKEN=,\n"); - return ERRCODE_FAIL; - } - const char *deviceId = (const char *)argv[0]; - const char *iccid = (const char *)argv[1]; - - // 1) 生成签名参数 - char ts[32]; - (void)snprintf(ts, sizeof(ts), "%llu", (unsigned long long)0ULL); // TODO: 替换为真实毫秒 - const char *nonce = "nonce"; // TODO: 替换为随机数 - const char *signSecret = "vDdXVXgPUEUM6_piUjz5AEhMvYTSFzQdPaN-ogKnSus="; - char signData[256] = {0}; - ln_build_sign_data_c(deviceId, iccid, ts, nonce, signData, sizeof(signData)); - char signature_hex[128] = {0}; - ln_build_signature_hex_c(signData, signSecret, signature_hex, sizeof(signature_hex)); - - // 2) 组装 HTTP 请求 - httpc_connection_t settings = {0}; - settings.result_fn = ln_http_result; - settings.headers_done_fn = ln_http_headers; - settings.file_rx_fn = ln_http_body; - settings.use_post = 0; - - const char *server = "ambybox-api.test.leiniao.com"; - uint16_t port = 80; // 调试用;如需 TLS,请切到 443 并配置 altcp_tls - const char *uri = "/ambybox-device-api/v1/auth/getDeviceToken"; - - printf("开始获取 Token: %s %s\n", deviceId, iccid); - cat1_api_add_cat1_vote(); - cat1_api_wakeup_cat1(1); - cat1_api_keep_wakeup(1); - cat1_api_disable_cat1_cmd(1); - - httpc_state_t *connection = NULL; - err_t rett = httpc_get_file_dns(server, port, uri, &settings, NULL, NULL, &connection); - if (rett != ERRCODE_SUCC) - { - printf("HTTP 启动失败: %d\n", (int)rett); - // 失败也释放 CAT1 约束 - cat1_api_remove_cat1_vote(); - cat1_api_keep_wakeup(0); - cat1_api_wakeup_cat1(0); - cat1_api_disable_cat1_cmd(0); - return ERRCODE_FAIL; - } - printf("HTTP 已发起,等待回调...\n"); - return ERRCODE_SUCC; -} - // AT^VAD_HELP - 显示帮助信息 static uint32_t vad_help(uint8_t *para, uint32_t paraLen, char *strCommonCmd) { @@ -652,6 +493,30 @@ static uint32_t vad_help(uint8_t *para, uint32_t paraLen, char *strCommonCmd) return ERRCODE_SUCC; } +/* AT^LN_GET_TOKEN[=deviceId,deviceIccid,deviceModel,deviceVersion] */ +//获取设备Token +static uint32_t ln_get_device_token_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + VAD_UNUSED(strCommonCmd); + uint8_t argv[LN_MAX_ARGC][LN_MAX_ARGV_LEN] = {0}; + uint32_t argc = 0; + (void)ConvertCmdToParam(para, paraLen, argv, &argc); + + const char *device_id = (argc >= 1) ? (const char *)argv[0] : "DEVICE_PC_TEST_001"; + const char *device_iccid = (argc >= 2) ? (const char *)argv[1] : "86123456789012345678"; + const char *device_model = (argc >= 3) ? (const char *)argv[2] : "abmybox_1"; + const char *device_ver = (argc >= 4) ? (const char *)argv[3] : "1.0.0"; + printf("[LN] GetDeviceToken start id=%s iccid=%s\n", device_id, device_iccid); + ln_device_token_req_t req = {0}; + strcpy(req.device_id, device_id); + strcpy(req.device_iccid, device_iccid); + strcpy(req.device_model, device_model); + strcpy(req.device_version, device_ver); + do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN, (char *)&req, sizeof(req)); + return ERRCODE_SUCC; +} + + static const at_cmd_table_t g_ln_api_cmd[] = { /* ----------------------------------- VAD ---------------------------------- */ {(char *)"AT^VAD_INIT", vad_init, (char *)"初始化 VAD"}, @@ -663,8 +528,7 @@ static const at_cmd_table_t g_ln_api_cmd[] = { {(char *)"AT^VAD_CLEANUP", vad_cleanup, (char *)"清理 VAD 资源"}, {(char *)"AT^VAD_HELP", vad_help, (char *)"显示帮助信息"}, /* ---------------------------------- 雷鸟API --------------------------------- */ - {(char *)"AT^LN_SIGN_PREVIEW", ln_sign_preview, (char *)"签名预览: 参数=deviceId,iccid"}, - {(char *)"AT^LN_GET_TOKEN", ln_get_token, (char *)"获取设备Token: 参数=deviceId,iccid"}, + {(char *)"AT^LN_GET_TOKEN", ln_get_device_token_at, (char *)"获取雷鸟设备Token: AT^LN_GET_TOKEN[=deviceId,deviceIccid,deviceModel,deviceVersion]"}, }; at_cmd_table_t *get_leiniao_api_cmd_table(uint32_t *cmd_count) diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c new file mode 100644 index 000000000..0cf227e4a --- /dev/null +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c @@ -0,0 +1,373 @@ +#include "ln_api.h" +/* for https/http client */ +#include "netstack/http/include/httpclient.h" +/* for HMAC-SHA256 */ +#include "mbedtls/md.h" +/* for JSON parsing */ +#include "cJSON.h" +#include +#include +#include + +static app_task_definition_t ln_send_taskcfg = {0}; +static app_task_definition_t ln_recv_taskcfg = {0}; +#define LN_HTTP_BOARD_TASK_SIZE 0x2000 + +static unsigned long g_ln_send_queue = 0xFFFFFFFF; +static unsigned long g_ln_recv_queue = 0xFFFFFFFF; + +/* ============================== 雷鸟设备Token获取 ============================== */ + +/* 接口基础配置 - 如需切换环境/密钥,在此调整 */ +#define LN_BASE_URL "https://ambybox-api.test.leiniao.com/ambybox-device-api" +#define LN_INTERFACE_PATH "/v1/auth/getDeviceToken" +#define LN_FULL_URL LN_BASE_URL LN_INTERFACE_PATH +#define LN_SIGN_SECRET "vDdXVXgPUEUM6_piUjz5AEhMvYTSFzQdPaN-ogKnSus=" + +/* 生成[a-zA-Z0-9]随机串 */ +static void ln_gen_nonce(char *out, size_t len) +{ + static const char table[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + if (out == NULL || len == 0) + { + return; + } + /* 使用时间作为随机种子,避免强依赖标准rand种子 */ + uint32_t ts_s = 0; + uapi_get_timestampe_ss(&ts_s); + srand((unsigned int)(ts_s ^ (unsigned int)uapi_tcxo_get_ms())); + for (size_t i = 0; i + 1 < len; i++) + { + out[i] = table[rand() % (sizeof(table) - 1)]; + } + out[len - 1] = '\0'; +} + +static void ln_to_hex_lower(const uint8_t *in, size_t in_len, char *out) +{ + static const char hex[] = "0123456789abcdef"; + for (size_t i = 0; i < in_len; i++) + { + out[i * 2] = hex[(in[i] >> 4) & 0x0F]; + out[i * 2 + 1] = hex[in[i] & 0x0F]; + } + out[in_len * 2] = '\0'; +} + +/* 计算 HMAC-SHA256 并输出小写hex字符串 */ +static int ln_hmac_sha256_hex(const char *key, const char *msg, char *out_hex, size_t out_hex_size) +{ + if (out_hex_size < 65) + { /* 32 bytes -> 64 hex chars + NUL */ + return -1; + } + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (md_info == NULL) + { + return -1; + } + uint8_t digest[32]; + int ret = mbedtls_md_hmac(md_info, (const unsigned char *)key, strlen(key), + (const unsigned char *)msg, strlen(msg), digest); + if (ret != 0) + { + return -1; + } + ln_to_hex_lower(digest, sizeof(digest), out_hex); + return 0; +} + +/* 发送HTTPS GET请求,携带定制Header,解析返回token */ +static uint32_t ln_get_device_token_http(const char *device_id, + const char *device_iccid, + const char *device_model, + const char *device_version) +{ + if (device_id == NULL || device_iccid == NULL) + { + printf("LN token: invalid parameters\n"); + return ERRCODE_FAIL; + } + + /* 1. 生成时间戳(ms)与nonce */ + uint32_t ts_s = 0; /* epoch seconds */ + uapi_get_timestampe_ss(&ts_s); + char timestamp[32] = {0}; + (void)snprintf(timestamp, sizeof(timestamp), "%u000", ts_s); /* 转毫秒字符串 */ + + char nonce[17] = {0}; /* 12~16位,取固定16以简化 */ + ln_gen_nonce(nonce, sizeof(nonce)); + + /* 2. 计算签名: deviceId:deviceIccid:timestamp:nonce */ + char sign_data[256] = {0}; + (void)snprintf(sign_data, sizeof(sign_data), "%s:%s:%s:%s", device_id, device_iccid, timestamp, nonce); + char signature[65] = {0}; + if (ln_hmac_sha256_hex(LN_SIGN_SECRET, sign_data, signature, sizeof(signature)) != 0) + { + printf("LN token: hmac calc failed\n"); + return ERRCODE_FAIL; + } + + /* 3. 组织自定义请求头 */ + char header_buf[1024] = {0}; + int hdr_len = snprintf(header_buf, sizeof(header_buf), + "deviceId: %s\r\n" + "deviceIccid: %s\r\n" + "timestamp: %s\r\n" + "nonce: %s\r\n" + "signature: %s\r\n" + "deviceModel: %s\r\n" + "deviceVersion: %s\r\n" + "Content-Type: application/json\r\n", + device_id, device_iccid, timestamp, nonce, signature, + (device_model && device_model[0]) ? device_model : "abmybox_1", + (device_version && device_version[0]) ? device_version : "1.0.0"); + if (hdr_len <= 0 || hdr_len >= (int)sizeof(header_buf)) + { + printf("LN token: header build failed\n"); + return ERRCODE_FAIL; + } + + /* 4. 保活CAT1,准备网络 */ + cat1_api_add_cat1_vote(); + cat1_api_wakeup_cat1(1); + cat1_api_keep_wakeup(1); + cat1_api_disable_cat1_cmd(1); + LOS_Msleep(500); + + /* 5. 发起HTTPS GET */ + HttpClient client = (HttpClient){0}; + HttpClientData clientData = (HttpClientData){0}; + client.isHttp = false; /* https */ + client.remotePort = 443; + HttpClientSetCustomHeader(&client, header_buf); + + HTTPC_RESULT prep = HttpClientPrepare(&clientData, 2048, 4096); + if (prep != HTTP_SUCCESS) + { + printf("LN token: HttpClientPrepare failed %d\n", prep); + return ERRCODE_FAIL; + } + + HTTPC_RESULT res = HttpClientGetRequest(&client, LN_FULL_URL, &clientData); + if (res != HTTP_SUCCESS) + { + printf("LN token: request failed %d\n", res); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_FAIL; + } + + int code = HttpClientGetResponseCode(&client); + if (code != 200) + { + printf("LN token: HTTP %d\n", code); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_FAIL; + } + + /* 6. 解析响应JSON */ + if (clientData.responseBuf == NULL || clientData.responseBufLen <= 0) + { + printf("LN token: empty body\n"); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_FAIL; + } + + int body_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen; + if (body_len <= 0) + body_len = (int)strlen(clientData.responseBuf); + + char *json_text = (char *)malloc((size_t)body_len + 1); + if (json_text == NULL) + { + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_FAIL; + } + memcpy(json_text, clientData.responseBuf, (size_t)body_len); + json_text[body_len] = '\0'; + + cJSON *root = cJSON_Parse(json_text); + if (!root) + { + printf("LN token: JSON parse failed\n"); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_FAIL; + } + + cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode"); + if (errorCode != NULL && !cJSON_IsNull(errorCode)) + { + cJSON *msg = cJSON_GetObjectItem(root, "message"); + printf("LN token: failed, err=%s\n", msg && cJSON_IsString(msg) ? msg->valuestring : "unknown"); + cJSON_Delete(root); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_FAIL; + } + + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (data && cJSON_IsObject(data)) + { + cJSON *token = cJSON_GetObjectItem(data, "token"); + cJSON *expire = cJSON_GetObjectItem(data, "expireTime"); + printf("LN Device Token: %s\n", (token && cJSON_IsString(token)) ? token->valuestring : ""); + if (expire && cJSON_IsNumber(expire)) + { + printf("Token expireTime: %lld\n", (long long)expire->valuedouble); + } + } + else + { + printf("LN token: no data field\n"); + } + + cJSON_Delete(root); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + return ERRCODE_SUCC; +} + +/* ============================ 雷鸟设备Token获取 End ============================ */ + +// 发送队列 +static void ln_http_server_send_task(void const *arg) +{ + errcode_t ret; + + ln_http_data_mail_t mail = {0}; + uint32_t msgsize = sizeof(ln_http_data_mail_t); + + while (1) + { + ret = osal_msg_queue_read_copy(g_ln_send_queue, (void *)&mail, &msgsize, + OSAL_MSGQ_WAIT_FOREVER); + if (ret != OSAL_SUCCESS) + { + continue; + } + if (mail.cmd == LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN) + { + if (mail.data != NULL && mail.len == sizeof(ln_device_token_req_t)) + { + printf("LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN\n"); + ln_device_token_req_t req; + memcpy(&req, mail.data, sizeof(req)); + ln_get_device_token_http(req.device_id, req.device_iccid, req.device_model, req.device_version); + } + } + if (mail.data != NULL) + { + printf("free(mail.data)\n"); + free(mail.data); + } + } +} + +// 接收队列 +static void ln_http_server_recv_task(void const *arg) +{ + errcode_t ret; + + ln_http_data_mail_t mail = {0}; + uint32_t msgsize = sizeof(ln_http_data_mail_t); + + while (1) + { + ret = osal_msg_queue_read_copy(g_ln_recv_queue, (void *)&mail, &msgsize, + OSAL_MSGQ_WAIT_FOREVER); + if (ret != OSAL_SUCCESS) + { + continue; + } + } +} + +static void create_ln_http_send_queue(void) +{ + if (osal_msg_queue_create("ln_http_send_queue", 24, &g_ln_send_queue, + 0, sizeof(ln_http_data_mail_t)) != ERRCODE_SUCC) + { + printf("[ln][service] app create mail fail\n"); + } +} + +static void create_ln_http_recv_queue(void) +{ + if (osal_msg_queue_create("ln_http_recv_queue", 24, &g_ln_recv_queue, + 0, sizeof(ln_http_data_mail_t)) != ERRCODE_SUCC) + { + printf("[ln][service] app create mail fail\n"); + } +} + +// 雷鸟http服务初始化 +errcode_t uapi_ln_http_server_init(void) +{ + printf("uapi_ln_http_server_init !\r\n"); + + ln_send_taskcfg.create_queue_handle = create_ln_http_send_queue; + ln_send_taskcfg.attr.name = "ln_http_server_send_task"; + ln_send_taskcfg.attr.priority = osPriorityNormal; + ln_send_taskcfg.attr.stack_size = LN_HTTP_BOARD_TASK_SIZE; + ln_send_taskcfg.func = ln_http_server_send_task; + ln_send_taskcfg.use_mem = USE_EXTEND_MEM; + + errcode_t ret = uapi_create_osThread_custom(&ln_send_taskcfg); + if (ret != ERRCODE_SUCC) + { + printf("create ln_send_service failed %d!\r\n", ret); + return ERRCODE_FAIL; + } + + ln_recv_taskcfg.create_queue_handle = create_ln_http_recv_queue; + ln_recv_taskcfg.attr.name = "ln_http_server_recv_task"; + ln_recv_taskcfg.attr.priority = osPriorityNormal; + ln_recv_taskcfg.attr.stack_size = LN_HTTP_BOARD_TASK_SIZE; + ln_recv_taskcfg.func = ln_http_server_recv_task; + ln_recv_taskcfg.use_mem = USE_EXTEND_MEM; + + ret = uapi_create_osThread_custom(&ln_recv_taskcfg); + if (ret != ERRCODE_SUCC) + { + printf("create gnss_recv_service failed %d!\r\n", ret); + return ERRCODE_FAIL; + } + + return ERRCODE_SUCC; +} + +/* 通用发送接口:向 LN HTTP 发送队列投递消息 */ +void do_ln_http_server_send_data(int cmd, char *data, uint32_t len) +{ + errcode_t ret; + ln_http_data_mail_t send_data = {0}; + send_data.cmd = cmd; + if (len && data) + { + send_data.len = len; + send_data.data = (char *)malloc(len); + if (send_data.data == NULL) + { + printf("malloc failed\n"); + return; + } + memcpy(send_data.data, data, len); + } + + uint32_t send_len = sizeof(send_data); + + ret = osal_msg_queue_write_copy(g_ln_send_queue, (void *)&send_data, + send_len, 0); + if (ret != OSAL_SUCCESS) + { + printf("Error ln http send failed! err=0x%x! \r\n", ret); + } +} diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h new file mode 100644 index 000000000..33a9939c0 --- /dev/null +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -0,0 +1,38 @@ +#ifndef LN_API_H +#define LN_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "stdint.h" +#include "errcode.h" + +typedef struct +{ + int cmd; + char *data; + uint32_t len; +} ln_http_data_mail_t; + +#define LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN 0x1 + +typedef struct +{ + char device_id[64]; + char device_iccid[32]; + char device_model[32]; + char device_version[16]; +} ln_device_token_req_t; + +errcode_t uapi_ln_http_server_init(void); + +/* 通用发送接口:向 LN HTTP 发送队列投递消息 */ +void do_ln_http_server_send_data(int cmd, char *data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* LN_API_H */ -- 2.17.1