ln:添加与蓝牙设备连接状态上报相关协议 2791/1 2791/head 2792/target/1
authorluozheng <1732036298@qq.com>
Sat, 22 Nov 2025 02:44:51 +0000 (10:44 +0800)
committerluozheng <1732036298@qq.com>
Sat, 22 Nov 2025 02:44:51 +0000 (10:44 +0800)
code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt
code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.h
code/sdk/zhihui/leiniao/imsl_ln/ln_api_web_ack.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c
code/sdk/zhihui/leiniao/imsl_ln/ln_bluetooth_api.c [new file with mode: 0644]

index e6c09ec..83db0ff 100644 (file)
@@ -22,6 +22,7 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_timeline_activities.c
     ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_web_ack.c
     ${CMAKE_CURRENT_SOURCE_DIR}/ln_file_recv_task.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/ln_bluetooth_api.c
 )
 
 # 公共头文件路径(供其他模块引用)
index 8bacb6d..b28cb23 100644 (file)
@@ -1647,6 +1647,19 @@ static uint32_t ln_debug_popup_at(uint8_t *para, uint32_t paraLen, char *strComm
     printf("+LN_DEBUG_POPUP: OK\n");
     return ERRCODE_SUCC;
 }
+
+//蓝牙状态上报
+static uint32_t ln_bluetooth_status_report_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    char *bluetoothStatus = NULL;
+    if (para != NULL && paraLen > 0) {
+        bluetoothStatus = (char*)para;
+    }
+    printf("+LN_BLUETOOTH_STATUS_REPORT: OK\n");
+    printf("[LN][BLUETOOTH_STATUS_REPORT] bluetoothStatus=%s\n", bluetoothStatus);
+    do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));
+    return ERRCODE_SUCC;
+}
 static const at_cmd_table_t g_ln_api_cmd[] = {
     /* ---------------------------------- 雷鸟API --------------------------------- */
     {(char *)"AT^LN_GET_TOKEN", ln_get_device_token_at, (char *)"获取雷鸟设备Token: AT^LN_GET_TOKEN[=deviceId,deviceIccid,deviceModel,deviceVersion]"},
@@ -1733,6 +1746,9 @@ static const at_cmd_table_t g_ln_api_cmd[] = {
     //WS状态和网络参数显示
     {(char *)"AT^LN_SHOW_WS_NET", ln_show_ws_net_at, (char *)"显示WS连接状态和网络参数: AT^LN_SHOW_WS_NET[=-p x,y]"},
     {(char *)"AT^LN_HIDE_WS_NET", ln_hide_ws_net_at, (char *)"隐藏WS连接状态和网络参数显示: AT^LN_HIDE_WS_NET"},
+
+    //蓝牙相关
+    {(char *)"AT^LN_BLUETOOTH_STATUS_REPORT", ln_bluetooth_status_report_at, (char *)"蓝牙状态上报: AT^LN_BLUETOOTH_STATUS_REPORT[=bluetoothStatus]"},
 };
 
 
index 45010ff..0bd797f 100644 (file)
@@ -457,7 +457,7 @@ void uapi_ln_remove_vote(void)
     uint8_t cnt = pm_veto_get_id_cnt(PM_ID_DEBUG);
     if (cnt == 1) 
     {
-        uapi_ln_remove_vote();
+        uapi_pm_add_sleep_veto(PM_ID_DEBUG);
     }
 }
 void uapi_ln_add_vote(void)
@@ -465,7 +465,7 @@ void uapi_ln_add_vote(void)
     uint8_t cnt = pm_veto_get_id_cnt(PM_ID_DEBUG);
     if (cnt == 0) 
     {
-        uapi_ln_add_vote();
+        uapi_pm_add_sleep_veto(PM_ID_DEBUG);
     }
 }
 
@@ -921,6 +921,44 @@ void ln_ws_process_message(const ws_data_msg_t *data_msg, ws_command_t type)
         }
         break;
     }
+    case WS_CMD_BLUETOOTH_CONNECT:
+    {
+        printf("[WS] BluetoothConnect:蓝牙连接\n");
+        if (json_str)
+        {
+            ln_parse_bluetooth_connect(json_str, (int)strlen(json_str));
+            /* 发送蓝牙连接应答 */
+            ln_ws_send_bluetooth_connect_ack(true, "蓝牙连接中");
+            /* TODO: 这里应该调用实际的蓝牙连接接口,执行搜索和连接操作 */
+            /* 连接完成后,通过BluetoothStatusReport命令上报最终状态 */
+        }
+        break;
+    }
+    case WS_CMD_BLUETOOTH_UNBIND:
+    {
+        printf("[WS] BluetoothUnbind:蓝牙解绑\n");
+        if (json_str)
+        {
+            ln_parse_bluetooth_unbind(json_str, (int)strlen(json_str));
+            const ln_bluetooth_unbind_data_t *unbind_data = ln_get_bluetooth_unbind_data();
+            /* 发送蓝牙解绑应答 */
+            ln_ws_send_bluetooth_unbind_ack(
+                unbind_data->bluetooth_address,
+                unbind_data->bluetooth_name,
+                true,
+                "蓝牙解绑中"
+            );
+            /* TODO: 这里应该调用实际的蓝牙解绑接口,执行解绑操作 */
+            /* 解绑完成后,通过BluetoothStatusReport命令上报最终状态 */
+        }
+        break;
+    }
+    case WS_CMD_BLUETOOTH_STATUS_REPORT_ACK:
+    {
+        printf("[WS] BluetoothStatusReportAck:蓝牙状态上报应答\n");
+        /* 服务端对设备蓝牙状态上报的应答,设备端可以记录或处理 */
+        break;
+    }
     case WS_CMD_PING:
     {
         printf("[WS] Ping\n");
@@ -1127,6 +1165,22 @@ static void ln_http_server_send_task(void const *arg)
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVICE_CMD_WS_EXIT_SLEEP] 退出休眠");
             ln_ws_exit_sleep();
         }
+        else if(mail.cmd == LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT] 蓝牙状态上报");
+            if (mail.data && mail.len > 0)
+            {
+                /* 确保字符串以\0结尾,避免乱码 */
+                char *bluetooth_status = (char *)malloc(mail.len + 1);
+                if (bluetooth_status)
+                {
+                    memcpy(bluetooth_status, mail.data, mail.len);
+                    bluetooth_status[mail.len] = '\0';
+                    ln_send_bluetooth_status_report(bluetooth_status);
+                    free(bluetooth_status);
+                }
+            }
+        }
         if (mail.data != NULL)
         {
             printf("free(mail.data)\n");
index 1c226ea..72633fd 100644 (file)
@@ -135,6 +135,9 @@ typedef struct
 #define LN_HTTP_SERVICE_CMD_WS_ENTER_SLEEP 0x1013 /* 进入休眠 */
 #define LN_HTTP_SERVICE_CMD_WS_EXIT_SLEEP 0x1014 /* 退出休眠 */
 
+//蓝牙状态上报相关命令
+#define LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT 0x1015 /* 蓝牙状态上报 */
+
 /* 下载文件相关结构体 */
 typedef struct
 {
@@ -326,6 +329,27 @@ void ln_parse_delete_emoji(const char *json_str, int json_len);
 void ln_emoji_report_status(char *data);
 /* 解析设备升级 */
 void ln_parse_device_upgrade(const char *json_str, int json_len);
+/* 解析蓝牙连接命令 */
+void ln_parse_bluetooth_connect(const char *json_str, int json_len);
+/* 解析蓝牙解绑命令 */
+void ln_parse_bluetooth_unbind(const char *json_str, int json_len);
+/* 发送蓝牙状态上报(使用消息队列方式) */
+void ln_send_bluetooth_status_report(const char *bluetooth_status);
+/* 蓝牙连接命令数据结构 */
+typedef struct {
+    char user_id[64];
+    char bluetooth_address[32];
+} ln_bluetooth_connect_data_t;
+/* 蓝牙解绑命令数据结构 */
+typedef struct {
+    char user_id[64];
+    char bluetooth_address[32];
+    char bluetooth_name[128];
+} ln_bluetooth_unbind_data_t;
+/* 获取蓝牙连接命令数据 */
+const ln_bluetooth_connect_data_t* ln_get_bluetooth_connect_data(void);
+/* 获取蓝牙解绑命令数据 */
+const ln_bluetooth_unbind_data_t* ln_get_bluetooth_unbind_data(void);
 /* 从下发JSON中提取userId */
 void ln_ws_ack_user_id_from_json(const char *json_str);
 /* ========== Ack 发送接口 ========== */
@@ -338,6 +362,8 @@ int ln_ws_send_schedule_reminder_config_ack(int schedule_id, bool success, const
 int ln_ws_send_delete_emoji_ack(const char *character_id, const char *eyesColor, const char *eyesShape, bool success, const char *msg);
 int ln_ws_send_download_emoji_ack(const char *character_id, const char *eyesColor, const char *eyesShape, bool success, const char *msg);
 int ln_ws_send_device_upgrade_ack(const char *update_id, const char *target_version, bool success, const char *msg);
+int ln_ws_send_bluetooth_connect_ack(bool success, const char *msg);
+int ln_ws_send_bluetooth_unbind_ack(const char *bluetooth_address, const char *bluetooth_name, bool success, const char *msg);
 /* =================== 时间线状态(Timeline getStatus) =================== */
 /* 查询时间线状态(GET /v1/timeline/getStatus)*/
 uint32_t ln_timeline_get_status_http(const char *device_id,
@@ -417,6 +443,9 @@ typedef enum {
     WS_CMD_AUDIO_RECORDING_END,      /* 结束录音上传 */
     WS_CMD_SENTENCE_PLAYBACK_COMPLETE, /* 单句语音播放完成 */
     WS_CMD_DEVICE_UPGRADE,           /* 设备升级(DeviceUpgrade) */
+    WS_CMD_BLUETOOTH_CONNECT,        /* 蓝牙连接(BluetoothConnect) */
+    WS_CMD_BLUETOOTH_UNBIND,         /* 蓝牙解绑(BluetoothUnbind) */
+    WS_CMD_BLUETOOTH_STATUS_REPORT_ACK, /* 蓝牙状态上报应答(BluetoothStatusReportAck) */
     WS_CMD_MAX                       /* 最大命令 */
 } ws_command_t;
 
index 7b92553..4b88ff4 100644 (file)
@@ -568,4 +568,102 @@ int ln_ws_send_device_upgrade_ack(const char *update_id, const char *target_vers
     cJSON_free(json_string);
     cJSON_Delete(json);
     return ret;
+}
+
+/*  发送蓝牙连接应答消息,确认设备已收到连接命令并开始处理 */
+int ln_ws_send_bluetooth_connect_ack(bool success, const char *msg)
+{
+    if (ln_ws_get_connection_state() != 2)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Cannot send BluetoothConnectAck, connection state: %d\n", ln_ws_get_connection_state());
+        return -1;
+    }
+
+    uint32_t timestamp;
+    uapi_get_timestampe_ss(&timestamp);
+
+    cJSON *json = cJSON_CreateObject();
+    if (!json)
+        return -1;
+
+    cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id());
+    cJSON_AddNumberToObject(json, "timestamp", (double)timestamp);
+
+    char message_id[64];
+    snprintf(message_id, sizeof(message_id), "ack_bt_connect_%u", timestamp);
+    cJSON_AddStringToObject(json, "messageId", message_id);
+    cJSON_AddStringToObject(json, "command", "BluetoothConnectAck");
+
+    cJSON *data = cJSON_CreateObject();
+    if (!data)
+    {
+        cJSON_Delete(json);
+        return -1;
+    }
+    cJSON_AddBoolToObject(data, "success", success);
+    cJSON_AddStringToObject(data, "message", msg ? msg : (success ? "蓝牙连接中" : "蓝牙连接失败"));
+    cJSON_AddItemToObject(json, "data", data);
+
+    char *json_string = cJSON_Print(json);
+    if (!json_string)
+    {
+        cJSON_Delete(json);
+        return -1;
+    }
+
+    int ret = uapi_ws_send_text(json_string);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent BluetoothConnectAck: %s\n", json_string);
+    cJSON_free(json_string);
+    cJSON_Delete(json);
+    return ret;
+}
+
+/* 发送蓝牙解绑应答消息,确认设备已收到解绑命令并开始处理 */
+int ln_ws_send_bluetooth_unbind_ack(const char *bluetooth_address, const char *bluetooth_name, bool success, const char *msg)
+{
+    if (ln_ws_get_connection_state() != 2)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Cannot send BluetoothUnbindAck, connection state: %d\n", ln_ws_get_connection_state());
+        return -1;
+    }
+
+    uint32_t timestamp;
+    uapi_get_timestampe_ss(&timestamp);
+
+    cJSON *json = cJSON_CreateObject();
+    if (!json)
+        return -1;
+
+    cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id());
+    cJSON_AddNumberToObject(json, "timestamp", (double)timestamp);
+
+    char message_id[64];
+    snprintf(message_id, sizeof(message_id), "ack_bt_unbind_%u", timestamp);
+    cJSON_AddStringToObject(json, "messageId", message_id);
+    cJSON_AddStringToObject(json, "command", "BluetoothUnbindAck");
+
+    cJSON *data = cJSON_CreateObject();
+    if (!data)
+    {
+        cJSON_Delete(json);
+        return -1;
+    }
+    cJSON_AddStringToObject(data, "bluetoothAddress", (bluetooth_address && bluetooth_address[0]) ? bluetooth_address : "");
+    cJSON_AddStringToObject(data, "bluetoothName", (bluetooth_name && bluetooth_name[0]) ? bluetooth_name : "");
+    cJSON_AddBoolToObject(data, "success", success);
+    cJSON_AddStringToObject(data, "message", msg ? msg : (success ? "蓝牙解绑中" : "蓝牙解绑失败"));
+    cJSON_AddItemToObject(json, "data", data);
+
+    char *json_string = cJSON_Print(json);
+    if (!json_string)
+    {
+        cJSON_Delete(json);
+        return -1;
+    }
+
+    int ret = uapi_ws_send_text(json_string);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent BluetoothUnbindAck: %s\n", json_string);
+    cJSON_free(json_string);
+    cJSON_Delete(json);
+    return ret;
 }
\ No newline at end of file
index 0001680..35272dd 100644 (file)
@@ -1620,6 +1620,12 @@ static ws_command_t ln_ws_parse_command_string(const char *command_str)
         return WS_CMD_RANDOM_STORY_RESPONSE;
     } else if (strcmp(command_str, "DeviceUpgrade") == 0) {
         return WS_CMD_DEVICE_UPGRADE;
+    } else if (strcmp(command_str, "BluetoothConnect") == 0) {
+        return WS_CMD_BLUETOOTH_CONNECT;
+    } else if (strcmp(command_str, "BluetoothUnbind") == 0) {
+        return WS_CMD_BLUETOOTH_UNBIND;
+    } else if (strcmp(command_str, "BluetoothStatusReportAck") == 0) {
+        return WS_CMD_BLUETOOTH_STATUS_REPORT_ACK;
     } else {
         return WS_CMD_UNKNOWN;
     }
diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_bluetooth_api.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_bluetooth_api.c
new file mode 100644 (file)
index 0000000..e48b1a8
--- /dev/null
@@ -0,0 +1,318 @@
+#include "ln_api.h"
+#include "cJSON.h"
+#include "custom_utils.h"
+#include <string.h>
+
+/* 蓝牙状态枚举值常量 */
+#define BT_STATUS_CONNECTED "CONNECTED"           /* 蓝牙已连接 */
+#define BT_STATUS_DISCONNECTED "DISCONNECTED"     /* 蓝牙已断开 */
+#define BT_STATUS_CONNECTING "CONNECTING"         /* 蓝牙连接中 */
+#define BT_STATUS_CONNECT_FAILED "CONNECT_FAILED" /* 蓝牙连接失败 */
+#define BT_STATUS_UNBINDING "UNBINDING"           /* 蓝牙解绑中 */
+#define BT_STATUS_UNBIND_FAILED "UNBIND_FAILED"   /* 蓝牙解绑失败 */
+#define BT_STATUS_UNBIND_SUCCESS "UNBIND_SUCCESS" /* 蓝牙解绑成功 */
+
+/* 全局变量存储蓝牙命令数据 */
+static ln_bluetooth_connect_data_t g_bluetooth_connect_data = {0};
+static ln_bluetooth_unbind_data_t g_bluetooth_unbind_data = {0};
+static char bluetooth_address[32]; /* 蓝牙设备MAC地址 */
+static char bluetooth_name[128];   /* 蓝牙设备名称 */
+static int battery_level;          /* 电池电量百分比,范围0-100 */
+
+/*获取已经绑定的耳机蓝牙设备MAC地址:"bluetoothAddress": "AA:BB:CC:DD:EE:FF"*/
+char *ln_get_bluetooth_device_mac(void)
+{
+    bluetooth_address[0] = '\0';
+    // errcode_t res = bluetooth_get_bound_device_mac(bluetooth_address, sizeof(bluetooth_address));
+    // if (res != ERRCODE_SUCCESS)
+    // {
+    //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 获取已绑定的耳机蓝牙设备MAC地址失败");
+    //     return NULL;
+    // }
+    // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 获取已绑定的耳机蓝牙设备MAC地址成功:%s", bluetooth_address);
+    strncpy(bluetooth_address, "AA:BB:CC:DD:EE:FF", sizeof(bluetooth_address) - 1);
+    bluetooth_address[sizeof(bluetooth_address) - 1] = '\0';
+    return bluetooth_address;
+}
+
+/* 获取已绑定的耳机蓝牙设备名称:"bluetoothName": "AirPods Pro"*/
+char *ln_get_bluetooth_device_name(void)
+{
+    bluetooth_name[0] = '\0';
+    // errcode_t res = bluetooth_get_bound_device_name(bluetooth_name, sizeof(bluetooth_name));
+    // if (res != ERRCODE_SUCCESS)
+    // {
+    //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 获取已绑定的耳机蓝牙设备名称失败");
+    //     return NULL;
+    // }
+    // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 获取已绑定的耳机蓝牙设备名称成功:%s", bluetooth_name);
+    strncpy(bluetooth_name, "AirPods Pro", sizeof(bluetooth_name) - 1);
+    bluetooth_name[sizeof(bluetooth_name) - 1] = '\0';
+    return bluetooth_name;
+}
+
+/* 获取已绑定的耳机蓝牙设备电池电量:"batteryLevel": 80 */
+int ln_get_bluetooth_device_battery_level(void)
+{
+    battery_level = 80;
+    // errcode_t res = bluetooth_get_battery_level(&battery_level);
+    // if (res != ERRCODE_SUCCESS)
+    // {
+    //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 获取耳机蓝牙设备电池电量失败");
+    //     return 0;
+    // }
+    // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 获取耳机蓝牙设备电池电量成功:%d", battery_level);
+    return battery_level;
+}
+
+/* 发送蓝牙状态上报 BluetoothStatusReport(内部实现,通过WebSocket发送) */
+static int ln_ws_send_bluetooth_status_report(const char *bluetooth_address, const char *bluetooth_name,
+                                              int battery_level, const char *bluetooth_status, const char *msg)
+{
+    if (ln_ws_get_connection_state() != 2)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Cannot send BluetoothStatusReport, connection state: %d\n", ln_ws_get_connection_state());
+        return -1;
+    }
+
+    uint32_t timestamp;
+    uapi_get_timestampe_ss(&timestamp);
+
+    cJSON *json = cJSON_CreateObject();
+    if (!json)
+        return -1;
+
+    cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id());
+    cJSON_AddNumberToObject(json, "timestamp", (double)timestamp);
+
+    char message_id[64];
+    snprintf(message_id, sizeof(message_id), "bt_status_%u", timestamp);
+    cJSON_AddStringToObject(json, "messageId", message_id);
+    cJSON_AddStringToObject(json, "command", "BluetoothStatusReport");
+
+    cJSON *data = cJSON_CreateObject();
+    if (!data)
+    {
+        cJSON_Delete(json);
+        return -1;
+    }
+    cJSON_AddStringToObject(data, "bluetoothAddress", (bluetooth_address && bluetooth_address[0]) ? bluetooth_address : "");
+    cJSON_AddStringToObject(data, "bluetoothName", (bluetooth_name && bluetooth_name[0]) ? bluetooth_name : "");
+
+    /* 限制电池电量范围在0-100之间 */
+    int battery = battery_level;
+    if (battery_level < 0 || battery_level > 100)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 电池电量范围不在0-100之间");
+    }
+    if (battery < 0)
+        battery = 0;
+    if (battery > 100)
+        battery = 100;
+    cJSON_AddNumberToObject(data, "batteryLevel", battery);
+
+    cJSON_AddStringToObject(data, "bluetoothStatus", (bluetooth_status && bluetooth_status[0]) ? bluetooth_status : "");
+    cJSON_AddStringToObject(data, "message", msg ? msg : "");
+    cJSON_AddItemToObject(json, "data", data);
+
+    char *json_string = cJSON_Print(json);
+    if (!json_string)
+    {
+        cJSON_Delete(json);
+        return -1;
+    }
+
+    int ret = uapi_ws_send_text(json_string);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent BluetoothStatusReport: %s\n", json_string);
+    cJSON_free(json_string);
+    cJSON_Delete(json);
+    return ret;
+}
+
+/* 发送蓝牙状态上报(使用消息队列方式) */
+void ln_send_bluetooth_status_report(const char *bluetooth_status)
+{
+    if (!bluetooth_status || !bluetooth_status[0])
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 蓝牙状态为空");
+        return;
+    }
+    char *msg = NULL;
+    if(strcmp(bluetooth_status, BT_STATUS_CONNECTED) == 0)
+    {
+        msg = "蓝牙已连接";
+    }
+    else if(strcmp(bluetooth_status, BT_STATUS_CONNECTING) == 0)
+    {
+        msg = "蓝牙连接中";
+    }
+    else if(strcmp(bluetooth_status, BT_STATUS_CONNECT_FAILED) == 0)
+    {
+        msg = "蓝牙已连接失败";
+    }
+    else if(strcmp(bluetooth_status, BT_STATUS_DISCONNECTED) == 0)
+    {
+        msg = "蓝牙断开连接";
+    }
+    else if(strcmp(bluetooth_status, BT_STATUS_UNBINDING) == 0)
+    {
+        msg = "蓝牙解绑中";
+    }
+    else if(strcmp(bluetooth_status, BT_STATUS_UNBIND_FAILED) == 0)
+    {
+        msg = "蓝牙解绑失败";
+    }
+    else if(strcmp(bluetooth_status, BT_STATUS_UNBIND_SUCCESS) == 0)
+    {
+        msg = "蓝牙解绑成功";
+    }
+    else
+    {
+        msg = NULL;
+    }
+    ln_ws_send_bluetooth_status_report(
+    ln_get_bluetooth_device_mac(), 
+    ln_get_bluetooth_device_name(), 
+    ln_get_bluetooth_device_battery_level(),
+    bluetooth_status, 
+    msg);
+}
+
+/* 解析蓝牙连接命令 BluetoothConnect */
+void ln_parse_bluetooth_connect(const char *json_str, int json_len)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 解析蓝牙连接命令");
+    if (!json_str || json_len <= 0)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] parse connect command: invalid json");
+        return;
+    }
+
+    char *text = (char *)malloc((size_t)json_len + 1);
+    if (!text)
+        return;
+    memcpy(text, json_str, (size_t)json_len);
+    text[json_len] = '\0';
+
+    cJSON *root = cJSON_Parse(text);
+    if (!root)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] parse connect command: json parse failed");
+        free(text);
+        return;
+    }
+
+    cJSON *data = cJSON_GetObjectItem(root, "data");
+    if (!data || !cJSON_IsObject(data))
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] connect command data missing");
+        cJSON_Delete(root);
+        free(text);
+        return;
+    }
+
+    /* 解析data字段 */
+    memset(&g_bluetooth_connect_data, 0, sizeof(g_bluetooth_connect_data));
+
+    cJSON *userId = cJSON_GetObjectItem(data, "userId");
+    if (userId && cJSON_IsString(userId) && userId->valuestring)
+    {
+        strncpy(g_bluetooth_connect_data.user_id, userId->valuestring,
+                sizeof(g_bluetooth_connect_data.user_id) - 1);
+        g_bluetooth_connect_data.user_id[sizeof(g_bluetooth_connect_data.user_id) - 1] = '\0';
+    }
+
+    cJSON *bluetoothAddress = cJSON_GetObjectItem(data, "bluetoothAddress");
+    if (bluetoothAddress && cJSON_IsString(bluetoothAddress) && bluetoothAddress->valuestring)
+    {
+        strncpy(g_bluetooth_connect_data.bluetooth_address, bluetoothAddress->valuestring,
+                sizeof(g_bluetooth_connect_data.bluetooth_address) - 1);
+        g_bluetooth_connect_data.bluetooth_address[sizeof(g_bluetooth_connect_data.bluetooth_address) - 1] = '\0';
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] BluetoothConnect - userId: %s, bluetoothAddress: %s",
+                  g_bluetooth_connect_data.user_id, g_bluetooth_connect_data.bluetooth_address);
+
+    cJSON_Delete(root);
+    free(text);
+}
+
+/* 解析蓝牙解绑命令 BluetoothUnbind */
+void ln_parse_bluetooth_unbind(const char *json_str, int json_len)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] 解析蓝牙解绑命令");
+    if (!json_str || json_len <= 0)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] parse unbind command: invalid json");
+        return;
+    }
+
+    char *text = (char *)malloc((size_t)json_len + 1);
+    if (!text)
+        return;
+    memcpy(text, json_str, (size_t)json_len);
+    text[json_len] = '\0';
+
+    cJSON *root = cJSON_Parse(text);
+    if (!root)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] parse unbind command: json parse failed");
+        free(text);
+        return;
+    }
+
+    cJSON *data = cJSON_GetObjectItem(root, "data");
+    if (!data || !cJSON_IsObject(data))
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] unbind command data missing");
+        cJSON_Delete(root);
+        free(text);
+        return;
+    }
+
+    /* 解析data字段 */
+    memset(&g_bluetooth_unbind_data, 0, sizeof(g_bluetooth_unbind_data));
+
+    cJSON *userId = cJSON_GetObjectItem(data, "userId");
+    if (userId && cJSON_IsString(userId) && userId->valuestring)
+    {
+        strncpy(g_bluetooth_unbind_data.user_id, userId->valuestring,
+                sizeof(g_bluetooth_unbind_data.user_id) - 1);
+        g_bluetooth_unbind_data.user_id[sizeof(g_bluetooth_unbind_data.user_id) - 1] = '\0';
+    }
+
+    cJSON *bluetoothAddress = cJSON_GetObjectItem(data, "bluetoothAddress");
+    if (bluetoothAddress && cJSON_IsString(bluetoothAddress) && bluetoothAddress->valuestring)
+    {
+        strncpy(g_bluetooth_unbind_data.bluetooth_address, bluetoothAddress->valuestring,
+                sizeof(g_bluetooth_unbind_data.bluetooth_address) - 1);
+        g_bluetooth_unbind_data.bluetooth_address[sizeof(g_bluetooth_unbind_data.bluetooth_address) - 1] = '\0';
+    }
+
+    cJSON *bluetoothName = cJSON_GetObjectItem(data, "bluetoothName");
+    if (bluetoothName && cJSON_IsString(bluetoothName) && bluetoothName->valuestring)
+    {
+        strncpy(g_bluetooth_unbind_data.bluetooth_name, bluetoothName->valuestring,
+                sizeof(g_bluetooth_unbind_data.bluetooth_name) - 1);
+        g_bluetooth_unbind_data.bluetooth_name[sizeof(g_bluetooth_unbind_data.bluetooth_name) - 1] = '\0';
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[BT] BluetoothUnbind - userId: %s, bluetoothAddress: %s, bluetoothName: %s",
+                  g_bluetooth_unbind_data.user_id, g_bluetooth_unbind_data.bluetooth_address,
+                  g_bluetooth_unbind_data.bluetooth_name);
+
+    cJSON_Delete(root);
+    free(text);
+}
+
+/* 获取蓝牙连接命令数据 */
+const ln_bluetooth_connect_data_t *ln_get_bluetooth_connect_data(void)
+{
+    return &g_bluetooth_connect_data;
+}
+
+/* 获取蓝牙解绑命令数据 */
+const ln_bluetooth_unbind_data_t *ln_get_bluetooth_unbind_data(void)
+{
+    return &g_bluetooth_unbind_data;
+}