优化绑定流程
authorcaisking <caiyqm@qq.com>
Sun, 24 May 2026 07:27:50 +0000 (15:27 +0800)
committercaisking <caiyqm@qq.com>
Sun, 24 May 2026 07:27:50 +0000 (15:27 +0800)
code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c
code/sdk/zhihui/services/ble_service/bleservice/bleEvent.h
code/sdk/zhihui/services/ble_service/bleservice/bleService.c

index 1456ea8..216302a 100644 (file)
@@ -901,8 +901,207 @@ void clearPaireCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totaldata,ui
     }
 }
 uint8_t *savephonename=NULL;
+
+/*
+ * ============================================================================
+ * App 绑定流程(手表侧)— 函数调用顺序
+ * ============================================================================
+ * 1. App 写 2AE4:73 02 10(手机 JSON) → SetPhoneInfo()
+ * 2. SetPhoneInfo() CRC 通过 → sendBindInfor() 比对 MAC,回 72 02 10(bond 字段)
+ * 3. bond=0x01 首次绑定 → 弹手表绑定 UI → 用户确认 → comfirmPaire(1)
+ * 4. comfirmPaire() 发 72 05 11 → 按需清手表配对 → gap_ble_pair_remote_device()
+ * 5. 手机系统配对成功 → svr_gap_ble_auth_complete_callback → sendParieSuccess() 发 72 05 10
+ * 6. svr_pair_result_cbt_cb → CTKD/BR 回连 → 跳主界面
+ * 7. 若步骤5超时(5s)或配对失败 → 主动发 72 05 10 flag=0,避免 App 长时间卡住
+ *
+ * bond 含义(72 02 10 的 value[17]):
+ *   0x01 = 手表未绑过,需首次绑定
+ *   0x02 = 同机回连
+ *   0x03 = 手表已绑其他手机 / MAC 对不上
+ *   0x00 = CRC 校验失败(SetPhoneInfo 专用)
+ * ============================================================================
+ */
+
+static void ble_clear_watch_all_pairs(const char *reason);
+
+uint8_t first_bond = 0; /* 是否第一次绑定;供配对超时回调使用,定义须在本文件靠前位置 */
+
+/* 首次绑定:comfirmPaire 发起系统配对后,等待 auth_complete 的超时(毫秒) */
+#define BLE_BIND_PAIR_TIMEOUT_MS 5000
+
+static osTimerId_t ble_bind_pair_timer = NULL;
+static bool ble_bind_pair_waiting_auth = false;
+
+static void ble_bind_pair_stop_timeout_timer(void)
+{
+    if (ble_bind_pair_timer != NULL) {
+        osTimerStop(ble_bind_pair_timer);
+        osTimerDelete(ble_bind_pair_timer);
+        ble_bind_pair_timer = NULL;
+    }
+    ble_bind_pair_waiting_auth = false;
+}
+
+static void ble_bind_pair_timeout_callback(int data)
+{
+    (void)data;
+
+    if (!ble_bind_pair_waiting_auth) {
+        return;
+    }
+    ble_bind_pair_waiting_auth = false;
+    ble_bind_pair_stop_timeout_timer();
+
+    if (g_ble_conn_id == 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] 配对超时但 BLE 已断开 取消发72_05_10");
+        first_bond = 0;
+        return;
+    }
+
+    bd_addr_t addr = {0};
+    get_phone_addr(&addr, g_ble_conn_id);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 配对超时(%us) 未收到auth_complete "
+        "主动发72_05_10 flag=0 常见原因=手机系统仍保留旧配对(手表已恢复出厂)",
+        (unsigned int)(BLE_BIND_PAIR_TIMEOUT_MS / 1000U));
+    sendParieSuccess(0, &addr);
+    first_bond = 0;
+}
+
+static void ble_bind_pair_start_timeout_timer(void)
+{
+    osStatus_t ret_timer;
+    uint32_t tick;
+
+    ble_bind_pair_stop_timeout_timer();
+    ble_bind_pair_waiting_auth = true;
+
+    ble_bind_pair_timer = osTimerNew((osTimerFunc_t)ble_bind_pair_timeout_callback,
+        osTimerOnce, NULL, NULL);
+    if (ble_bind_pair_timer == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] 创建绑定配对超时定时器失败");
+        ble_bind_pair_waiting_auth = false;
+        return;
+    }
+
+    tick = osMs2Tick(BLE_BIND_PAIR_TIMEOUT_MS);
+    ret_timer = osTimerStart(ble_bind_pair_timer, tick);
+    if (ret_timer != osOK) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] 启动绑定配对超时定时器失败 ret=0x%lx", (unsigned long)ret_timer);
+        osTimerDelete(ble_bind_pair_timer);
+        ble_bind_pair_timer = NULL;
+        ble_bind_pair_waiting_auth = false;
+        return;
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 已启动绑定配对超时定时器 %us 等待auth_complete",
+        (unsigned int)(BLE_BIND_PAIR_TIMEOUT_MS / 1000U));
+}
+
+void ble_bind_pair_on_auth_complete(void)
+{
+    if (!ble_bind_pair_waiting_auth) {
+        return;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 收到auth_complete 取消绑定配对超时定时器");
+    ble_bind_pair_stop_timeout_timer();
+}
+
+void ble_bind_pair_on_pair_failed(const bd_addr_t *addr)
+{
+    if (!ble_bind_pair_waiting_auth || first_bond != 1) {
+        return;
+    }
+    ble_bind_pair_waiting_auth = false;
+    ble_bind_pair_stop_timeout_timer();
+
+    if (g_ble_conn_id == 0 || addr == NULL) {
+        first_bond = 0;
+        return;
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] BLE配对失败 主动发72_05_10 flag=0");
+    sendParieSuccess(0, (bd_addr_t *)addr);
+    first_bond = 0;
+}
+
+void ble_bind_pair_on_disconnect(void)
+{
+    if (ble_bind_pair_waiting_auth) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] BLE断开 取消绑定配对超时定时器");
+    }
+    ble_bind_pair_stop_timeout_timer();
+}
+
+/**
+ * @brief 判断「首次绑定」前是否需要清除手表侧 BLE/BR 配对表
+ *
+ * 仅在「密钥状态不一致」时返回 true,例如:
+ * - 刚恢复出厂(手表 JSON 无绑定,但协议栈可能还有旧 key)
+ * - 手表协议栈里仍有配对记录
+ * - 当前链路已显示 PAIRED,但 phone_watch.json 无 MAC
+ *
+ * 若手机和手表都没有配对(干净首次绑定),返回 false,不要清配对,
+ * 否则会在 App 已连接时清 key,导致绑定中途报错。
+ */
+static bool ble_should_clear_watch_pairs_before_first_bind(const bd_addr_t *addr)
+{
+    if (uapi_dev_runtime_get_restore_factory_status() != 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] 需清配对: 原因=恢复出厂标记有效");
+        return true;
+    }
+
+    uint16_t paired_num = 0;
+    if (gap_get_paired_devices_num(&paired_num) && paired_num > 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] 需清配对: 原因=手表协议栈仍有配对数=%u", paired_num);
+        return true;
+    }
+
+    if (addr != NULL) {
+        gap_ble_pair_state_t pair_state = GAP_BLE_PAIR_NONE;
+        if (gap_ble_get_pair_state(addr, &pair_state) == ERRCODE_SUCC &&
+            pair_state == GAP_BLE_PAIR_PAIRED) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "[连接时序][App绑定] 需清配对: 原因=链路已PAIRED但JSON无绑定(密钥不一致)");
+            return true;
+        }
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 无需清配对: 手机/手表均为干净首次绑定状态");
+    return false;
+}
+
+/**
+ * @brief 清除手表侧 BLE + 经典蓝牙配对表(不能清除手机系统里的配对)
+ */
+static void ble_clear_watch_all_pairs(const char *reason)
+{
+    errcode_t ble_ret = gap_ble_remove_all_pairs();
+    bool br_ret = gap_remove_all_pairs();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 清除手表侧配对 原因=%s ble_ret=0x%x br_ret=%d",
+        reason, ble_ret, br_ret);
+}
+
 //确认配对指令
-uint8_t first_bond = 0;//是否第一次绑定 第一次绑定保存配对mac地址
+
+/**
+ * @brief 【步骤3】用户在手表上确认/拒绝绑定
+ * @param flag 1=同意绑定  0=拒绝
+ *
+ * 同意时:发 72 05 11 → 开 CTKD → 按需清手表配对 → 发起 BLE 系统配对
+ * 拒绝时:断连并清配对
+ */
 void comfirmPaire(uint8_t flag)
 {
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
@@ -920,29 +1119,69 @@ void comfirmPaire(uint8_t flag)
     memcpy(value+15,&tmp,2);
     value[17] = flag;
     value[18] = Calculate_CRC(value,1+17);
-    sendBleData(value,19);
+    errcode_t send_ret = sendBleData(value,19);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 已发72_05_11 flag=%u conn_id=%u ret=0x%x", flag, g_ble_conn_id, send_ret);
     if(flag == 1)
     {
         first_bond = 1;
 
-        if(get_ble_pair())
-        {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP," gap_ble_pair \r\n");
+        bd_addr_t addr={0};
+        get_phone_addr(&addr,g_ble_conn_id);
 
-            bd_addr_t addr={0};
-            get_phone_addr(&addr,g_ble_conn_id);
+        set_ctkd_flag(true);
+        errcode_t ctkd_ret = gap_ble_set_ctkd_enable(true);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] 用户确认后开启CTKD ret=0x%x ios安卓=%u", ctkd_ret, get_ble_pair());
+
+        if (get_ble_pair()) {
+            /* iOS:由手表发起 BLE 配对 */
+            gap_ble_pair_state_t pair_state = GAP_BLE_PAIR_NONE;
+            (void)gap_ble_get_pair_state(&addr, &pair_state);
+            if (pair_state != GAP_BLE_PAIR_PAIRED && pair_state != GAP_BLE_PAIR_PAIRING) {
+                errcode_t code = gap_ble_pair_remote_device(&addr);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "[连接时序][App绑定] iOS发起BLE配对 ret=0x%x pair_state=%u", code, pair_state);
+            } else {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "[连接时序][App绑定] iOS已配对/配对中 pair_state=%u 跳过重复配对", pair_state);
+            }
+        } else {
+            /*
+             * 【安卓首次绑定】
+             * - 干净环境(系统蓝牙无配对、手表无 key):只 gap_ble_pair_remote_device,不清配对
+             * - 密钥残留(恢复出厂/手表有旧 key):先清手表配对再发起配对
+             * - 不在此处重复清配对,避免 App 已连上时清 key 导致绑定失败
+             */
+            bool need_clear = ble_should_clear_watch_pairs_before_first_bind(&addr);
+            if (need_clear) {
+                ble_clear_watch_all_pairs("comfirmPaire安卓首次绑定-密钥不一致");
+            }
 
-            errcode_t code = gap_ble_pair_remote_device(&addr);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                "[连接时序][App绑定] 发起BLE配对 调用方=comfirmPaire ret=0x%x", code);
-            if(code!=ERRCODE_SUCC)
-            {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"gap_ble_pair_remote_device fail %X\r\n",code);
+            gap_ble_pair_state_t pair_state = GAP_BLE_PAIR_NONE;
+            (void)gap_ble_get_pair_state(&addr, &pair_state);
+
+            if (need_clear || (pair_state != GAP_BLE_PAIR_PAIRED &&
+                pair_state != GAP_BLE_PAIR_PAIRING)) {
+                errcode_t code = gap_ble_pair_remote_device(&addr);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "[连接时序][App绑定] 安卓发起BLE系统配对 need_clear=%d pair_state=%u ret=0x%x",
+                    need_clear, pair_state, code);
+            } else {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "[连接时序][App绑定] 安卓已配对/配对中 pair_state=%u 跳过重复发起配对",
+                    pair_state);
             }
         }
+        /*
+         * 步骤5: auth_complete → sendParieSuccess(72_05_10)
+         * 步骤6: pair_result → CTKD/BR + 跳主界面
+         * 若超时未收到 auth_complete(如手机系统仍保留旧配对),主动发 72_05_10 flag=0
+         */
+        ble_bind_pair_start_timeout_timer();
 
-        
     }else{
+        ble_bind_pair_on_disconnect();
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
             "[连接时序][App绑定] 用户拒绝配对 将断开并清除配对信息");
         first_bond = 0;
@@ -1117,6 +1356,13 @@ void getPhoneMac(uint8_t *data, uint8_t *phoneMac)
 
         mac_array_len = cJSON_GetArraySize(mac_node);
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[MAC解析] MAC数组长度:%d(期望6)", mac_array_len);
+        if (mac_array_len == 0) {
+            /* App 重装后常见 mac:[],视为未携带 MAC,走本地 save_mac 比对 */
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[MAC解析] MAC数组为空,按未携带MAC处理(App重装场景)");
+            memset(phoneMac, 0, 6);
+            cJSON_Delete(root);
+            return;
+        }
         if (mac_array_len != 6) {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[MAC解析] MAC数组长度异常,非6字节");
             memset(phoneMac, 0, 6);
@@ -1186,13 +1432,11 @@ void GetwatchSaveMac(uint8_t *mac,uint8_t *mactype)//获取手表本地保存的
                   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"watch MAC地址: ");
                 cJSON* macElement = NULL;
                 cJSON_ArrayForEach(macElement, modifiedJson) {
-                    if (cJSON_IsNumber(macElement)) {
+                    if (cJSON_IsNumber(macElement) && count < 6) {
                           WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"%d", macElement->valueint);
-                        if ((macElement->prev != NULL)) {
-                            mac_tmp[count] = macElement->valueint;
-                            count++;
-                              WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,", ");
-                        }
+                        mac_tmp[count] = (uint8_t)macElement->valueint;
+                        count++;
+                          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,", ");
                     }
                 }
                   WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"\n");
@@ -1421,16 +1665,122 @@ void set_ctkd_flag(bool flag)
 bool get_ctkd_flag(void)
 {
     return true;//ctkd_flag_ble;
+} 
+
+static bool ble_mac_all_zero(const uint8_t *mac)
+{
+    if (mac == NULL) {
+        return true;
+    }
+    return (mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]) == 0;
+}
+
+static bool ble_mac_equal(const uint8_t *a, const uint8_t *b)
+{
+    uint8_t rev_b[BD_ADDR_LEN];
+    uint8_t rev_a[BD_ADDR_LEN];
+
+    if (a == NULL || b == NULL) {
+        return false;
+    }
+    if (memcmp(a, b, BD_ADDR_LEN) == 0) {
+        return true;
+    }
+    for (uint8_t i = 0; i < BD_ADDR_LEN; i++) {
+        rev_b[i] = b[BD_ADDR_LEN - 1 - i];
+        rev_a[i] = a[BD_ADDR_LEN - 1 - i];
+    }
+    return (memcmp(a, rev_b, BD_ADDR_LEN) == 0) || (memcmp(rev_a, b, BD_ADDR_LEN) == 0);
 }
 
+static bool ble_app_phone_name_matches_saved(const uint8_t *data)
+{
+    bool matched = false;
+
+    if (data == NULL) {
+        return false;
+    }
+
+    cJSON *root = cJSON_Parse((const char *)data);
+    if (root == NULL) {
+        return false;
+    }
+
+    cJSON *pn = cJSON_GetObjectItem(root, "pn");
+    if (cJSON_IsString(pn) && pn->valuestring != NULL) {
+        uint8_t *saved_name = GetwatchSaveName();
+        if (saved_name != NULL) {
+            matched = (strcmp(pn->valuestring, (char *)saved_name) == 0);
+            ym_free(saved_name);
+        }
+    }
+
+    cJSON_Delete(root);
+    return matched;
+}
+
+
+/**
+ * @brief 【步骤2-分支】同机重连:回复 bond=0x02,不走首次绑定 UI
+ *
+ * 触发条件(sendBindInfor 内):
+ * - App 上报 MAC 与 phone_watch.json 里 save_mac 一致
+ * - App 重装 mac:[] 但 BLE 对端地址与 save_mac 一致
+ * - App 重装 mac:[] 且手机名 pn 与本地记录一致
+ */
+static void ble_reply_same_phone_reconnect(uint8_t *value, const char *reason)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+        "[连接时序][App绑定] 判定=同机重连(bond=0x02) 原因=%s", reason);
+
+    if (get_ble_pair()) {
+        set_ctkd_flag(true);
+        errcode_t ret = gap_ble_set_ctkd_enable(true);
+        if (ret != ERRCODE_SUCC) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 同机回连 CTKD使能失败 0x%X", ret);
+        }
+    } else {
+        errcode_t ret = gap_ble_set_ctkd_enable(true);
+        if (ret != ERRCODE_SUCC) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 同机回连 CTKD使能失败 0x%X", ret);
+        }
+    }
+
+    if (get_ble_pair()) {
+        bd_addr_t addr = {0};
+        get_phone_addr(&addr, g_ble_conn_id);
+        errcode_t code = gap_ble_pair_remote_device(&addr);
+        if (code != ERRCODE_SUCC) {
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gap_ble_pair_remote_device fail %X\r\n", code);
+        }
+    }
+
+    value[17] = 0x02;
+    value[18] = Calculate_CRC(value, 18);
+    sendBleData(value, 19);
+}
+
+/**
+ * @brief 【步骤2】比对 App 上报 JSON 与本地 phone_watch.json,决定 bond 并回复 72 02 10
+ *
+ * 流程概要:
+ * 1. 读本地 save_mac(GetwatchSaveMac)
+ * 2. 读 App JSON 里的 mac(getPhoneMac)
+ * 3. save_mac 全 0 → bond=0x01 首次绑定 → 发 72 02 10 → 弹绑定 UI(等 comfirmPaire)
+ * 4. save_mac 有值 → 比对 MAC/手机名 → bond=0x02 同机回连 或 bond=0x03 冲突
+ *
+ * 重要:首次绑定 bond=0x01 时不在此处清手表配对!
+ * App 已通过 BLE 连上,过早 gap_ble_remove_all_pairs 会破坏链路,导致 App 绑定报错。
+ * 清配对仅在 comfirmPaire() 用户确认后、且检测到密钥残留时执行。
+ */
 void sendBindInfor(uint8_t *data)
 {
     // 1. 入参校验(新增:防止空指针)
     if (data == NULL) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 入参data为空,直接返回");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 入参data为空,直接返回");
         return;
     }
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 开始处理绑定信息,入参data有效");
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 开始处理绑定信息,入参data有效");
 
     // 初始化基础指令缓冲区(保持原有)
     uint8_t value[19] = {0};
@@ -1462,7 +1812,7 @@ void sendBindInfor(uint8_t *data)
     
     // 获取手表本地MAC - 添加错误日志
     GetwatchSaveMac(&save_mac,&MacType);
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 手表本地保存MAC: %02X:%02X:%02X:%02X:%02X:%02X, MAC类型: %d",
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 手表本地保存MAC: %02X:%02X:%02X:%02X:%02X:%02X, MAC类型: %d",
                    save_mac[0], save_mac[1], save_mac[2], save_mac[3], save_mac[4], save_mac[5], MacType);
     
     // 获取手机MAC - 添加错误日志
@@ -1487,7 +1837,7 @@ void sendBindInfor(uint8_t *data)
         value[17] = bond;//
         value[18] = Calculate_CRC(value,18);
         sendBleData(value,19);
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 发送首次绑定指令,CRC: 0x%02X", value[18]);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 发送首次绑定指令,CRC: 0x%02X", value[18]);
 
         #ifdef SUPPORT_DEVICE_PAIRING_NOTIFICATION
         #ifdef SUPPORT_A5133_SERVICE_BLE_PAIR
@@ -1496,25 +1846,20 @@ void sendBindInfor(uint8_t *data)
         // 获取手机名称长度和类型 - 添加错误日志
         devnamelen = 0;
         getPhoneNameLen(data,&devnamelen,&phone_type);
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 手机类型: %d(0=安卓,1=IOS),设备名称长度: %d", phone_type, devnamelen);
+        phoneType = phone_type; /* 供 sendParieSuccess 写入 phone_watch.json */
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 手机类型: %d(0=安卓,1=IOS),设备名称长度: %d", phone_type, devnamelen);
 
-        if(phone_type==0) // 安卓手机
-        {
-            unsigned int paired_devices_num=0;
-            bool gap_get_paired_result = gap_get_paired_devices_num(&paired_devices_num); // 重命名避免混淆
-            if(!gap_get_paired_result || paired_devices_num!=0 )
-            {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[Bind] 安卓手机:清除所有已配对设备,当前配对数: %d,获取状态: %d", paired_devices_num, gap_get_paired_result);
-                gap_remove_all_pairs();
-            }
-        }
+        /*
+         * 首次绑定 bond=0x01:此处只弹 UI,不清配对、不发起系统配对。
+         * 用户点确认后由 comfirmPaire() 发 72_05_11 并按需清配对+gap_ble_pair_remote_device。
+         */
 
         if(devnamelen > 0 )
         {
             devname = getPhoneName(data);
             if (devname != NULL)
             {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[Bind] 手机名称: %s, 长度: %d", devname, devnamelen);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[连接时序] 手机名称: %s, 长度: %d", devname, devnamelen);
                 uint8_t buf[devnamelen+2]; 
                 memset(buf,0,devnamelen+2);
                 buf[0] = DEVICEBIND ;
@@ -1523,42 +1868,31 @@ void sendBindInfor(uint8_t *data)
 
                 if(phone_type==1) // IOS手机
                 {
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 检测到IOS手机,开启配对模式");
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误/关键] 检测到IOS手机,开启配对模式");
                     ble_set_pair(1);
-                    
-                    ret = gap_ble_set_ctkd_enable(true);
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] IOS - gap_ble_set_ctkd_enable返回值: 0x%X", ret);
-                    if(ret != ERRCODE_SUCC) {
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] IOS - CTKD使能失败!");
-                    }
-                    set_ctkd_flag(true);
                 }
                 else // 安卓手机
                 {
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 检测到安卓手机,关闭配对模式");
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误/关键] 检测到安卓手机,关闭配对模式");
                     ble_set_pair(0);
-                    ret = gap_ble_set_ctkd_enable(true);
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 安卓 - gap_ble_set_ctkd_enable返回值: 0x%X", ret);
-                    if(ret != ERRCODE_SUCC) {
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 安卓 - CTKD使能失败!");
-                    }
                 }
+                /* CTKD 延后到 comfirmPaire 用户确认后再开,避免绑定弹窗前就触发系统配对 */
                 
                 // 发布绑定事件 - 添加错误日志
                 CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,(uint8_t *)buf,devnamelen+2);
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 发布设备绑定事件,数据长度: %d", devnamelen+2);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误/关键] 发布设备绑定事件,数据长度: %d", devnamelen+2);
                 
                 // 释放内存 - 增加空指针校验
                 if(devname)
                 {   
                     ym_free(devname);
                     devname = NULL;
-                    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Bind] 已释放手机名称内存");
+                    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[连接时序] 已释放手机名称内存");
                 }
             }
             else
             {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 获取手机名称失败!devname为空");
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误] 获取手机名称失败!devname为空");
                 uint8_t buf[2]; 
                 memset(buf,0,2);
                 buf[0] = DEVICEBIND;
@@ -1568,7 +1902,7 @@ void sendBindInfor(uint8_t *data)
         }
         else
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 手机名称长度为0,无法获取设备名称");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误] 手机名称长度为0,无法获取设备名称");
             uint8_t buf[2]; 
             memset(buf,0,2);
             buf[0] = DEVICEBIND;
@@ -1583,89 +1917,46 @@ void sendBindInfor(uint8_t *data)
     }
     else // 场景2:手表本地有保存的MAC
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 手表本地有绑定MAC,进入MAC比对流程");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 手表本地有绑定MAC,进入MAC比对流程");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 手机MAC: %02X:%02X:%02X:%02X:%02X:%02X",
+                   copare_mac[0], copare_mac[1], copare_mac[2], copare_mac[3], copare_mac[4], copare_mac[5]);
         
-        // 子场景2.1:手机下发MAC为空
-        if(copare_mac[0] == 0 && copare_mac[1] == 0 && copare_mac[2] == 0 && copare_mac[3] == 0 && copare_mac[4] == 0 && copare_mac[5] == 0)
+        // 子场景2.1:App 未带 MAC(mac:[] / 全0,常见于卸载重装)
+        if (ble_mac_all_zero(copare_mac))
         {
-            /* App 未带 MAC:用当前 BLE 连接对端地址与本地已保存 MAC 比对(如重装 App 后系统仍配对) */
             bd_addr_t peer = {0};
             get_phone_addr(&peer, g_ble_conn_id);
-            bool peer_addr_valid = (peer.addr[0] | peer.addr[1] | peer.addr[2] | peer.addr[3] | peer.addr[4] |
-                peer.addr[5]) != 0;
-            if (peer_addr_valid && memcmp(peer.addr, save_mac, BD_ADDR_LEN) == 0) {
-                if (get_ble_pair()) {
-                    set_ctkd_flag(true);
-                    errcode_t ret = gap_ble_set_ctkd_enable(true);
-                    (void)ret;
-                } else {
-                    errcode_t ret = gap_ble_set_ctkd_enable(true);
-                    (void)ret;
-                }
-                if (get_ble_pair()) {
-                    bd_addr_t addr = {0};
-                    get_phone_addr(&addr, g_ble_conn_id);
-                    errcode_t code = gap_ble_pair_remote_device(&addr);
-                    if (code != ERRCODE_SUCC) {
-                        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gap_ble_pair_remote_device fail %X\r\n", code);
-                    }
-                }
-                bond = 0x02;
-                value[17] = bond;
-                value[18] = Calculate_CRC(value, 18);
-                sendBleData(value, 19);
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "[连接时序][App绑定] App未带MAC 本地save_mac=%02X:%02X:%02X:%02X:%02X:%02X BLE对端=%02X:%02X:%02X:%02X:%02X:%02X",
+                save_mac[0], save_mac[1], save_mac[2], save_mac[3], save_mac[4], save_mac[5],
+                peer.addr[0], peer.addr[1], peer.addr[2], peer.addr[3], peer.addr[4], peer.addr[5]);
+
+            if (!ble_mac_all_zero(save_mac) && !ble_mac_all_zero(peer.addr) &&
+                ble_mac_equal(peer.addr, save_mac)) {
+                ble_reply_same_phone_reconnect(value, "BLE对端地址与本地save_mac一致");
+                return;
+            }
+
+            if (!ble_mac_all_zero(save_mac) && ble_app_phone_name_matches_saved(data)) {
+                /* 卸载重装:App 无 MAC,但手机名与本地绑定记录一致,以 save_mac 为准判定同机 */
+                ble_reply_same_phone_reconnect(value, "App重装无MAC且手机名与本地save_mac记录一致");
                 return;
             }
+
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "[连接时序][App绑定] App未带MAC且无法与save_mac匹配 本地=%02X:%02X:%02X:%02X:%02X:%02X",
+                save_mac[0], save_mac[1], save_mac[2], save_mac[3], save_mac[4], save_mac[5]);
             bond = 0x03;
         } 
         else 
         {
-            int result = memcmp(copare_mac,save_mac,6);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] MAC比对结果: %d(0=一致,非0=不一致)", result);
-            
-            if(result == 0) // MAC一致(同一手机)
-            {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 手机MAC与手表保存MAC一致,判定为同一手机绑定");
-                
-                if(get_ble_pair())
-                {
-                    set_ctkd_flag(true);
-                    ret = gap_ble_set_ctkd_enable(true);
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 同一手机-开启CTKD返回值: 0x%X", ret);
-                    if(ret != ERRCODE_SUCC) {
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 同一手机-CTKD使能失败!");
-                    }
-                }
-                else
-                {
-                    ret = gap_ble_set_ctkd_enable(true);
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 同一手机-关闭配对模式-CTKD返回值: 0x%X", ret);
-                    if(ret != ERRCODE_SUCC) {
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 同一手机-CTKD使能失败!");
-                    }
-                }
+            bool mac_match = ble_mac_equal(copare_mac, save_mac);
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] MAC比对结果: %s",
+                mac_match ? "一致" : "不一致");
 
-                if(get_ble_pair())
-                {
-                    bd_addr_t addr={0};
-                    get_phone_addr(&addr,g_ble_conn_id);
-                    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Bind] 尝试配对远程设备,地址: %02X:%02X:%02X:%02X:%02X:%02X",
-                                   addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]);
-                    
-                    ret = gap_ble_pair_remote_device(&addr);
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 配对远程设备返回值: 0x%X", ret);
-                    if(ret != ERRCODE_SUCC) {
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 配对远程设备失败!错误码: 0x%X", ret);
-                    }
-                }
-        
-                bond = 0x02;//手表与该手机绑定过
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                    "[连接时序][App绑定] 判定=同机重连(bond=0x02) 将发起BLE配对");
-                value[17] = bond;//
-                value[18] = Calculate_CRC(value,18);
-                sendBleData(value,19);
-                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Bind] 发送同一手机绑定指令,CRC: 0x%02X", value[18]);
+            if (mac_match) // App 上报 MAC 与本地 save_mac 一致
+            {
+                ble_reply_same_phone_reconnect(value, "App上报MAC与本地save_mac一致");
                 return;
             }
             else // MAC不一致(其他手机)
@@ -1677,15 +1968,15 @@ void sendBindInfor(uint8_t *data)
         }
     }
   
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[Bind] 最终bond标识: %d,first_bond: %d", bond, first_bond);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[连接时序] 最终bond标识: %d,first_bond: %d", bond, first_bond);
    
     // 场景3:bond=0x03(其他手机绑定)- 发布解绑事件
     if(bond == 0x03)
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 进入其他手机绑定流程,发布解绑事件");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误] 进入其他手机绑定流程,发布解绑事件");
         devnamelen = 0;
         GetwatchSaveNameLen(&devnamelen);
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind] 手表保存的手机名称长度: %d", devnamelen);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 手表保存的手机名称长度: %d", devnamelen);
         
         if(devnamelen > 0)
         {   
@@ -1697,19 +1988,19 @@ void sendBindInfor(uint8_t *data)
                 buf[0] = DEVICEUNBIND ;
                 buf[1] = devnamelen;
                 memcpy(buf+2,devname,devnamelen);
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 发布设备解绑事件,解绑设备名称: %s,长度: %d", devname, devnamelen+2);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误/关键] 发布设备解绑事件,解绑设备名称: %s,长度: %d", devname, devnamelen+2);
                 CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,(uint8_t *)buf,devnamelen+2);
                 
                 if(devname)
                 {
                     ym_free(devname);
                     devname = NULL;
-                    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[Bind] 已释放解绑设备名称内存");
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序] 已释放解绑设备名称内存");
                 }
             }
             else
             {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 获取手表保存的手机名称失败!devname为空");
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误] 获取手表保存的手机名称失败!devname为空");
                 uint8_t buf[2]; 
                 memset(buf,0,2);
                 buf[0] = DEVICEUNBIND;
@@ -1719,7 +2010,7 @@ void sendBindInfor(uint8_t *data)
         }
         else
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误] 手表保存的手机名称长度为0,发布空解绑事件");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误] 手表保存的手机名称长度为0,发布空解绑事件");
             uint8_t buf[2]; 
             memset(buf,0,2);
             buf[0] = DEVICEUNBIND;
@@ -1732,9 +2023,15 @@ void sendBindInfor(uint8_t *data)
     value[17] = bond;
     value[18] = Calculate_CRC(value,18);
     sendBleData(value,19);
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Bind][错误/关键] 发送最终绑定指令,bond标识: %d,CRC: 0x%02X", bond, value[18]);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[连接时序][错误/关键] 发送最终绑定指令,bond标识: %d,CRC: 0x%02X", bond, value[18]);
 }
 
+/**
+ * @brief 【步骤1】App 写 2AE4 下发手机 JSON(73 02 10),手表入口
+ *
+ * CRC 通过 → sendBindInfor() 走 MAC 比对
+ * CRC 失败 → 直接回 72 02 10 bond=0x00(App 会提示绑定/校验错误)
+ */
 void SetPhoneInfo(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totalData,uint8_t crcvalue)//获取手机信息
 {
     uint8_t value[19];
@@ -1754,6 +2051,8 @@ void SetPhoneInfo(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totalData,uin
     {
         sendBindInfor(data);
     }else{
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "[连接时序][App绑定] SetPhoneInfo CRC失败 回bond=0x00 App会报绑定错误");
         value[17] = 0x00;
         value[18] = Calculate_CRC(value,18);
         sendBleData(value,19);
@@ -1761,6 +2060,17 @@ void SetPhoneInfo(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totalData,uin
 }
 
 
+/**
+ * @brief 【步骤5】BLE 系统配对成功后,向 App 发送 72 05 10 并写入 phone_watch.json
+ *
+ * 前置条件(三者同时满足才会写 JSON):
+ * - first_bond == 1  (用户在 comfirmPaire 里点了同意)
+ * - phoneDataFlag == 1 (已收到 73 02 10)
+ * - g_ble_conn_id != 0 (BLE 仍连接,否则 App 收不到 72_05_10)
+ *
+ * @param flag 1=配对成功  0=配对失败
+ * @param addr 手机 BLE 地址(写入 JSON 的 mac 字段)
+ */
 void sendParieSuccess(uint8_t flag,bd_addr_t *addr)//发送配对成功指令to app
 {
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sendParieSuccess:0x%x-0x%x-0x%x-0x%x-0x%x-0x%x\r\n",addr->addr[0],addr->addr[1],addr->addr[2],addr->addr[3],addr->addr[4],addr->addr[5]);
@@ -1774,7 +2084,8 @@ void sendParieSuccess(uint8_t flag,bd_addr_t *addr)//发送配对成功指令to
     if(first_bond == 1 && phoneDataFlag == 1)//第一次连接绑定
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-            "[连接时序][App绑定] 发送72_05_10成功 首次绑定完成 conn_id=%u", g_ble_conn_id);
+            "[连接时序][App绑定] 发送72_05_10 %s conn_id=%u flag=%u",
+            flag ? "成功" : "失败", g_ble_conn_id, flag);
         set_ble_falg(1);
         uint8_t value[25];
         uint8_t length = 0;
@@ -1847,6 +2158,7 @@ void sendParieSuccess(uint8_t flag,bd_addr_t *addr)//发送配对成功指令to
             value[length] = crcvalue;
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sendParieSuccess:%d length:%d crcvalue:%d",sizeof(value),length,crcvalue );
             sendBleData(value,length+1);
+            /* 主界面跳转改到 svr_pair_result_cbt_cb:等手机系统 BLE 配对完成并触发 CTKD/BR 后再进表盘 */
         }else{
             length = 18;
             uint8_t crcvalue = Calculate_CRC(value,length);
index aa279b5..1da48bb 100644 (file)
@@ -794,6 +794,9 @@ void getDeviceState(void);
 void cleanUnbindInfor(uint8_t flag);//和旧手机解绑清除配对信息 0不清除配对信息 1清除配对信息重启
 
 void comfirmPaire(uint8_t flag);//发送确认配对指令 1确认配对 0取消配对
+void ble_bind_pair_on_auth_complete(void);//auth_complete 成功时取消绑定配对超时定时器
+void ble_bind_pair_on_pair_failed(const bd_addr_t *addr);//BLE 配对失败时主动发 72_05_10 flag=0
+void ble_bind_pair_on_disconnect(void);//BLE 断开时取消绑定配对超时定时器
 
 void cameraSend(uint8_t flag);//发送拍照指令给app 2进行拍照 3退出拍照界面设备发给app
 
@@ -835,6 +838,7 @@ void cancel_AI_cur_chat_(void);
 void GetCurDataCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totaldata,uint8_t crcvalue);
 
 bool get_ctkd_flag(void);
+void set_ctkd_flag(bool flag);
 
 void Watch_SendDial_ToAppCmd(void);
 
index 0b603b7..24666a5 100644 (file)
@@ -692,6 +692,7 @@ void svr_ble_connstate_change_cb(unsigned short conn_id, bd_addr_t *addr, gap_bl
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
                 "[连接时序][BLE链路] 断开处理 决策=重启广播 原因=主连接断开或无任何BLE连接 "\r
                 "conn_id=%u g_ble_conn_id=%u", conn_id, g_ble_conn_id);\r
+            ble_bind_pair_on_disconnect();\r
             free_ble_data(); \r
                 \r
             ble_disconnect_ok();\r
@@ -911,7 +912,13 @@ void svr_pair_result_cbt_cb(uint16_t conn_id, const bd_addr_t *addr, errcode_t s
             }\r
             else\r
             { \r
-                if(get_br_is_pair())\r
+                if((cm_get_A2DP_switch() || cm_get_HFP_switch()) && addr != NULL)\r
+                {\r
+                    int ret = gap_reconnect_media_device(addr);\r
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                        "[连接时序][BR回连] 触发方=BLE配对成功+CTKD(安卓) 动作=gap_reconnect_media_device ret=0x%x", ret);\r
+                }\r
+                else if(get_br_is_pair())\r
                 {\r
                     bd_addr_t bdaddr={0};\r
                     uapi_get_br_address(&bdaddr);\r
@@ -944,13 +951,18 @@ void svr_pair_result_cbt_cb(uint16_t conn_id, const bd_addr_t *addr, errcode_t s
                 "[连接时序][BR回连] 跳过 原因=CTKD未开或蓝牙总开关关闭 ctkd=%d bt开关=%d",\r
                 get_ctkd_flag(), uapi_dev_runtime_get_bt_powerstat());\r
         }\r
+#ifdef BLE_INSTRUCT\r
         hand_watch_first_time_Paired();\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+            "[连接时序][App绑定] BLE配对成功 已触发跳转主界面 hand_watch_first_time_Paired");\r
+#endif\r
 \r
     }\r
     else\r
     {\r
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
             "[连接时序][BLE配对] 失败 后续不会触发BR回连 status=0x%x", status);\r
+        ble_bind_pair_on_pair_failed(addr);\r
     }\r
 }\r
  \r
@@ -1838,193 +1850,149 @@ errcode_t svr_ble_bt_gatts_noyify_AI(uint8_t *data, uint16_t data_len)//这里
     return ret;  \r
 }\r
 \r
-errcode_t svr_ble_read_data_value_updata_noyify(void)//2ae2\r
+#define BLE_2AE2_PAYLOAD_LEN 20\r
+\r
+static void ble_fill_2ae2_device_info(uint8_t *payload, bool use_test_power, uint8_t test_power)\r
 {\r
-    gatts_ntf_ind_t data_info;\r
-    data_info.attr_handle = data2ae2Cmd;\r
-    static uint8_t battery_point_val[20] = {0};\r
-    // 获取电池电压值\r
     float voltage = 0.0F;\r
-    uint8_t power = 0;\r
-    power =battery_get_voltage(&voltage);\r
-    battery_point_val[0] =power;//power ;//power;//电量90\r
+    if (use_test_power) {\r
+        payload[0] = test_power;\r
+    } else {\r
+        payload[0] = battery_get_voltage(&voltage);\r
+    }\r
+\r
     uint16_t dial = ble_get_dial_id();\r
-    memcpy_s(&battery_point_val[1],2,&dial,2);\r
+    memcpy_s(&payload[1], 2, &dial, 2);\r
 \r
-    uint8_t _major,_mid,_minor;\r
-    uapi_get_fw_version(&_major,&_mid,&_minor);\r
-\r
-    battery_point_val[3] = _major;//固件版本号\r
-    battery_point_val[4] = _mid;\r
-    battery_point_val[5] = _minor;\r
+    uint8_t _major, _mid, _minor;\r
+    uapi_get_fw_version(&_major, &_mid, &_minor);\r
+    payload[3] = _major;\r
+    payload[4] = _mid;\r
+    payload[5] = _minor;\r
 \r
     bd_addr_t addr_info;\r
-    errcode_t ret = gap_ble_get_local_addr(&addr_info);\r
-    battery_point_val[6] = addr_info.addr[5];\r
-    battery_point_val[7] = addr_info.addr[4];\r
-    battery_point_val[8] = addr_info.addr[3];\r
-    battery_point_val[9] = addr_info.addr[2];\r
-    battery_point_val[10] = addr_info.addr[1];\r
-    battery_point_val[11] = addr_info.addr[0];\r
+    (void)gap_ble_get_local_addr(&addr_info);\r
+    payload[6] = addr_info.addr[5];\r
+    payload[7] = addr_info.addr[4];\r
+    payload[8] = addr_info.addr[3];\r
+    payload[9] = addr_info.addr[2];\r
+    payload[10] = addr_info.addr[1];\r
+    payload[11] = addr_info.addr[0];\r
+\r
+    payload[12] = 0;\r
+    payload[13] = 0;\r
+#if defined(BOARD_W9)\r
+    payload[14] = 6;\r
+    payload[15] = 6;\r
+#else\r
+    payload[14] = 5;\r
+    payload[15] = 5;\r
+#endif\r
+    payload[16] = 0;\r
+    payload[17] = 1;\r
+    payload[18] = 0;\r
+    payload[19] = 1;\r
+}\r
 \r
-    battery_point_val[12] = 0;//消息推送开关 默认是关闭 0\r
-    battery_point_val[13] = 0;//多媒体开关\r
-    \r
-    #if defined(BOARD_W9) \r
-    battery_point_val[14] = 6;//客户编号\r
-    battery_point_val[15] = 6;//产品编号\r
-    // #elif defined(BOARD_N9) \r
-    // battery_point_val[14] = 7;//客户编号\r
-    // battery_point_val[15] = 7;//产品编号\r
-    #else\r
-    battery_point_val[14] = 5;//客户编号\r
-    battery_point_val[15] = 5;//产品编号\r
-    #endif\r
+static errcode_t ble_send_2ae2_read_response(uint8_t server_id, uint16_t conn_id,\r
+    gatts_req_read_cb_t *read_cb_para, const uint8_t *payload)\r
+{\r
+    gatts_send_rsp_t rsp = {0};\r
+    rsp.request_id = read_cb_para->request_id;\r
+    rsp.offset = read_cb_para->offset;\r
 \r
-    battery_point_val[16] = 0;//硬件版本号\r
-    battery_point_val[17] = 1;\r
+    if (read_cb_para->offset >= BLE_2AE2_PAYLOAD_LEN) {\r
+        rsp.status = GATT_STATUS_INVALID_OFFSET;\r
+        rsp.value_len = 0;\r
+        rsp.value = NULL;\r
+    } else {\r
+        rsp.status = GATT_STATUS_SUCCESS;\r
+        rsp.value_len = BLE_2AE2_PAYLOAD_LEN - read_cb_para->offset;\r
+        rsp.value = (uint8_t *)(payload + read_cb_para->offset);\r
+    }\r
 \r
-    battery_point_val[18] = 0;//ble版本号\r
-    battery_point_val[19] = 1;\r
+    errcode_t ret = gatts_send_response(server_id, conn_id, &rsp);\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+        "[连接时序][2AE2] Read Response conn_id=%u need_rsp=%d offset=%u len=%u ret=0x%x",\r
+        conn_id, read_cb_para->need_rsp, read_cb_para->offset, rsp.value_len, ret);\r
+    return ret;\r
+}\r
 \r
+errcode_t svr_ble_read_data_value_updata_noyify(void)//2ae2\r
+{\r
+    gatts_ntf_ind_t data_info;\r
+    data_info.attr_handle = data2ae2Cmd;\r
+    static uint8_t battery_point_val[BLE_2AE2_PAYLOAD_LEN] = {0};\r
 \r
+    ble_fill_2ae2_device_info(battery_point_val, false, 0);\r
     data_info.value = battery_point_val;\r
-    data_info.value_len = 20;\r
+    data_info.value_len = BLE_2AE2_PAYLOAD_LEN;\r
 \r
-    // if (g_ble_conn_id == 0)\r
-    // return 0;\r
-     \r
-     ret = gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, &data_info);\r
+    errcode_t ret = gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, &data_info);\r
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gatts_notify_indicate ret:0x%x. serverid:%u,conn_id:%u,handle:%u.data_len:%d", ret, g_ble_server_id,\r
-        g_ble_conn_id, g_ble_server_handle,20);\r
-    \r
-    return ret;  \r
+        g_ble_conn_id, g_ble_server_handle, BLE_2AE2_PAYLOAD_LEN);\r
+\r
+    return ret;\r
 }\r
 \r
 errcode_t svr_ble_read_data_value_updata_noyify_test(uint8_t test)//2ae2\r
 {\r
     gatts_ntf_ind_t data_info;\r
     data_info.attr_handle = data2ae2Cmd;\r
-    static uint8_t battery_point_val[20] = {0};\r
-\r
-    battery_point_val[0] =test;//power ;//power;//电量90\r
-\r
-    uint16_t dial = ble_get_dial_id();\r
-    memcpy_s(&battery_point_val[1],2,&dial,2);\r
-\r
-    uint8_t _major,_mid,_minor;\r
-    uapi_get_fw_version(&_major,&_mid,&_minor);\r
-\r
-    battery_point_val[3] = _major;//固件版本号\r
-    battery_point_val[4] = _mid;\r
-    battery_point_val[5] = _minor;\r
-\r
-    bd_addr_t addr_info;\r
-    errcode_t ret = gap_ble_get_local_addr(&addr_info);\r
-    battery_point_val[6] = addr_info.addr[5];\r
-    battery_point_val[7] = addr_info.addr[4];\r
-    battery_point_val[8] = addr_info.addr[3];\r
-    battery_point_val[9] = addr_info.addr[2];\r
-    battery_point_val[10] = addr_info.addr[1];\r
-    battery_point_val[11] = addr_info.addr[0];\r
-\r
-    battery_point_val[12] = 0;//消息推送开关 默认是关闭 0\r
-    battery_point_val[13] = 0;//多媒体开关\r
-\r
-    #if defined(BOARD_W9) \r
-    battery_point_val[14] = 6;//客户编号\r
-    battery_point_val[15] = 6;//产品编号\r
-    // #elif defined(BOARD_N9) \r
-    // battery_point_val[14] = 7;//客户编号\r
-    // battery_point_val[15] = 7;//产品编号\r
-    #else\r
-    battery_point_val[14] = 5;//客户编号\r
-    battery_point_val[15] = 5;//产品编号\r
-    #endif\r
-\r
-    battery_point_val[16] = 0;//硬件版本号\r
-    battery_point_val[17] = 1;\r
-\r
-    battery_point_val[18] = 0;//ble版本号\r
-    battery_point_val[19] = 1;\r
-\r
+    static uint8_t battery_point_val[BLE_2AE2_PAYLOAD_LEN] = {0};\r
 \r
+    ble_fill_2ae2_device_info(battery_point_val, true, test);\r
     data_info.value = battery_point_val;\r
-    data_info.value_len = 20;\r
-     ret = gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, &data_info);\r
+    data_info.value_len = BLE_2AE2_PAYLOAD_LEN;\r
+\r
+    errcode_t ret = gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, &data_info);\r
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gatts_notify_indicate ret:0x%x. serverid:%u,conn_id:%u,handle:%u.data_len:%d", ret, g_ble_server_id,\r
-        g_ble_conn_id, g_ble_server_handle,20);\r
-    \r
-    return ret;  \r
+        g_ble_conn_id, g_ble_server_handle, BLE_2AE2_PAYLOAD_LEN);\r
+\r
+    return ret;\r
 }\r
 \r
 static uint8_t flag=1;\r
 static void svr_ble_bt_gatts_req_read_cb(uint8_t server_id, uint16_t conn_id, gatts_req_read_cb_t *read_cb_para,\r
     errcode_t status)\r
 {\r
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "svr_ble_bt_gatts_req_read_cb ret:is_long:%d %d",read_cb_para->is_long,status);\r
-\r
-    //WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "svr_ble_bt_gatts_req_read_cb ret:is_long:%d  2ae2 %d read_cb_para->handle :%d",read_cb_para->is_long,data2ae2Cmd,read_cb_para->handle);\r
-    if(read_cb_para->handle==data2ae2Cmd && get_ble_connect() && status==0 )\r
-    {\r
-        g_ble_conn_id=conn_id;\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
-            "[连接时序][App识别] 标记主连接 来源=App读2AE4 conn_id=%u", conn_id);\r
-\r
-    static uint8_t battery_point_val[20] = {0};\r
-    // 获取电池电压值\r
-    float voltage = 0.0F;\r
-    uint8_t power = 0;\r
-    power =battery_get_voltage(&voltage);\r
-    battery_point_val[0] =power;//power ;//power;//电量90\r
-    uint16_t dial = ble_get_dial_id();\r
-    memcpy_s(&battery_point_val[1],2,&dial,2);\r
-\r
-    uint8_t _major,_mid,_minor;\r
-    uapi_get_fw_version(&_major,&_mid,&_minor);\r
+    if (read_cb_para == NULL) {\r
+        return;\r
+    }\r
 \r
-    battery_point_val[3] = _major;//固件版本号\r
-    battery_point_val[4] = _mid;\r
-    battery_point_val[5] = _minor;\r
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,\r
+        "svr_ble_bt_gatts_req_read_cb handle=%u 2ae2=%u is_long=%d need_rsp=%d status=0x%x ble连=%d",\r
+        read_cb_para->handle, data2ae2Cmd, read_cb_para->is_long, read_cb_para->need_rsp, status, get_ble_connect());\r
 \r
-    bd_addr_t addr_info;\r
-    errcode_t ret = gap_ble_get_local_addr(&addr_info);\r
-    battery_point_val[6] = addr_info.addr[5];\r
-    battery_point_val[7] = addr_info.addr[4];\r
-    battery_point_val[8] = addr_info.addr[3];\r
-    battery_point_val[9] = addr_info.addr[2];\r
-    battery_point_val[10] = addr_info.addr[1];\r
-    battery_point_val[11] = addr_info.addr[0];\r
+    if (read_cb_para->handle != data2ae2Cmd || data2ae2Cmd == 0) {\r
+        return;\r
+    }\r
+    if (status != ERRCODE_SUCC) {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+            "[连接时序][2AE2] 读请求失败 conn_id=%u status=0x%x", conn_id, status);\r
+        return;\r
+    }\r
 \r
-    battery_point_val[12] = 0;//消息推送开关 默认是关闭 0\r
-    battery_point_val[13] = 0;//多媒体开关\r
+    g_ble_conn_id = conn_id;\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+        "[连接时序][App识别] 标记主连接 来源=App读2AE2 conn_id=%u ble连=%d", conn_id, get_ble_connect());\r
 \r
-    #if defined(BOARD_W9) \r
-    battery_point_val[14] = 6;//客户编号\r
-    battery_point_val[15] = 6;//产品编号\r
-    // #elif defined(BOARD_N9) \r
-    // battery_point_val[14] = 7;//客户编号\r
-    // battery_point_val[15] = 7;//产品编号\r
-    #else\r
-    battery_point_val[14] = 5;//客户编号\r
-    battery_point_val[15] = 5;//产品编号\r
-    #endif\r
+    static uint8_t battery_point_val[BLE_2AE2_PAYLOAD_LEN] = {0};\r
+    ble_fill_2ae2_device_info(battery_point_val, false, 0);\r
 \r
-    battery_point_val[16] = 0;//硬件版本号\r
-    battery_point_val[17] = 1;\r
+    uapi_save_runtime_log(RUNTIME_LOG_BLE_APP_READ);\r
 \r
-    battery_point_val[18] = 0;//ble版本号\r
-    battery_point_val[19] = 1;\r
+    if (read_cb_para->need_rsp) {\r
+        (void)ble_send_2ae2_read_response(server_id, conn_id, read_cb_para, battery_point_val);\r
+    }\r
 \r
-    static gatts_ntf_ind_t  gatts_ntf_ind;\r
-    gatts_ntf_ind.attr_handle=read_cb_para->handle;\r
-    gatts_ntf_ind.value=battery_point_val;\r
-    gatts_ntf_ind.value_len=20;\r
-    // read_cb_para->need_rsp=0;\r
-    \r
-    uapi_save_runtime_log(RUNTIME_LOG_BLE_APP_READ);\r
-    gatts_notify_indicate(server_id,conn_id,&gatts_ntf_ind);\r
-}\r
+    gatts_ntf_ind_t gatts_ntf_ind = {0};\r
+    gatts_ntf_ind.attr_handle = read_cb_para->handle;\r
+    gatts_ntf_ind.value = battery_point_val;\r
+    gatts_ntf_ind.value_len = BLE_2AE2_PAYLOAD_LEN;\r
+    errcode_t ntf_ret = gatts_notify_indicate(server_id, conn_id, &gatts_ntf_ind);\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+        "[连接时序][2AE2] Notify conn_id=%u ret=0x%x", conn_id, ntf_ret);\r
 }\r
 \r
 \r
@@ -2103,11 +2071,14 @@ void svr_gap_ble_auth_complete_callback(uint16_t conn_id, const bd_addr_t *addr,
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
         "[连接时序][BLE配对] 鉴权完成 来源=协议栈 conn_id=%u status=0x%x g_ble_conn_id=%u",\r
         conn_id, status, g_ble_conn_id);\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sendParieSuccess");\r
-\r
 \r
-    sendParieSuccess(1,addr);\r
-    uapi_set_br_address(addr);\r
+    if (status == ERRCODE_SUCC && addr != NULL) {\r
+        ble_bind_pair_on_auth_complete();\r
+        sendParieSuccess(1, (bd_addr_t *)addr);\r
+        uapi_set_br_address(addr);\r
+    } else {\r
+        ble_bind_pair_on_pair_failed(addr);\r
+    }\r
 }\r
 \r
 static bool ble_adv_start=false;\r
@@ -2172,7 +2143,7 @@ void srv_ble_server_register_gatt_callbacks(void)
     gatts_register_callbacks(&g_ble_gatts_cbs);\r
 #else\r
     wrapper_gatts_register_callbacks(&g_ble_gatts_cbs);\r
-#endif\r
+#endif \r
     return;\r
 }\r
 static uint8_t g_server_id = 0;\r