-/*\r
- * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.\r
- * Description: BluetoothModel view\r
- * Author:\r
- * Create: 2021-10-13\r
- */\r
-#include <cstdint>\r
-#include "bluetooth/BluetoothModel.h"\r
-#include "bluetooth/BluetoothWrapper.h"\r
-#include "bluetooth/BluetoothPresenter.h"\r
-#include "connectnewphone/ConnectPhonePresenter.h"\r
-#include "player/BluetoothView.h"\r
-#include "bluetooth/BluetoothItemView.h"\r
-#include "player/PlayersModel.h"\r
-#include "phoneservice/PhoneAudio.h"\r
-#include "graphic_service.h"\r
-#include "msg_center.h"\r
-#include "bts_def.h"\r
-#include "bts_gatt_stru.h"\r
-#include "bts_a2dp_source.h"\r
-#include "bts_gatt_server.h"\r
-#include "bts_le_gap.h"\r
-#include "bts_spp.h"\r
-#include "osal_task.h"\r
-#ifdef SUPPORT_ALIPAY_SEC\r
-#include "alipay_feature.h"\r
-#endif\r
-#include "bts_a2dp_sink.h"\r
-#include "bts_feature.h"\r
-#include "bt_audio_hal_interface.h"\r
-#include "audio_manager_c_wrapper.h"\r
-#include "bts_avrcp_target.h"\r
-#include "msg_center_msg.h"\r
-#include "client/msg_center_client.h"\r
-#include "msg_center_protocol.h"\r
-#include "dfx_channel.h"\r
-#include "tcxo.h"\r
-#include "uiservice/ui_service.h"\r
-#include "network/network_listener.h"\r
-#if defined(SUPPORT_LWIP) && defined(SUPPORT_BREDR)\r
-#include "lwip_driver_adapter.h"\r
-#endif\r
-#include <bluetooth/BluetoothHeadsetEvent.h>\r
-#include "ln_api.h"\r
-#include "phoneservice/PhoneService.h"\r
-#include "thunderbird/include/ThunderBirdMainView.h"\r
-#include "thunderbird/include/ThunderBirdBlueView.h"\r
-#include <custom_utils.h>\r
-#include "ai_media.h"\r
-\r
-namespace OHOS {\r
-\r
-#define BT_SPP_TASK_STACK_SIZE 2048\r
-#define BT_SPP_TASK_PRI 20\r
-#define TEN 10\r
-\r
-constexpr uint16_t BLUETOOTH_MAX_NUM = 20;\r
-\r
-#define MEDIA_A2DP_SNK_INTERFACE 1\r
-osal_timer g_a2dp_stream_accept_timer = {nullptr, nullptr, 0, 0};\r
-#define A2DP_STREAM_ACCEPT_TIMER_PERIOD 500\r
-AudioFormatConfig g_audio_format_config = {AUDIO_DEFAULT, 0, 0};\r
-static uint16_t g_sample_svr_handle = 0;\r
-static uint16_t g_sample_characteristic_handle = 0;\r
-static uint16_t g_diag_characteristic_handle = 0;\r
-static uint16_t g_diag_desc_handle = 0;\r
-constexpr uint16_t g_sample_adv_id = 2;\r
-static bd_addr_t g_bd_addr = { 0 };\r
-\r
-void BluetoothModel::SetBluetoothCalleridStatus(int16_t value)\r
-{\r
- callerid = value;\r
-}\r
-\r
-int BluetoothModel::GetBluetoothCalleridStatus(void)\r
-{\r
- return callerid;\r
-}\r
-\r
-BluetoothModel::BluetoothModel()\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::BluetoothModel");\r
-}\r
-\r
-BluetoothModel *BluetoothModel::GetInstance(void)\r
-{\r
- static BluetoothModel instance;\r
- return &instance;\r
-}\r
-\r
-char* BluetoothModel::getWatchName(void)\r
-{\r
- return watchName;\r
-}\r
-\r
-void BluetoothModel::InitBluetoothInfo(void)\r
-{\r
- errcode_t ret;\r
- unsigned char nameLen = BD_NAME_LEN;\r
- memset_s(watchName, sizeof(watchName), 0, sizeof(watchName));\r
- ret = bluetooth_get_local_name((unsigned char *)watchName, &nameLen);\r
- // 为了实验室测试需要,客户需要自己修改\r
- if ((nameLen == strlen("WatchDemo") + 1) && (strcmp("WatchDemo", watchName) == 0)) {\r
- uint32_t currentUs = uapi_tcxo_get_us();\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "currentUs 0x%x", currentUs);\r
- // 设置蓝牙名称\r
- (void)sprintf_s(watchName, sizeof(watchName), "LN%x", (currentUs & 0xFFFF));\r
- ret = bluetooth_set_local_name((unsigned char*)watchName, strlen((char*)watchName) + 1);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bluetooth_set_local_name %s ret = %u", watchName, ret);\r
-\r
- // 设置蓝牙地址\r
- bd_addr_t addr = {{0x1C, 0x1D, 0x2B, 0x0, 0x0, 0x0} ,0};\r
- addr.addr[3] = currentUs & 0xFF;\r
- addr.addr[4] = (currentUs & 0XFF00) >> 8;\r
- addr.addr[5] = currentUs & 0xFF;\r
- ret = bluetooth_set_local_addr(addr.addr, BD_ADDR_LEN);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bluetooth_set_local_addr [0x%x:0x%x] ret = %u", addr.addr[0], addr.addr[1], ret);\r
- } else {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "watchName: %s", watchName);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "nameLen: %u", nameLen);\r
- }\r
-}\r
-\r
-void BluetoothModel::Init()\r
-{\r
-#ifndef SUPPORT_AUTO_OTA\r
- errcode_t ret;\r
-\r
- // 设置自动回连,ios一键双连依赖此配置\r
- bts_feature_t bts_feature = { 0 };\r
- bts_feature.bt_auto_reconnect_closed = 1;\r
- ret = bts_set_features(&bts_feature);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bt bts_set_features ret = %u", ret);\r
-\r
- ret = enable_bt_stack();\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bt enable_bt_stack ret = %u", ret);\r
-\r
- InitBluetoothInfo();\r
- BtInitCallBacks();\r
-\r
- InitBtHeadsetEvent(); // 蓝牙ct和tg适配初始化\r
- PhoneServiceInit();\r
- BtA2dpInit();\r
-#endif\r
-}\r
-\r
-void BluetoothModel::SetCaseListClear()\r
-{\r
- btScansDevicesList_.clear();\r
- SetUpConnedDevicesList();\r
-}\r
-\r
-// 检查扫描列表是否存在该设备\r
-bool BluetoothModel::CheckExistScanList(BluetoothCaseInfo caseInfo)\r
-{\r
- std::list<BluetoothCaseInfo>::iterator node = btScansDevicesList_.begin();\r
- if (btScansDevicesList_.empty()) {\r
- return false;\r
- }\r
- while (node != btScansDevicesList_.end()) {\r
- if ((caseInfo.addr[0] == node->addr[0]) && (caseInfo.addr[1] == node->addr[1])\r
- && (caseInfo.addr[2] == node->addr[2]) && (caseInfo.addr[3] == node->addr[3])\r
- && (caseInfo.addr[4] == node->addr[4]) && (caseInfo.addr[5] == node->addr[5])) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "true");\r
- return true;\r
- }\r
- node++;\r
- }\r
- return false;\r
-}\r
-\r
-void BluetoothModel::SetUpListCase()\r
-{\r
- SetCaseListClear();\r
-}\r
-\r
-std::list<BluetoothCaseInfo>& BluetoothModel::GetCase()\r
-{\r
- return btScansDevicesList_;\r
-}\r
-\r
-void BluetoothModel::AddCase(BluetoothCaseInfo caseInfo)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AddCase::caseInfo addr: %02x%02x%02x%02x%02x%02x",\r
- caseInfo.addr[5], caseInfo.addr[4], caseInfo.addr[3], /* mac下标 0 1 2 3 4 5 */\r
- caseInfo.addr[2], caseInfo.addr[1], caseInfo.addr[0]);\r
- if (btScansDevicesList_.size() >= BLUETOOTH_MAX_NUM) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "btScansDevicesList_.size is BLUETOOTH_MAX_NUM");\r
- return;\r
- } else {\r
- btScansDevicesList_.push_back(caseInfo);\r
- }\r
-}\r
-\r
-void BluetoothModel::SetScansCaseRssi(const bd_addr_t *bdAddr, int rssi)\r
-{\r
- for (auto it = btScansDevicesList_.begin(); it != btScansDevicesList_.end(); it++) {\r
- if ((it->addr[0] == bdAddr->addr[0]) && (it->addr[1] == bdAddr->addr[1])\r
- && (it->addr[2] == bdAddr->addr[2]) && (it->addr[3] == bdAddr->addr[3])\r
- && (it->addr[4] == bdAddr->addr[4]) && (it->addr[5] == bdAddr->addr[5])) {\r
- it->temp = rssi;\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "btScansDevicesList_ rssi:%d deviceName:%s", it->temp, it->deviceName);\r
- }\r
- }\r
-}\r
-\r
-\r
-bool CompBuletoothInfo(const BluetoothCaseInfo& a, const BluetoothCaseInfo& b)\r
-{\r
- if (a.temp > b.temp) {\r
- return true;\r
- }\r
- return false;\r
-}\r
-\r
-void BluetoothModel::SortScansCaseRssi()\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SortScansCaseRssi");\r
- btScansDevicesList_.sort(CompBuletoothInfo);\r
-}\r
-\r
-void BluetoothModel::ResetScanDevicesCase(const BluetoothCaseInfo& caseInfo)\r
-{\r
- for (auto it = btScansDevicesList_.begin(); it != btScansDevicesList_.end(); it++) {\r
- if ((it->addr[0] == caseInfo.addr[0]) && (it->addr[1] == caseInfo.addr[1])\r
- && (it->addr[2] == caseInfo.addr[2]) && (it->addr[3] == caseInfo.addr[3])\r
- && (it->addr[4] == caseInfo.addr[4]) && (it->addr[5] == caseInfo.addr[5])) {\r
- (void)memcpy_s(it->deviceName, BD_NAME_LEN,\r
- caseInfo.deviceName, BD_NAME_LEN);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ResetConnedDevicesCase deviceName:%s", it->deviceName);\r
- }\r
- }\r
-}\r
-\r
-/* 已配对设备队列 */\r
-void BluetoothModel::SetConnedDevicesListClear()\r
-{\r
- btConnedDevicesList_->Clear();\r
-}\r
-\r
-void BluetoothModel::SetUpConnedDevicesList()\r
-{\r
- if (btConnedDevicesList_ == nullptr) {\r
- btConnedDevicesList_ = new List<BluetoothCaseInfo>();\r
- if (btConnedDevicesList_ == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BluetoothModel btConnedDevicesList_ new fail");\r
- return;\r
- }\r
- SetConnedDevicesListClear();\r
- unsigned int connedDevicesNum = 0;\r
- bool ret = gap_get_paired_devices_num(&connedDevicesNum);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setup GetPariedDevicesNum ret = %d, num = %d", ret, connedDevicesNum);\r
-\r
- gap_paired_device_info_t *devInfo = (gap_paired_device_info_t*)malloc(sizeof(gap_paired_device_info_t) *connedDevicesNum);\r
- if (devInfo == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DevInfo malloc failed %u", sizeof(gap_paired_device_info_t) *connedDevicesNum);\r
- return;\r
- }\r
- ret = gap_get_paired_devices_list(devInfo, (int *)&connedDevicesNum);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetUpConnedDevicesList gap_get_paired_devices_list ret = %d", ret);\r
-\r
- BluetoothCaseInfo caseInfo{};\r
- for (int i = 0; i < static_cast<int>(connedDevicesNum); ++i) {\r
- if ((gap_get_device_class((const bd_addr_t *)devInfo[i].addr.addr) & 0x200) != 0) {\r
- continue;\r
- }\r
- (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN,\r
- devInfo[i].addr.addr, BD_ADDR_LEN);\r
- (void)memcpy_s(caseInfo.deviceName, BD_NAME_LEN,\r
- devInfo[i].device_name, BD_NAME_LEN);\r
- AddConnedDevicesCase(caseInfo);\r
- }\r
- free(devInfo);\r
- }\r
-}\r
-\r
-// 已连接设备队列\r
-void BluetoothModel::AddConnedDevicesCase(BluetoothCaseInfo caseInfo)\r
-{\r
- if (btConnedDevicesList_ == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "btConnedDevicesList_ nullptr");\r
- return;\r
- }\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddConnedDevicesCase::caseInfo addr: %02x%02x%02x%02x%02x%02x",\r
- caseInfo.addr[5], caseInfo.addr[4], caseInfo.addr[3], /* mac下标 0 1 2 3 4 5 */\r
- caseInfo.addr[2], caseInfo.addr[1], caseInfo.addr[0]);\r
- if (btConnedDevicesList_->Size() >= BLUETOOTH_MAX_NUM) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "btConnedDevicesList_->Size is BLUETOOTH_MAX_NUM");\r
- return;\r
- } else {\r
- btConnedDevicesList_->PushBack(caseInfo);\r
- }\r
-}\r
-\r
-List<BluetoothCaseInfo>& BluetoothModel::GetConnedDevicesCase()\r
-{\r
- // 确保已连接设备列表已经初始化\r
- if (btConnedDevicesList_ == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetConnedDevicesCase: btConnedDevicesList_ is nullptr, calling SetUpConnedDevicesList");\r
- SetUpConnedDevicesList();\r
- }\r
-\r
- // 如果仍然为空,返回一个静态空列表,防止野指针导致异常\r
- if (btConnedDevicesList_ == nullptr) {\r
- static List<BluetoothCaseInfo> emptyList;\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetConnedDevicesCase: btConnedDevicesList_ still nullptr, return empty list");\r
- return emptyList;\r
- }\r
-\r
- return *btConnedDevicesList_;\r
-}\r
-\r
-void BluetoothModel::SetBtStatus(void)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetBtStatus tempMacValue: %02x%02x%02x%02x%02x%02x",\r
- tempMacValue.addr[5], tempMacValue.addr[4], tempMacValue.addr[3], /* mac챐 0 1 2 3 4 5 */\r
- tempMacValue.addr[2], tempMacValue.addr[1], tempMacValue.addr[0]); /* mac챐 0 1 2 3 4 5 */\r
- aclConnected = bt_is_acl_connected((const bd_addr_t*)&tempMacValue.addr);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "aclConnected %d", aclConnected);\r
-}\r
-\r
-bool BluetoothModel::GetAclConnected(void)\r
-{\r
- return aclConnected;\r
-}\r
-\r
-void BluetoothModel::SetTempMacValue(BluetoothCaseInfo *caseInfo)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetTempMacValue: %02x%02x%02x%02x%02x%02x",\r
- caseInfo->addr[5], caseInfo->addr[4], caseInfo->addr[3], /* mac챐 0 1 2 3 4 5 */\r
- caseInfo->addr[2], caseInfo->addr[1], caseInfo->addr[0]); /* mac챐 0 1 2 3 4 5 */\r
- (void)memcpy_s(tempMacValue.addr, BD_ADDR_LEN,\r
- caseInfo->addr, BD_ADDR_LEN);\r
- (void)memcpy_s(tempMacValue.deviceName, BD_NAME_LEN,\r
- caseInfo->deviceName, BD_NAME_LEN);\r
-}\r
-\r
-BluetoothCaseInfo *BluetoothModel::GetTempMacValue(void)\r
-{\r
- return &tempMacValue;\r
-}\r
-\r
-// 设置最后连接的蓝牙设备地址\r
-void BluetoothModel::SetLastConnedAddr(const bd_addr_t *addr)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置最后连接的蓝牙设备地址: %02X:%02X:%02X:%02X:%02X:%02X",\r
- addr->addr[5], addr->addr[4], addr->addr[3], /* mac챐 0 1 2 3 4 5 */\r
- addr->addr[2], addr->addr[1], addr->addr[0]); /* mac챐 0 1 2 3 4 5 */\r
- (void)memcpy_s(lastConnedAddr.addr, BD_ADDR_LEN, addr->addr, BD_ADDR_LEN);\r
- if (addr != nullptr) {\r
- char lastConnedDeviceName[BD_NAME_LEN] = {0};\r
- snprintf(lastConnedDeviceName, BD_NAME_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",\r
- addr->addr[5], addr->addr[4], addr->addr[3], /* mac챐 0 1 2 3 4 5 */\r
- addr->addr[2], addr->addr[1], addr->addr[0]); /* mac챐 0 1 2 3 4 5 */\r
- SetBoundDeviceMac(lastConnedDeviceName);\r
- }\r
-}\r
-\r
-// 获取最后连接的蓝牙设备地址\r
-bd_addr_t *BluetoothModel::GetLastConnedAddr(void)\r
-{\r
- return &lastConnedAddr;\r
-}\r
-\r
-void BluetoothModel::SetConnectionView(BluetoothItemView *item)\r
-{\r
- selectItemView = item;\r
-}\r
-\r
-BluetoothItemView *BluetoothModel::GetConnectionView()\r
-{\r
- return selectItemView;\r
-}\r
-\r
-\r
-void BluetoothModel::SetTagReconnectJump(bool tag)\r
-{\r
- tagReconnectJump = tag;\r
-}\r
-\r
-bool BluetoothModel::GetTagReconnectJump(void)\r
-{\r
- return tagReconnectJump;\r
-}\r
-\r
-void BluetoothModel::SetCurView(int16_t viewNum)\r
-{\r
- curView = viewNum;\r
-}\r
-\r
-int BluetoothModel::GetCurView(void)\r
-{\r
- return curView;\r
-}\r
-\r
-void BluetoothModel::SetTagConnectView(bool tag)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagConnectView:%d", tag);\r
- tagConnectView = tag;\r
-}\r
-\r
-// 判断是否需要跳转连接成功\失败界面(已退出蓝牙模块)\r
-bool BluetoothModel::IsTagConnectView(void)\r
-{\r
- return tagConnectView;\r
-}\r
-\r
-void BluetoothModel::SetTagDisconnectView(bool tag)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagDisconnectView:%d", tag);\r
- tagDisconnectView = tag;\r
-}\r
-\r
-// 判断是否需要跳转连接失败界面\r
-bool BluetoothModel::IsTagDisconnectView(void)\r
-{\r
- return tagDisconnectView;\r
-}\r
-\r
-void BluetoothModel::SetTagConnectNew(bool tag)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagConnectNew:%d", tag);\r
- tagConnectNew = tag;\r
-}\r
-\r
-void BluetoothModel::SetTagReturnToDeviceListView(bool tag)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagReturnToDeviceListView:%d", tag);\r
- tagReturnToDeviceListView = tag;\r
-}\r
-\r
-bool BluetoothModel::IsTagReturnToDeviceListView(void)\r
-{\r
- return tagReturnToDeviceListView;\r
-}\r
-\r
-// 判断断开连接时是否需要马上连接新设备\r
-bool BluetoothModel::IsTagConnectNew(void)\r
-{\r
- return tagConnectNew;\r
-}\r
-\r
-// 设置是否已点击设备请求连接\r
-void BluetoothModel::SetTagScanDeviceClicked(bool tag)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagScanDeviceClicked:%d", tag);\r
- tagScanDeviceClicked = tag;\r
-}\r
-\r
-// 判断是否已点击设备请求连接\r
-bool BluetoothModel::IsTagScanDeviceClicked(void)\r
-{\r
- return tagScanDeviceClicked;\r
-}\r
-\r
-bool BluetoothModel::CheckExistConnedList(BluetoothCaseInfo caseInfo)\r
-{\r
- ListNode<BluetoothCaseInfo> *node = btConnedDevicesList_ ->Begin();\r
- if (node == nullptr) {\r
- return false;\r
- } else if ((caseInfo.addr[0] == 0) && (caseInfo.addr[1] == 0)\r
- && (caseInfo.addr[2] == 0) && (caseInfo.addr[3] == 0)\r
- && (caseInfo.addr[4] == 0) && (caseInfo.addr[5] == 0)) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CheckExistConnedList false addr: 000000000000");\r
- return true;\r
- }\r
- while (node != btConnedDevicesList_ ->End()) {\r
- if ((caseInfo.addr[0] == node->data_.addr[0]) && (caseInfo.addr[1] == node->data_.addr[1])\r
- && (caseInfo.addr[2] == node->data_.addr[2]) && (caseInfo.addr[3] == node->data_.addr[3])\r
- && (caseInfo.addr[4] == node->data_.addr[4]) && (caseInfo.addr[5] == node->data_.addr[5])) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CheckExistConnedList true");\r
- return true;\r
- }\r
- node = node->next_;\r
- }\r
- return false;\r
-}\r
-\r
-bool BluetoothModel::FindNameByAddr(BluetoothCaseInfo &listInfo, BluetoothCaseInfo *caseInfo)\r
-{\r
- if ((listInfo.addr[0] == caseInfo->addr[0]) && (listInfo.addr[1] == caseInfo->addr[1]) &&\r
- (listInfo.addr[2] == caseInfo->addr[2]) && (listInfo.addr[3] == caseInfo->addr[3]) &&\r
- (listInfo.addr[4] == caseInfo->addr[4]) && (listInfo.addr[5] == caseInfo->addr[5])) {\r
- (void)memcpy_s(caseInfo->deviceName, BD_NAME_LEN, listInfo.deviceName, BD_NAME_LEN);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FindNameFromList success, deviceName:%s", listInfo.deviceName);\r
- return true;\r
- } else {\r
- return false;\r
- }\r
-}\r
-\r
-bool BluetoothModel::FindNameFromList(BluetoothCaseInfo *caseInfo)\r
-{\r
- ListNode<BluetoothCaseInfo> *node = btConnedDevicesList_->Begin();\r
- if (!btScansDevicesList_.empty()) {\r
- for (auto it = btScansDevicesList_.begin(); it != btScansDevicesList_.end(); it++) {\r
- if (FindNameByAddr(*it, caseInfo)) {\r
- return true;\r
- }\r
- }\r
- }\r
- if (node != nullptr) {\r
- while (node != btConnedDevicesList_->End()) {\r
- if (FindNameByAddr(node->data_, caseInfo)) {\r
- return true;\r
- }\r
- node = node->next_;\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-bool BluetoothModel::GetBluetoothAclState(void)\r
-{\r
- if ((lastConnedAddr.addr[0] == 0) && (lastConnedAddr.addr[1] == 0) &&\r
- (lastConnedAddr.addr[2] == 0) && (lastConnedAddr.addr[3] == 0) &&\r
- (lastConnedAddr.addr[4] == 0) && (lastConnedAddr.addr[5] == 0)) {\r
- return false;\r
- } else {\r
- return bt_is_acl_connected(&lastConnedAddr);\r
- }\r
-}\r
-\r
-bool BluetoothModel::GetAdvStartState(void)\r
-{\r
- return advStartState;\r
-}\r
-void BluetoothModel::SetAdvStartState(bool state)\r
-{\r
- advStartState = state;\r
-}\r
-\r
-// 连接远程设备\r
-int BluetoothModel::ConnectRemoteDevice(const bd_addr_t *addr)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice: 准备连接设备 addr=%02x%02x%02x%02x%02x%02x",\r
- addr->addr[5], addr->addr[4], addr->addr[3],\r
- addr->addr[2], addr->addr[1], addr->addr[0]);\r
- /* 恢厂后耳机连接要开启BT广播否则会导致AVRCP无法音量控制 */\r
- bool ret = gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE, 60);\r
- if (!ret) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice gap_br_set_bt_scan_mode ret = 0x%x", ret);\r
- }\r
- errcode_t retVal = gap_connect_remote_device(addr);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "连接远程设备 ret = 0x%x", retVal);\r
- (void)memcpy_s(&remoteConnectAddr, sizeof(bd_addr_t), addr, sizeof(bd_addr_t));\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice: remoteConnectAddr已设置为 %02x%02x%02x%02x%02x%02x",\r
- remoteConnectAddr.addr[5], remoteConnectAddr.addr[4], remoteConnectAddr.addr[3],\r
- remoteConnectAddr.addr[2], remoteConnectAddr.addr[1], remoteConnectAddr.addr[0]);\r
- return retVal;\r
-}\r
-\r
-// 断开远程设备\r
-int BluetoothModel::DisconnectRemoteDevice(void)\r
-{\r
- bd_addr_t *lastAddr = BluetoothModel::GetInstance()->GetLastConnedAddr();\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "断开远程设备 Addr: %02X:%02X:%02X:%02X:%02X:%02X",\r
- lastAddr->addr[5], lastAddr->addr[4], lastAddr->addr[3], /* mac下标 0 1 2 3 4 5 */\r
- lastAddr->addr[2], lastAddr->addr[1], lastAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */\r
- errcode_t retVal = gap_disconnect_remote_device(lastAddr);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gap_disconnect_remote_device %d", retVal);\r
- // 清空正在连接的设备地址,避免影响后续连接\r
- (void)memset_s(&remoteConnectAddr, sizeof(bd_addr_t), 0, sizeof(bd_addr_t));\r
- return retVal;\r
-}\r
-\r
-// 解绑本地设备\r
-int BluetoothModel::UnBindLocalDevice(void)\r
-{\r
- bd_addr_t *lastAddr = BluetoothModel::GetInstance()->GetLastConnedAddr();\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "解绑蓝牙设备 Addr: %02X:%02X:%02X:%02X:%02X:%02X",\r
- lastAddr->addr[5], lastAddr->addr[4], lastAddr->addr[3], /* mac下标 0 1 2 3 4 5 */\r
- lastAddr->addr[2], lastAddr->addr[1], lastAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */\r
- bool ret = gap_remove_pair(lastAddr);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gap_remove_pair %d", ret);\r
- return ret;\r
-}\r
-\r
-/* 解析蓝牙地址字符串为 bd_addr_t 结构 */\r
-static int parse_bt_address(const char *addr_str, bd_addr_t *addr)\r
-{\r
- if (addr_str == NULL || addr == NULL) {\r
- return 0;\r
- }\r
- \r
- // 支持格式: "AA:BB:CC:DD:EE:FF" 或 "AABBCCDDEEFF"\r
- unsigned int addr_bytes[6] = {0};\r
- int count = sscanf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X",\r
- &addr_bytes[0], &addr_bytes[1], &addr_bytes[2],\r
- &addr_bytes[3], &addr_bytes[4], &addr_bytes[5]);\r
- \r
- if (count != 6) {\r
- // 尝试无冒号格式\r
- count = sscanf(addr_str, "%02X%02X%02X%02X%02X%02X",\r
- &addr_bytes[0], &addr_bytes[1], &addr_bytes[2],\r
- &addr_bytes[3], &addr_bytes[4], &addr_bytes[5]);\r
- if (count != 6) {\r
- return 0;\r
- }\r
- }\r
- \r
- // 蓝牙地址是反向存储的\r
- addr->addr[0] = (unsigned char)addr_bytes[5];\r
- addr->addr[1] = (unsigned char)addr_bytes[4];\r
- addr->addr[2] = (unsigned char)addr_bytes[3];\r
- addr->addr[3] = (unsigned char)addr_bytes[2];\r
- addr->addr[4] = (unsigned char)addr_bytes[1];\r
- addr->addr[5] = (unsigned char)addr_bytes[0];\r
- \r
- return 1;\r
-}\r
-\r
-// 解绑远程设备\r
-int BluetoothModel::UnBindRemoteDevice(const char *mac)\r
-{\r
- if (mac == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice mac is nullptr");\r
- return 0;\r
- }\r
- bd_addr_t addr = {0};\r
- if (parse_bt_address((char*)mac, &addr) != 1) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ERROR: Invalid Bluetooth address format");\r
- return ERRCODE_FAIL;\r
- }\r
- bool ret = gap_remove_pair(&addr);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gap_remove_pair %d", ret);\r
- if(ret == true)\r
- {\r
- // 从已连接设备列表中移除该设备\r
- if (btConnedDevicesList_ != nullptr) {\r
- ListNode<BluetoothCaseInfo> *node = btConnedDevicesList_->Begin();\r
- while (node != nullptr && node != btConnedDevicesList_->End()) {\r
- if ((node->data_.addr[0] == addr.addr[0]) && (node->data_.addr[1] == addr.addr[1]) &&\r
- (node->data_.addr[2] == addr.addr[2]) && (node->data_.addr[3] == addr.addr[3]) &&\r
- (node->data_.addr[4] == addr.addr[4]) && (node->data_.addr[5] == addr.addr[5])) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice: 从列表中移除设备 %02x%02x%02x%02x%02x%02x",\r
- addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0]);\r
- ListNode<BluetoothCaseInfo> *nextNode = node->next_;\r
- btConnedDevicesList_->Remove(node);\r
- node = nextNode;\r
- } else {\r
- node = node->next_;\r
- }\r
- }\r
- }\r
- \r
- // 刷新设备列表视图\r
- ThunderBirdBlueView *thunderBirdBlueView = ThunderBirdBlueView::GetInstance();\r
- if (thunderBirdBlueView != nullptr) {\r
- thunderBirdBlueView->RefreshDeviceList();\r
- }\r
- \r
- // 只有在已连接状态下才能发送状态报告\r
- if (ln_ws_get_connection_state() == 2)\r
- {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice gap_remove_pair ret = 0");\r
- char *bluetoothStatus = "UNBIND_SUCCESS";\r
- do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));\r
- }\r
- }\r
- else\r
- {\r
- char *bluetoothStatus = "UNBIND_FAILED";\r
- do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));\r
- }\r
- return ret;\r
-}\r
-\r
-// 设置绑定的本地设备MAC地址\r
-void BluetoothModel::SetBoundDeviceMac(const char *mac)\r
-{\r
- if (mac != nullptr) {\r
- (void)strcpy_s(boundDeviceMac, BD_NAME_LEN, mac);\r
- }\r
-}\r
-\r
-// 获取绑定的本地设备MAC地址\r
-char *BluetoothModel::GetBoundDeviceMac(void)\r
-{\r
- return boundDeviceMac;\r
-}\r
-\r
-// 设置最后连接的设备名称\r
-void BluetoothModel::SetLastConnedDeviceName(const char *name)\r
-{\r
- if (name != nullptr) {\r
- (void)strcpy_s(lastConnedDeviceName, BD_NAME_LEN, name);\r
- }\r
-}\r
-\r
-// 获取最后连接的设备名称\r
-char *BluetoothModel::GetLastConnedDeviceName(void)\r
-{\r
- return lastConnedDeviceName;\r
-}\r
-\r
-// 设置最后连接的设备电池电量\r
-void BluetoothModel::SetLastConnedDeviceBatteryLevel(int level)\r
-{\r
- lastConnedDeviceBatteryLevel = level;\r
-}\r
-\r
-// 获取最后连接的设备电池电量\r
-int BluetoothModel::GetLastConnedDeviceBatteryLevel(void)\r
-{\r
- return lastConnedDeviceBatteryLevel;\r
-}\r
-\r
-// 设置扫描状态\r
-void BluetoothModel::SetScanStatus(bool value)\r
-{\r
- scanStart = value;\r
-}\r
-\r
-// 获取扫描状态\r
-bool BluetoothModel::GetScanStatus(void)\r
-{\r
- return scanStart;\r
-}\r
-\r
-// 检查是否是正在连接的设备\r
-bool BluetoothModel::ConnectRemoteCheck(const bd_addr_t *addr)\r
-{\r
- bool ret;\r
- // 如果remoteConnectAddr为空(全0),说明没有明确的连接目标,允许A2DP连接\r
- if ((remoteConnectAddr.addr[0] == 0) && (remoteConnectAddr.addr[1] == 0) &&\r
- (remoteConnectAddr.addr[2] == 0) && (remoteConnectAddr.addr[3] == 0) &&\r
- (remoteConnectAddr.addr[4] == 0) && (remoteConnectAddr.addr[5] == 0)) {\r
- return true;\r
- }\r
- // 检查地址是否匹配\r
- if ((remoteConnectAddr.addr[0] == addr->addr[0]) && (remoteConnectAddr.addr[1] == addr->addr[1]) &&\r
- (remoteConnectAddr.addr[2] == addr->addr[2]) && (remoteConnectAddr.addr[3] == addr->addr[3]) &&\r
- (remoteConnectAddr.addr[4] == addr->addr[4]) && (remoteConnectAddr.addr[5] == addr->addr[5])) {\r
- ret = true;\r
- (void)memset_s(&remoteConnectAddr, sizeof(bd_addr_t), 0, sizeof(bd_addr_t));\r
- } else {\r
- ret = false;\r
- }\r
- return ret;\r
-}\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-// 回调: gap_read_remote_rssi_value 接口的数据上报\r
-void BtGapReadRemoteRssiEventCallback(const bd_addr_t *bdAddr, int rssi, int status)\r
-{\r
- UNUSED(status);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGapReadRemoteRssiEventCallback addr: %02x%02x%02x%02x%02x%02x",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */\r
- BluetoothModel::GetInstance()->SetScansCaseRssi(bdAddr, rssi);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bt BtGapReadRemoteRssiEventCallback SetSortCaseRssi: %d status: %d", rssi, status);\r
-}\r
-\r
-// 回调:发现状态变化上报/扫描结束\r
-void BtGapDiscoveryStateChangedCallback(int status)\r
-{\r
- UNUSED(status);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bt BtGapDiscoveryStateChangedCallback %d", status);\r
-}\r
-\r
-// 回调:发现设备上报处理\r
-void BluetoothModel::BtGapDiscoveryResultCallbakHandle(const bd_addr_t &bdAddr)\r
-{\r
- BluetoothCaseInfo caseInfo{};\r
- (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN);\r
- unsigned char nameLen = BD_NAME_LEN;\r
- bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发现蓝牙设备 : %d nameLen: %d name:%s",getNameRet, nameLen, caseInfo.deviceName);\r
- if (nameLen == 0) { // 过滤未扫描到名字的设备\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "过滤未扫描到名字的设备");\r
- return;\r
- }\r
- // 去重操作\r
- bool tag = BluetoothModel::GetInstance()->CheckExistScanList(caseInfo);\r
- if (!tag) \r
- {\r
- BluetoothModel::GetInstance()->AddCase(caseInfo); // 增加扫描设备信息\r
- }\r
- else\r
- {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckExistScanList true");\r
- }\r
-\r
- bool ret = gap_read_remote_rssi_value(&bdAddr); // 获取rssi\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gap_read_remote_rssi_value ret = %d", ret);\r
-\r
- tag = GetScanStatus();\r
- if (tag) { \r
- // 扫描状态下不立即跳转,等待定时器触发(至少10秒后)\r
- // 只记录设备,由定时器控制跳转时机\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "扫描中,已发现 %d 个设备", btScansDevicesList_.size());\r
- } else {\r
- // 已在设备列表界面,刷新列表\r
- ThunderBirdBlueView *thunderBirdBlueView = ThunderBirdBlueView::GetInstance();\r
- if (thunderBirdBlueView == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderBirdBlueView nullptr");\r
- return;\r
- }\r
- thunderBirdBlueView->RefreshDeviceList();\r
- }\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtGapDiscoveryResultCallback end");\r
-}\r
-\r
-//蓝牙取消配对ui处理\r
-static void UnpairDevice(const bd_addr_t *bdAddr)\r
-{\r
- if(ThunderBirdMainView::GetInstance()) {\r
- int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();\r
- ThunderBirdMainView::GetInstance()->ChangeView(currentView, \r
- THUNDERBIRD_BLUEVIEW, \r
- ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_SUCCESS_NEW);\r
- }\r
- return;\r
-}\r
-\r
-void BtGapPairStatusChangedCallback(const bd_addr_t *bdAddr, int status)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对状态变化 addr: ****%02x%02x%02x%02x status: %d\n",\r
- bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], status); /* addr下标 0 1 2 3 */\r
- if(status == GAP_PAIR_NONE){\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "取消配对");\r
- GraphicService::GetInstance()->PostGraphicEvent(std::bind(UnpairDevice, bdAddr));\r
- } else if(status == GAP_PAIR_PAIRING){\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "正在配对");\r
- } else if(status == GAP_PAIR_PAIRED){\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对成功");\r
- }\r
-}\r
-\r
-void BtGapPairRequestedCallback(const bd_addr_t *bdAddr)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对请求 addr: ****%02x%02x%02x%02x\n",\r
- bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* addr下标 0 1 2 3 */\r
-}\r
-\r
-void BtGapPairConfirmedCallback(const bd_addr_t *bdAddr, int req_type, int number)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对确认 addr: ****%02x%02x%02x%02x req_type: %d number: %d\n",\r
- bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], /* addr下标 0 1 2 3 */\r
- req_type, number);\r
-}\r
-// 回调:远程电池等级变化上报\r
-void BtGapRemoteBatteryLevelChangedCallback(const bd_addr_t *bdAddr, int level)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "远程电池等级变化 addr: ****%02x%02x%02x%02x level: %d\n",\r
- bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], level); /* addr下标 0 1 2 3 */\r
-}\r
-\r
-// 回调:扫描结果处理/发现结果上报\r
-void BtGapDiscoveryResultCallback(const bd_addr_t *bdAddr)\r
-{\r
- if ((gap_get_device_class(bdAddr) & DEVICE_MAJOR_CLASS_PHONE) != 0) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发现结果: Mobile Phone Device");\r
- return;\r
- }\r
-\r
- if (bdAddr == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "addr nullptr");\r
- return;\r
- }\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发现结果 addr: %02x:%02x:%02x:%02x:%02x:%02x",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */\r
- GraphicService::GetInstance()->PostGraphicEvent(std::bind(&BluetoothModel::BtGapDiscoveryResultCallbakHandle,\r
- BluetoothModel::GetInstance(), *bdAddr));\r
-}\r
-\r
-void HandleBeforeChangeView()\r
-{\r
- int curView = BluetoothModel::GetInstance()->GetCurView();\r
- if (curView == BLUETOOTHEARPHONEVIEW) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView curView == BLUETOOTHEARPHONEVIEW");\r
- BluetoothEarPhoneView *bluetoothEarPhoneView = BluetoothEarPhoneView::GetInstance();\r
- if (bluetoothEarPhoneView == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView bluetoothEarPhoneView == nullptr");\r
- return;\r
- }\r
- bluetoothEarPhoneView->BtAnimatorStop();\r
- bluetoothEarPhoneView->StopBtDiscovery();\r
- } else if (curView == BLUETOOTHEARLISTVIEW) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView curView == BLUETOOTHEARLISTVIEW");\r
- BluetoothEarPhoneView *bluetoothEarPhone = BluetoothEarPhoneView::GetInstance();\r
- if (bluetoothEarPhone == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView bluetoothEarPhoneView == nullptr");\r
- return;\r
- }\r
- bluetoothEarPhone->StopBtDiscovery();\r
- BluetoothItemView *pbItermView = BluetoothModel::GetInstance()->GetConnectionView();\r
- if (pbItermView == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView The GetConnectionView get failed.");\r
- return;\r
- }\r
- pbItermView->ConnectAnimatorStop();\r
- BluetoothModel::GetInstance()->SetConnectionView(nullptr);\r
- } else if (curView == BLUETOOTHRECONNECTVIEW) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView curView == BLUETOOTHRECONNECTVIEW");\r
- BluetoothReconnectView *bluetoothReconnectView = BluetoothReconnectView::GetInstance();\r
- if (bluetoothReconnectView == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView bluetoothReconnectView == nullptr");\r
- return;\r
- }\r
- bluetoothReconnectView->BtReconnectStop();\r
- }\r
-}\r
-\r
-// 回调:ACL连接成功\r
-static void ACLConnectionSuss(const bd_addr_t &bdAddr)\r
-{\r
- BluetoothCaseInfo caseInfo;\r
- (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN);\r
- unsigned char nameLen = BD_NAME_LEN;\r
- bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接成功 deviceName: %s", caseInfo.deviceName);\r
- BluetoothModel::GetInstance()->SetLastConnedDeviceName((const char *)caseInfo.deviceName);\r
- if(strcmp((const char *)caseInfo.deviceName, BluetoothModel::GetInstance()->GetLastConnedDeviceName()) == 0){\r
- \r
- //亮屏操作\r
- uapi_set_screen_on_api();\r
-\r
- ThunderBirdMainView *thunderBirdMainView = ThunderBirdMainView::GetInstance();\r
- if (thunderBirdMainView == nullptr)\r
- {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderBirdMainView nullptr");\r
- return;\r
- }\r
- int currentView = thunderBirdMainView->GetCurrentView();\r
- thunderBirdMainView->ChangeView(\r
- currentView,\r
- THUNDERBIRD_BLUEVIEW,\r
- ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_SUCCESS);\r
- }\r
-}\r
-\r
-// 回调:ACL连接失败\r
-static void ACLConnectionFail(const bd_addr_t &bdAddr)\r
-{\r
- // 如果当前正处于“切换到新耳机”的流程中(用户点了另一台设备准备自动重连),\r
- // 就不要弹出“连接已断开”页面,直接走后续新设备连接流程,避免多余页面跳转。\r
- BluetoothModel* btModel = BluetoothModel::GetInstance();\r
- if (btModel != nullptr && (btModel->IsTagConnectNew() || btModel->IsTagScanDeviceClicked())) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
- "ACLConnectionFail: in switch-device flow, skip DISCONNECT_SUCCESS page");\r
- // 清掉“需要自动连接新设备”的标记,由后续连接结果负责更新界面\r
- btModel->SetTagConnectNew(false);\r
- return;\r
- }\r
-\r
- BluetoothCaseInfo caseInfo;\r
- (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN);\r
- unsigned char nameLen = BD_NAME_LEN;\r
- bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接断开 deviceName: %s", caseInfo.deviceName);\r
- // 设备名为空不处理\r
- if(strcmp((const char *)caseInfo.deviceName, "") == 0){\r
- return;\r
- }\r
- if(strcmp((const char *)caseInfo.deviceName, BluetoothModel::GetInstance()->GetLastConnedDeviceName()) == 0)\r
- {\r
- \r
- //亮屏操作\r
- uapi_set_screen_on_api();\r
- \r
- ThunderBirdMainView *thunderBirdMainView = ThunderBirdMainView::GetInstance();\r
- if (thunderBirdMainView == nullptr)\r
- {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderBirdMainView nullptr");\r
- return;\r
- }\r
- int currentView = thunderBirdMainView->GetCurrentView();\r
- thunderBirdMainView->ChangeView(\r
- currentView,\r
- THUNDERBIRD_BLUEVIEW,\r
- ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_SUCCESS);\r
- }\r
-}\r
-void BluetoothModel::BtGapAclStateChangedHandle(gap_acl_state_t state, unsigned int reason, const bd_addr_t &bdAddr)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtGapAclStateChangedHandle reason is %x", reason);\r
- bool tag = BluetoothModel::GetInstance()->IsTagScanDeviceClicked();\r
- if ((reason == 0x13) || (reason == 0x14) || (reason == 0x15) || (reason == 0x3D) || (reason == 0x08 && (!tag))) { // 连接断开\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "蓝牙设备主动断开连接 reason is %x", reason);\r
- } else if (reason == 0x16) { // 主动断开连接\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "主动断开与蓝牙设备连接,reason is%x", reason);\r
- BluetoothCaseInfo *onClickBtCaseInfo = BluetoothModel::GetInstance()->GetTempMacValue();\r
- if (BluetoothModel::GetInstance()->IsTagConnectNew()) {\r
- errcode_t retVal = ConnectRemoteDevice((const bd_addr_t *)&onClickBtCaseInfo->addr);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice retVal = %d", retVal);\r
- }\r
- } else if ((reason == 0xb) || (reason > 0x45)) { // 0xb:重复点击连接按钮 0x45:acl状态最大参数\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "reason is false.");\r
- SetTagDisconnectView(false);\r
- } \r
- else if(reason == 0x2){\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接失败,链路连接被对端主动拒绝/未响应 reason is 0x2.");\r
- // 检查是否是期望连接的设备\r
- BluetoothCaseInfo *expectedDevice = GetTempMacValue();\r
- bool isExpectedDevice = false;\r
- if (expectedDevice != nullptr) {\r
- isExpectedDevice = (memcmp(expectedDevice->addr, bdAddr.addr, BD_ADDR_LEN) == 0);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接失败: 期望设备=%02x%02x%02x%02x%02x%02x, 回调地址=%02x%02x%02x%02x%02x%02x, 匹配=%d",\r
- expectedDevice->addr[5], expectedDevice->addr[4], expectedDevice->addr[3],\r
- expectedDevice->addr[2], expectedDevice->addr[1], expectedDevice->addr[0],\r
- bdAddr.addr[5], bdAddr.addr[4], bdAddr.addr[3],\r
- bdAddr.addr[2], bdAddr.addr[1], bdAddr.addr[0],\r
- isExpectedDevice);\r
- }\r
- // 清除连接状态标记(无论地址是否匹配,都清除,因为连接已失败)\r
- SetTagScanDeviceClicked(false);\r
- // 清空正在连接的设备地址\r
- (void)memset_s(&remoteConnectAddr, sizeof(bd_addr_t), 0, sizeof(bd_addr_t));\r
- // 刷新设备列表以停止"连接中"动画\r
- ThunderBirdBlueView *thunderBirdBlueView = ThunderBirdBlueView::GetInstance();\r
- if (thunderBirdBlueView != nullptr) {\r
- thunderBirdBlueView->RefreshDeviceList();\r
- }\r
- if(ThunderBirdMainView::GetInstance()) {\r
- int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();\r
- ThunderBirdMainView::GetInstance()->ChangeView(currentView, \r
- THUNDERBIRD_BLUEVIEW, \r
- ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_FAILED);\r
- }\r
- return;\r
- }\r
-\r
- if ((state == GAP_ACL_STATE_CONNECTED) || (state == GAP_ACL_STATE_LE_CONNECTED)) {\r
- SetLastConnedAddr(&bdAddr);\r
- // 将数据存入设备列表\r
- BluetoothCaseInfo *info = GetTempMacValue();\r
- tag = CheckExistConnedList(*info);\r
- if ((!tag) && (memcmp(info->addr, bdAddr.addr, BD_ADDR_LEN) == 0)) {\r
- AddConnedDevicesCase(*info);\r
- }\r
- }\r
- else\r
- {\r
- ACLConnectionFail(bdAddr);\r
- }\r
-\r
- if ((state == GAP_ACL_STATE_CONNECTED) || (state == GAP_ACL_STATE_LE_CONNECTED)) {\r
- if (BluetoothModel::GetInstance()->ConnectRemoteCheck(&bdAddr)) {\r
- int32_t retA2dp = a2dp_src_connect(&bdAddr);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "a2dp连接结果 result 0x%x", retA2dp);\r
- } else {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "忽略a2dp连接");\r
- }\r
- }\r
-}\r
-\r
-void ChangeBleConnectToMax()\r
-{\r
- if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) {\r
- gap_conn_param_update_t conn_param = { 0 };\r
- conn_param.conn_handle = BLUETOOTH_CONN_HANDLE;\r
- conn_param.interval_min = BLUETOOTH_INTERVAL_TOMAX_MIN;\r
- conn_param.interval_max = BLUETOOTH_INTERVAL_TOMAX_MAX;\r
- conn_param.slave_latency = BLUETOOTH_LATENCY;\r
- conn_param.timeout_multiplier = BLUETOOTH_TIMEOUT_MUTIPLIER;\r
- errcode_t ret = gap_ble_connect_param_update(&conn_param);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback change to max interval ret:%d : latency-min:%u latency-max:%u\n", \r
- ret, conn_param.interval_min, conn_param.interval_max);\r
- }\r
-}\r
-\r
-void ChangeBleConnectToDefault()\r
-{\r
- if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) {\r
- gap_conn_param_update_t conn_param = { 0 };\r
- conn_param.conn_handle = BLUETOOTH_CONN_HANDLE;\r
- conn_param.interval_min = BLUETOOTH_INTERVAL_TODEFAULT_MIN;\r
- conn_param.interval_max = BLUETOOTH_INTERVAL_TODEFAULT_MAX;\r
- conn_param.slave_latency = BLUETOOTH_LATENCY;\r
- conn_param.timeout_multiplier = BLUETOOTH_TIMEOUT_MUTIPLIER;\r
- errcode_t ret = gap_ble_connect_param_update(&conn_param);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback change to default interval ret:%d : latency-min:%u latency-max:%u\n", \r
- ret, conn_param.interval_min, conn_param.interval_max);\r
- }\r
-}\r
-\r
-// 回调:ACL连接状态上报\r
-void GapAclStateChangedCallback(const bd_addr_t *bdAddr, gap_acl_state_t state, unsigned int reason)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ACL连接状态上报 state %d, reason %x succ or err", state, reason);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "addr: %02x%02x%02x%02x%02x%02x",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */\r
- \r
- // 检查设备类型\r
- uint32_t deviceClass = gap_get_device_class(bdAddr);\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: deviceClass=0x%x, (class&0x200)=0x%x", \r
- deviceClass, deviceClass & 0x200);\r
- \r
- // 获取当前期望连接的设备地址\r
- BluetoothModel* btModel = BluetoothModel::GetInstance();\r
- BluetoothCaseInfo* expectedDevice = btModel->GetTempMacValue();\r
- if (expectedDevice != nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: 期望连接的设备 addr=%02x%02x%02x%02x%02x%02x",\r
- expectedDevice->addr[5], expectedDevice->addr[4], expectedDevice->addr[3],\r
- expectedDevice->addr[2], expectedDevice->addr[1], expectedDevice->addr[0]);\r
- }\r
- \r
- static bd_addr_t gapAclConnectAddr{0}; /* 连接后保存手机地址,手表清除手机配对后查询不到class比较手机地址 */\r
- if ((deviceClass & 0x200) != 0 || memcmp(gapAclConnectAddr.addr, bdAddr->addr, BD_ADDR_LEN) == 0) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: Mobile Phone Device (class&0x200=%d, matched=%d)", \r
- (deviceClass & 0x200) != 0, memcmp(gapAclConnectAddr.addr, bdAddr->addr, BD_ADDR_LEN) == 0);\r
- if (state == GAP_ACL_STATE_DISCONNECTED) {\r
- /* 通知msg_center,ble状态仍用bt状态,此处不区分 */\r
- // MsgCenterSendMsg(BT_DISCONNECTED_TO_MSGCENTER, 0, nullptr, 0);\r
- // SendMsgToUIService(BT_DISCONNECTED_TO_UI, 0, nullptr, 0);\r
- // send to ace network\r
- // SetAclConnected(false);\r
- // net_connect_status_change(NETWORK_TYPE_BLUETOOTH, CONNECTION_STATUS_DISCONNECTED);\r
- } else if (state == GAP_ACL_STATE_CONNECTED) {\r
- (void)memcpy_s(gapAclConnectAddr.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);\r
- // MsgCenterSendMsg(BT_CONNECTED_TO_MSGCENTER, 0, nullptr, 0);\r
- // SendMsgToUIService(BT_CONNECTED_TO_UI, 0, nullptr, 0);\r
- // send to ace network\r
- // SetAclConnected(true);\r
-#if defined(SUPPORT_LWIP) && defined(SUPPORT_BREDR)\r
- // bt_pan_open();\r
-#endif\r
- // net_connect_status_change(NETWORK_TYPE_BLUETOOTH, CONNECTION_STATUS_CONNECTED);\r
- }\r
- return;\r
- }\r
-\r
- GraphicService::GetInstance()->PostGraphicEvent(\r
- std::bind(&BluetoothModel::BtGapAclStateChangedHandle, BluetoothModel::GetInstance(), state, reason, *bdAddr));\r
-}\r
-\r
-// 回调:远端设备名称变化\r
-void BtRemoteNameChangedCallback(const bd_addr_t *bdAddr, const unsigned char *deviceName, unsigned char length)\r
-{\r
- if ((gap_get_device_class(bdAddr) & 0x200) != 0) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback: Mobile Phone Device");\r
- return;\r
- }\r
- BluetoothCaseInfo caseInfo{};\r
- if (bdAddr == nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback addr nullptr");\r
- return;\r
- }\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback addr: %02x%02x%02x%02x%02x%02x",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */\r
-\r
- (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);\r
- int ret = memcpy_s(caseInfo.deviceName, BD_NAME_LEN, deviceName, length);\r
- if (ret != EOK) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback memcpy fail!");\r
- return;\r
- }\r
- BluetoothModel::GetInstance()->ResetScanDevicesCase(caseInfo);\r
-}\r
-\r
-void BtIsAcceptConnOnSafeModeCallback(const bd_addr_t *bdAddr, bool *res)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtIsAcceptConnOnSafeModeCallback addr: %02x%02x%02x%02x%02x%02x set *res true",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* addr下标 3 4 5 */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* addr下标 0 1 2 */\r
- *res = true;\r
-}\r
-\r
-static void A2dpSrcConnectstateChanged(bd_addr_t *bdAddr, int connState)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "a2dp_src_connectStateChangedCallback addr: %02x%02x%02x%02x%02x%02x connState: %x",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* 5 4 3 idx */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], connState); /* 2 1 0 idx */\r
- if ((gap_get_device_class(bdAddr) & 0x200) != 0) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "a2dp_src_connectstateChangedCb: Mobile Phone Device");\r
- return;\r
- }\r
- if (connState == PROFILE_STATE_CONNECTED) {\r
- uint32_t ret = avrcp_ct_connect(bdAddr);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "avrcp_ct_connect ret = 0x%x", ret);\r
-\r
- set_a2dp_is_connect(true);\r
- PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_CONNECTED);\r
- GraphicService::GetInstance()->PostGraphicEvent(std::bind(ACLConnectionSuss, *bdAddr));\r
- int earphoneConnectStatus = 1;\r
- SendMsgToUIService(HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY, 0, &earphoneConnectStatus, sizeof(earphoneConnectStatus));\r
- }\r
-\r
- if (connState == PROFILE_STATE_DISCONNECTED) {\r
-\r
-\r
- PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_DISCONNECTED);\r
- \r
- set_a2dp_is_connect(false);\r
-\r
- \r
- GraphicService::GetInstance()->PostGraphicEvent(std::bind(ACLConnectionFail, *bdAddr));\r
- int earphoneConnectStatus = 0;\r
- SendMsgToUIService(HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY, 0, &earphoneConnectStatus, sizeof(earphoneConnectStatus));\r
- /* 实验室测试耳机回连场景,用户根据需要调整策略 */\r
- bool ret = gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 60); // start scan\r
- if (!ret) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "a2dp disc: gap_br_set_bt_scan_mode ret = 0x%x", ret);\r
- }\r
- }\r
- //上报蓝牙耳机连接状态\r
- GraphicService::GetInstance()-> PostGraphicEvent(std::bind(ln_bt_report_earphone_connection_status));\r
-}\r
-\r
-uint8_t A2dpSrcPlayingState=0;\r
-\r
-static void A2dpSrcPlayingStateChanged(bd_addr_t *bdAddr, int playState)\r
-{\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "A2dpSrcPlayingStateChangedCallback addr: %02x%02x%02x%02x%02x%02x playState: %x",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* 5 4 3 idx */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], playState); /* 2 1 0 idx */\r
- A2dpSrcPlayingState=playState;\r
-\r
-}\r
-\r
-uint8_t get_A2dpSrcPlayingStat(void)\r
-{\r
- return A2dpSrcPlayingState;\r
-}\r
-\r
-static void A2dpSrcConfigureChanged(bd_addr_t *bdAddr, a2dp_codec_info_t *info)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "A2dpSrcConfigurationChangedCallback addr: %02x%02x%02x%02x%02x%02x ",\r
- bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* 5 4 3 idx */\r
- bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* 2 1 0 idx */\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "codec_priority: %04x codec_type: %04x sample_rate: %02x bits_per_sample: %02x channel_mode: %02x ",\r
- info->codec_priority, info->codec_type, info->sample_rate, info->bits_per_sample, info->channel_mode);\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "codec_specific1: %04x codec_specific2: %04x codec_specific3: %04x codec_specific4: %04x",\r
- info->codec_specific1, info->codec_specific2, info->codec_specific3, info->codec_specific4);\r
-}\r
-\r
-static void BleConnStateChangeCallback(unsigned short connId, bd_addr_t *addr, gap_ble_conn_state_t connState,\r
- gap_ble_pair_state_t pairState, gap_ble_disc_reason_t discReason)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnStateChangeCallback connId 0x%x, connState 0x%x, pairState 0x%x",\r
- connId, connState, pairState);\r
- if (GAP_BLE_STATE_DISCONNECTED == connState) { // restart ble adv when disconnected\r
- /* 通知msg_center,ble状态仍用bt状态,此处不区分 */\r
- MsgCenterSendMsg(BT_DISCONNECTED_TO_MSGCENTER, 0, nullptr, 0);\r
- msg_center_set_ble_conn_state(GAP_BLE_STATE_DISCONNECTED);\r
- // send to ace network\r
- net_connect_status_change(NETWORK_TYPE_BLUETOOTH_LE, CONNECTION_STATUS_DISCONNECTED);\r
- } else {\r
- MsgCenterSendMsg(BT_CONNECTED_TO_MSGCENTER, 0, nullptr, 0);\r
- msg_center_set_ble_conn_state(GAP_BLE_STATE_CONNECTED);\r
- (void)memcpy_s(&g_bd_addr, sizeof(bd_addr_t), addr, sizeof(bd_addr_t));\r
- // send to ace network\r
- net_connect_status_change(NETWORK_TYPE_BLUETOOTH_LE, CONNECTION_STATUS_CONNECTED);\r
- }\r
- // send to ace network\r
-}\r
-\r
-static void BleAdvStartCallback(uint8_t advId, adv_status_t status)\r
-{\r
- if (g_sample_adv_id == advId) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStartCallback advId: %d, status:%d\n", advId, status);\r
- BluetoothModel::GetInstance()->SetAdvStartState(true);\r
- }\r
-}\r
-\r
-static void BleAdvStopCallback(uint8_t advId, adv_status_t status)\r
-{\r
- if (g_sample_adv_id == advId) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStopCallback advId: %d, status:%d\n", advId, status);\r
- BluetoothModel::GetInstance()->SetAdvStartState(false);\r
- }\r
-}\r
-\r
-static void BleAdvTerminateCallback(uint8_t advId, adv_status_t status)\r
-{\r
- if (g_sample_adv_id == advId) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvTerminateCallback advId: %d, status:%d\n", advId, status);\r
- BluetoothModel::GetInstance()->SetAdvStartState(false);\r
- // 此处开广播是为了实验室测试需要,客户需要自己修改\r
- BleAdvStart();\r
- }\r
-}\r
-\r
-static void BtGattsServiceAddCallback(uint8_t serverId, bt_uuid_t *uuid, uint16_t srvcHandle, errcode_t status)\r
-{\r
- if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t*)uuid->uuid) == 0xF01F)) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceAddCallback 0x%x 0x%x 0x%x",\r
- status, serverId, srvcHandle);\r
- uint16_t sample_id = 0xF11F;\r
- uint16_t diag_id = 0xF21F;\r
- gatts_add_chara_info_t character;\r
- uint16_t value = 0;\r
-\r
- memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t));\r
- character.chara_uuid.uuid_len = sizeof(sample_id);\r
- memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&sample_id, sizeof(sample_id));\r
- character.permissions = GATT_ATTRIBUTE_PERMISSION_WRITE;\r
- character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP;\r
- character.value_len = (uint16_t)sizeof(value);\r
- character.value = (uint8_t *)(&value);\r
- int ret = gatts_add_characteristic(serverId, srvcHandle, &character);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_characteristic sample ret 0x%x", ret);\r
-\r
- memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t));\r
- character.chara_uuid.uuid_len = sizeof(diag_id);\r
- memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&diag_id, sizeof(diag_id));\r
- character.permissions = GATT_ATTRIBUTE_PERMISSION_WRITE | GATT_ATTRIBUTE_PERMISSION_READ;\r
- character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP | GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY;\r
- character.value_len = (uint16_t)sizeof(value);\r
- character.value = (uint8_t *)(&value);\r
-\r
- ret = gatts_add_characteristic(serverId, srvcHandle, &character);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_characteristic diag ret 0x%x", ret);\r
-\r
- g_sample_svr_handle = srvcHandle;\r
- }\r
-}\r
-\r
-static void BtGattsCharacteristicAddCallback(uint8_t serverId, bt_uuid_t *uuid, uint16_t srvcHandle, gatts_add_character_result_t *result, errcode_t status)\r
-{\r
- if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t*)uuid->uuid) == 0xF11F)) {\r
- g_sample_characteristic_handle = result->value_handle;\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsCharacteristicAddCallback 0x%x 0x%x 0x%x 0x%x",\r
- status, serverId, srvcHandle, g_sample_characteristic_handle);\r
- }\r
- if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t*)uuid->uuid) == 0xF21F)) {\r
- g_diag_characteristic_handle = result->value_handle;\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsCharacteristicAddCallback 0x%x 0x%x 0x%x 0x%x",\r
- status, serverId, srvcHandle, g_diag_characteristic_handle);\r
-\r
- uint8_t ccc_val[] = { 0x01, 0x00 };\r
- uint16_t diag_desc = 0x0229;\r
- gatts_add_desc_info_t descriptor;\r
- memset_s(&descriptor, sizeof(gatts_add_desc_info_t), 0, sizeof(gatts_add_desc_info_t));\r
- descriptor.desc_uuid.uuid_len = sizeof(diag_desc);\r
- memcpy_s(descriptor.desc_uuid.uuid, sizeof(descriptor.desc_uuid.uuid), (char *)&diag_desc, sizeof(diag_desc));\r
- descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE;\r
- descriptor.value_len = (uint16_t)sizeof(ccc_val);\r
- descriptor.value = ccc_val;\r
- int ret = gatts_add_descriptor(serverId, srvcHandle, &descriptor);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_descriptor diag_desc ret 0x%x", ret);\r
- }\r
-\r
- if (g_sample_characteristic_handle != 0 && g_diag_characteristic_handle !=0 && g_diag_desc_handle != 0) {\r
- int ret = gatts_start_service(serverId, srvcHandle);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_start_service ret 0x%x", ret);\r
- }\r
-}\r
-\r
-static void BtGattsDescriptorAddCallback(uint8_t serverId, bt_uuid_t *uuid, uint16_t srvcHandle, uint16_t descriptorHandle, errcode_t status)\r
-{\r
- if (g_sample_svr_handle == srvcHandle) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsDescriptorAddCallback 0x%x 0x%x 0x%x 0x%x",\r
- status, serverId, srvcHandle, descriptorHandle);\r
- g_diag_desc_handle = descriptorHandle;\r
- }\r
-\r
- if (g_sample_characteristic_handle != 0 && g_diag_characteristic_handle !=0 && g_diag_desc_handle != 0) {\r
- int ret = gatts_start_service(serverId, srvcHandle);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_start_service ret 0x%x", ret);\r
- }\r
-}\r
-\r
-static void BtGattsServiceStartCallback(uint8_t serverId, uint16_t srvcHandle, errcode_t status)\r
-{\r
- if (g_sample_svr_handle == srvcHandle) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceStartCallback 0x%x 0x%x 0x%x", status, serverId, srvcHandle);\r
- }\r
-}\r
-\r
-static void BtGattsServiceStopCallback(uint8_t serverId, uint16_t srvcHandle, errcode_t status)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceStopCallback 0x%x 0x%x 0x%x", status, serverId, srvcHandle);\r
-}\r
-\r
-static void BtGattsServiceDeleteCallback(uint8_t serverId, errcode_t status)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceDeleteCallback 0x%x 0x%x", status, serverId);\r
-}\r
-\r
-static void BtGattsRequestReadCallback(uint8_t serverId, uint16_t connId, gatts_req_read_cb_t *readCbPara, errcode_t status)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGattsRequestReadCallback handle = %u", readCbPara->handle);\r
-}\r
-\r
-static void BtGattsRequestWriteCallback(uint8_t serverId, uint16_t connId, gatts_req_write_cb_t *writeCbPara, errcode_t status)\r
-{\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGattsRequestWriteCallback handle = %u", writeCbPara->handle);\r
- if (g_sample_characteristic_handle == writeCbPara->handle) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGattsRequestWriteCallback handle = %u", writeCbPara->handle);\r
- if (writeCbPara->length == 9) {\r
- if (memcmp("open ctkd", writeCbPara->value, writeCbPara->length) == 0) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "enable ctkd");\r
- // 一键双连使能(依赖安全连接参数配置)\r
- errcode_t ret = gap_ble_set_ctkd_enable(true);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gap_ble_set_ctkd_enable ret = %u", ret);\r
-\r
- // 发起ble配对\r
- ret = gap_ble_pair_remote_device(&g_bd_addr);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gap_ble_pair_remote_device ret = %u ", ret);\r
- }\r
- } else if (writeCbPara->length == 10) {\r
- if (memcmp("close ctkd", writeCbPara->value, writeCbPara->length) == 0) {\r
- // 一键双连去使能\r
- errcode_t ret = gap_ble_set_ctkd_enable(false);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gap_ble_set_ctkd_disable ret = %u", ret);\r
- }\r
- }\r
- } else if (g_diag_characteristic_handle == writeCbPara->handle) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "diag_gatt_write_req_cbk handle = %u", writeCbPara->handle);\r
- diag_gatt_write_req_cbk(serverId, connId, writeCbPara, status);\r
- } else if (g_diag_desc_handle == writeCbPara->handle) {\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "diag_gatt_set_handle handle = %u", writeCbPara->handle);\r
- if ((writeCbPara->length == 2) && (*(char*)(writeCbPara->value) == 1)) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "open gatt channel");\r
- diag_gatt_set_handle(serverId, connId, g_diag_characteristic_handle);\r
- msg_center_set_trans_channel(DIAG_FRAME_FID_BT);\r
- } else if ((writeCbPara->length == 2) && (*(char*)(writeCbPara->value) == 0)) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "close gatt channel");\r
- diag_gatt_set_handle(0, 0, 0);\r
- msg_center_set_trans_channel(DIAG_FRAME_FID_PHONE);\r
- }\r
- }\r
-}\r
-\r
-static void BtGattsMtuChangedCallback(uint8_t serverId, uint16_t connId, uint16_t mtuSize, errcode_t status)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsMtuChangedCallback connId = %u mtuSize = %u", connId, mtuSize);\r
-}\r
-\r
-static void BtA2dpSnkAcceptTimerStop(void)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "stop timer\n");\r
- if (g_a2dp_stream_accept_timer.timer != nullptr) {\r
- (void)osal_timer_stop(&g_a2dp_stream_accept_timer);\r
- (void)osal_timer_destroy(&g_a2dp_stream_accept_timer);\r
- g_a2dp_stream_accept_timer.timer = nullptr;\r
- }\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "stop timer success!\n");\r
-}\r
-\r
-static void BtA2dpSnStartAcceptHandler(unsigned long data)\r
-{\r
- UNUSED(data);\r
- bd_addr_t active_bd_addr = a2dp_snk_get_active_device();\r
- a2dp_snk_start_accept(&active_bd_addr);\r
- BtA2dpSnkAcceptTimerStop();\r
-}\r
-\r
-static errcode_t BtA2dpSnkStartAcceptTimer(void)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "start timer\n");\r
- if (g_a2dp_stream_accept_timer.timer != nullptr) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timer is running");\r
- return ERRCODE_SUCC;\r
- }\r
-\r
- g_a2dp_stream_accept_timer.handler = BtA2dpSnStartAcceptHandler;\r
- g_a2dp_stream_accept_timer.interval = A2DP_STREAM_ACCEPT_TIMER_PERIOD;\r
-\r
- int32_t timer_ret = osal_timer_init(&g_a2dp_stream_accept_timer);\r
- if (timer_ret != EOK) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "create timer error! ret: %x\n", timer_ret);\r
- BtA2dpSnkAcceptTimerStop();\r
- return ERRCODE_FAIL;\r
- }\r
- timer_ret = osal_timer_start(&g_a2dp_stream_accept_timer);\r
- if (timer_ret != EOK) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "start timer error! ret: %x\n", timer_ret);\r
- BtA2dpSnkAcceptTimerStop();\r
- return ERRCODE_FAIL;\r
- }\r
- return ERRCODE_SUCC;\r
-}\r
-\r
-static int32_t BtA2dpSnkAudioCreate()\r
-{\r
-#if MEDIA_A2DP_SNK_INTERFACE\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "audioFormat %d channelCount %d sampleRate %d \n",\r
- g_audio_format_config.audioFormat, g_audio_format_config.channelCount, g_audio_format_config.sampleRate);\r
-\r
- int32_t ret = AudioManagerA2dpSinkSetParam(g_audio_format_config);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AudioManagerA2dpSinkSetParam ret %x\n", ret);\r
- ret = AudioManagerA2dpSinkCreate();\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AudioManagerA2dpSinkCreate ret %x\n", ret);\r
-#endif\r
- /* 起定时器接受音乐开始请求 */\r
- (void)BtA2dpSnkStartAcceptTimer();\r
- return 0;\r
-}\r
-\r
-static int32_t BtA2dpSnkAudioDestroy()\r
-{\r
-#if MEDIA_A2DP_SNK_INTERFACE\r
- int32_t ret = AudioManagerA2dpSinkDestroy();\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AudioManagerA2dpSinkDestroy ret %x\n", ret);\r
-#endif\r
- return 0;\r
-}\r
-\r
-static void BtA2dpSnkConnectStateChangedCb(bd_addr_t *bd_addr, int conn_state)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x conn_state: %x\n",\r
- bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0], conn_state); /* 3 2 1 0 idx */\r
-}\r
-\r
-static void BtA2dpSnkStartStreamReqCb(bd_addr_t *bd_addr)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x \n",\r
- bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* 3 2 1 0 idx */\r
- BtA2dpSnkAudioCreate();\r
-}\r
-\r
-static void BtA2dpSnkPlayingStateChangedCb(bd_addr_t *bd_addr, int playing_state)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x playing_state: %x\n",\r
- bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0], playing_state); /* 3 2 1 0 idx */\r
- if (playing_state == A2DP_NOT_PLAYING) {\r
- BtA2dpSnkAudioDestroy();\r
- }\r
-}\r
-\r
-static void BtA2dpSnkConfigChangedCb(bd_addr_t *bd_addr, a2dp_snk_codec_info_t *info)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x ",\r
- bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* 3 2 1 0 idx */\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,\r
- "codec_priority: %04x codec_type: %04x sample_rate: %02x bits_per_sample: %02x channel_mode: %02x",\r
- info->codec_priority, info->codec_type, info->sample_rate, info->bits_per_sample, info->channel_mode);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,\r
- "codec_specific1: %04x codec_specific2: %04x codec_specific3: %04x codec_specific4: %04x\n",\r
- (unsigned int)info->codec_specific1,\r
- (unsigned int)info->codec_specific2,\r
- (unsigned int)info->codec_specific3,\r
- (unsigned int)info->codec_specific4);\r
-#if MEDIA_A2DP_SNK_INTERFACE\r
- if (info->codec_type == A2DP_SNK_CODEC_TYPE_AAC) {\r
- g_audio_format_config.audioFormat = AAC_LC;\r
- } else {\r
- g_audio_format_config.audioFormat = SBC;\r
- }\r
- /* channel count 1 or 2 */\r
- g_audio_format_config.channelCount = (info->channel_mode == A2DP_SNK_CODEC_CHANNEL_MODE_NONE ? 1 : 2);\r
-\r
- switch (info->sample_rate) {\r
- case A2DP_SNK_CODEC_SAMPLE_RATE_48000:\r
- g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE48000;\r
- break;\r
- case A2DP_SNK_CODEC_SAMPLE_RATE_88200:\r
- g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE88200;\r
- break;\r
- case A2DP_SNK_CODEC_SAMPLE_RATE_96000:\r
- g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE96000;\r
- break;\r
- default:\r
- g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE44100;\r
- break;\r
- }\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "audioFormat %d channelCount %d sampleRate %d \n",\r
- g_audio_format_config.audioFormat, g_audio_format_config.channelCount, g_audio_format_config.sampleRate);\r
-#endif\r
-}\r
-\r
-// 注册回调函数\r
-static gap_call_backs_t g_btGapCallBacks{};\r
-static a2dp_src_callbacks_t g_a2dpSrcCallbacks{};\r
-static gap_ble_callbacks_t g_gapBleCallbacks{};\r
-static gatts_callbacks_t g_btGattsCallbacks{};\r
-\r
-static a2dp_snk_callbacks_t g_a2dp_snk_callbacks = {\r
- BtA2dpSnkConnectStateChangedCb,\r
- BtA2dpSnkStartStreamReqCb,\r
- BtA2dpSnkPlayingStateChangedCb,\r
- BtA2dpSnkConfigChangedCb\r
-};\r
-\r
-static void BleConnectCallback(uint16_t conn_id, errcode_t status, const gap_ble_conn_param_update_t *param)\r
-{\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback conn_id:%u, interval-1:%u latency:%u timeout:%u\n",conn_id, param->interval, param->latency, param->timeout);\r
-}\r
-\r
-void BtInitCallBacks()\r
-{\r
- g_btGapCallBacks.discovery_result_callback = BtGapDiscoveryResultCallback;\r
- g_btGapCallBacks.discovery_state_changed_callback = BtGapDiscoveryStateChangedCallback;\r
- g_btGapCallBacks.acl_state_changed_callbak = GapAclStateChangedCallback;\r
- g_btGapCallBacks.read_remote_rssi_event_callback = BtGapReadRemoteRssiEventCallback;\r
- g_btGapCallBacks.remote_name_changed_callback = BtRemoteNameChangedCallback;\r
- g_btGapCallBacks.is_accept_conn_on_safe_mode_callback = BtIsAcceptConnOnSafeModeCallback;\r
- g_btGapCallBacks.pair_status_changed_callback = BtGapPairStatusChangedCallback;\r
- g_btGapCallBacks.pair_requested_callback = BtGapPairRequestedCallback;\r
- g_btGapCallBacks.pair_confiremed_callback = BtGapPairConfirmedCallback;\r
- g_btGapCallBacks.remote_battery_level_changed_callback = BtGapRemoteBatteryLevelChangedCallback;\r
- gap_register_callbacks(&g_btGapCallBacks);\r
-\r
-}\r
-\r
-void BtA2dpInit(void)\r
-{\r
- /* a2dp source */\r
- g_a2dpSrcCallbacks.connectstate_changed_cb = A2dpSrcConnectstateChanged;\r
- g_a2dpSrcCallbacks.configuration_changed_cb = A2dpSrcConfigureChanged;\r
- g_a2dpSrcCallbacks.playing_state_changed_cb = A2dpSrcPlayingStateChanged;\r
- a2dp_src_register_callbacks(&g_a2dpSrcCallbacks);\r
- /* a2dp sink */\r
- a2dp_snk_register_callbacks(&g_a2dp_snk_callbacks);\r
-}\r
-\r
-void BtInitCallBacksEx()\r
-{\r
- g_gapBleCallbacks.conn_state_change_cb = BleConnStateChangeCallback;\r
- g_gapBleCallbacks.start_adv_cb = BleAdvStartCallback;\r
- g_gapBleCallbacks.stop_adv_cb = BleAdvStopCallback;\r
- g_gapBleCallbacks.terminate_adv_cb = BleAdvTerminateCallback;\r
- g_gapBleCallbacks.conn_param_update_cb = BleConnectCallback;\r
- wrapper_gap_ble_register_callbacks(&g_gapBleCallbacks);\r
-\r
- g_btGattsCallbacks.add_service_cb = BtGattsServiceAddCallback;\r
- g_btGattsCallbacks.add_characteristic_cb = BtGattsCharacteristicAddCallback;\r
- g_btGattsCallbacks.add_descriptor_cb = BtGattsDescriptorAddCallback;\r
- g_btGattsCallbacks.start_service_cb = BtGattsServiceStartCallback;\r
- g_btGattsCallbacks.stop_service_cb = BtGattsServiceStopCallback;\r
- g_btGattsCallbacks.delete_service_cb = BtGattsServiceDeleteCallback;\r
- g_btGattsCallbacks.read_request_cb = BtGattsRequestReadCallback;\r
- g_btGattsCallbacks.write_request_cb = BtGattsRequestWriteCallback;\r
- g_btGattsCallbacks.mtu_changed_cb = BtGattsMtuChangedCallback;\r
- wrapper_gatts_register_callbacks(&g_btGattsCallbacks);\r
-}\r
-\r
-void BtInitGatts(void)\r
-{\r
- uint16_t id = 0xF01F;\r
- uint16_t ser_id = 0xFF1F;\r
- uint8_t serverId = 0;\r
- bt_uuid_t uuid;\r
- int ret;\r
-\r
- uuid.uuid_len = sizeof(ser_id);\r
- memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&ser_id, sizeof(ser_id));\r
- ret = wrapper_gatts_register_server(&uuid, &serverId); /* 注册gatt server */\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_register_server ret: 0x%x serverId = 0x%x", ret, serverId);\r
-\r
- uuid.uuid_len = sizeof(id);\r
- memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&id, sizeof(id));\r
- ret = wrapper_gatts_add_service(serverId, &uuid, true);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_service ret: 0x%x", ret);\r
-\r
- wrapper_gatts_service_start();\r
-}\r
-\r
-static uint8_t Char2Num(int8_t c)\r
-{\r
- if (c >= '0' && c <= '9') {\r
- return (uint8_t)(c - '0');\r
- } else if (c >= 'A' && c <= 'F') {\r
- return (uint8_t)(c - 'A' + TEN);\r
- } else if (c >= 'a' && c <= 'f') {\r
- return (uint8_t)(c - 'a' + TEN);\r
- } else {\r
- return 0xFF;\r
- }\r
-}\r
-\r
-static uint32_t GenerateUuidFromString(const char *str, uint8_t len, bt_uuid_t *uuid_out)\r
-{\r
- int slen = (int)strnlen(str, len);\r
- bool new_uuid = false;\r
- if (uuid_out == nullptr) {\r
- return ERRCODE_INVALID_PARAM;\r
- }\r
-\r
- uuid_out->uuid_len = (uint8_t)slen / 2; /* 2: 2个字符组成一个字节,因此只取偶数个字符 */\r
- for (int i = 0; i + 1 < slen; i += 2) { /* 2: 同上 */\r
- uint8_t num1 = Char2Num(str[i]);\r
- uint8_t num2 = Char2Num(str[i + 1]);\r
- if (num1 == UINT8_MAX || num2 == UINT8_MAX) {\r
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "invalid input %c%c\n", str[i], str[i + 1]);\r
- return ERRCODE_INVALID_PARAM;\r
- }\r
-\r
- uuid_out->uuid[i / 2] = (uint8_t)((num1 << BIT4) | num2); /* 2: 同上 */\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "%02x ", (uint8_t)(uuid_out->uuid[i / 2])); /* 2: 同上 */\r
- }\r
-\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "\n");\r
- return ERRCODE_SUCC;\r
-}\r
-\r
-void BtSppServerCreate(const char *spp_uuid, const char *name, uint8_t name_len)\r
-{\r
- spp_create_socket_para_t param;\r
- if (GenerateUuidFromString((const char *)spp_uuid, (uint8_t)strlen(spp_uuid), ¶m.uuid) != ERRCODE_SUCC) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get uuid fail\n");\r
- return;\r
- }\r
-\r
- param.socket_type = SPP_SOCKET_RFCOMM;\r
- param.is_encrypt = true;\r
-\r
- int ret = spp_server_create(¶m, name, name_len);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_create ret: %x\n", ret);\r
-}\r
-\r
-static int BtSppServerAcceptTaskBody(void *data)\r
-{\r
- int server_id = (int)(intptr_t)data;\r
- int ret = spp_server_accept(server_id);\r
-\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_accept ret: %x, server_id: %d\r\n", ret, server_id);\r
- return OSAL_SUCCESS;\r
-}\r
-\r
-/* 等待client连接 */\r
-void BtSppServerAccept(uint8_t server_id)\r
-{\r
- osal_task *task = osal_kthread_create(BtSppServerAcceptTaskBody, (void *)(uintptr_t)server_id,\r
- "spp_server_accept_task", BT_SPP_TASK_STACK_SIZE);\r
- if (task == nullptr) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "create task fail\n");\r
- return;\r
- }\r
-\r
- int ret = osal_kthread_set_priority(task, BT_SPP_TASK_PRI);\r
- if (ret != OSAL_SUCCESS) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "set pri error: %08x\n", ret);\r
- }\r
-}\r
-\r
-void BtInitSpp(void)\r
-{\r
- char uuid[] = "1101";\r
- char name[] = "COM1";\r
- uint8_t name_len = strlen(name) + 1;\r
- uint8_t server_id = 0;\r
-\r
- /* 创建spp */\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "create spp server uuid=%s name=%s name_len=%d\n", uuid, name, name_len);\r
- BtSppServerCreate(uuid, name, name_len);\r
- BtSppServerAccept(server_id);\r
-}\r
-\r
-void BleAdvStart(void)\r
-{\r
- int advId = g_sample_adv_id;\r
- if (BluetoothModel::GetInstance()->GetAdvStartState()) {\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStart already started");\r
- gap_ble_stop_adv(advId);\r
- osDelay(50);\r
- }\r
- gap_ble_adv_params_t adv_para;\r
- memset_s(&adv_para, sizeof(gap_ble_adv_params_t), 0, sizeof(gap_ble_adv_params_t));\r
- adv_para.min_interval = 0x30;\r
- adv_para.max_interval = 0x60;\r
- adv_para.adv_type = GAP_BLE_ADV_CONN_SCAN_UNDIR;\r
- adv_para.channel_map = 0x7;\r
- adv_para.duration = 0;\r
- gap_ble_set_adv_param(advId, &adv_para);\r
- gap_ble_set_local_appearance(GAP_BLE_APPEARANCE_TYPE_GENERIC_WATCH);\r
- errcode_t ret = gap_ble_start_adv(advId);\r
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStart bt gap_ble_start_adv ret = 0x%x", ret);\r
-}\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-}\r
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: BluetoothModel view
+ * Author:
+ * Create: 2021-10-13
+ */
+#include <cstdint>
+#include "bluetooth/BluetoothModel.h"
+#include "bluetooth/BluetoothWrapper.h"
+#include "bluetooth/BluetoothPresenter.h"
+#include "connectnewphone/ConnectPhonePresenter.h"
+#include "player/BluetoothView.h"
+#include "bluetooth/BluetoothItemView.h"
+#include "player/PlayersModel.h"
+#include "phoneservice/PhoneAudio.h"
+#include "graphic_service.h"
+#include "msg_center.h"
+#include "bts_def.h"
+#include "bts_gatt_stru.h"
+#include "bts_a2dp_source.h"
+#include "bts_gatt_server.h"
+#include "bts_le_gap.h"
+#include "bts_spp.h"
+#include "osal_task.h"
+#include "los_task.h"
+#ifdef SUPPORT_ALIPAY_SEC
+#include "alipay_feature.h"
+#endif
+#include "bts_a2dp_sink.h"
+#include "bts_feature.h"
+#include "bt_audio_hal_interface.h"
+#include "audio_manager_c_wrapper.h"
+#include "bts_avrcp_target.h"
+#include "msg_center_msg.h"
+#include "client/msg_center_client.h"
+#include "msg_center_protocol.h"
+#include "dfx_channel.h"
+#include "tcxo.h"
+#include "uiservice/ui_service.h"
+#include "network/network_listener.h"
+#if defined(SUPPORT_LWIP) && defined(SUPPORT_BREDR)
+#include "lwip_driver_adapter.h"
+#endif
+#include <bluetooth/BluetoothHeadsetEvent.h>
+#include "ln_api.h"
+#include "phoneservice/PhoneService.h"
+#include "thunderbird/include/ThunderBirdMainView.h"
+#include "thunderbird/include/ThunderBirdBlueView.h"
+#include <custom_utils.h>
+#include "ai_media.h"
+
+namespace OHOS {
+
+#define BT_SPP_TASK_STACK_SIZE 2048
+#define BT_SPP_TASK_PRI 20
+#define TEN 10
+
+constexpr uint16_t BLUETOOTH_MAX_NUM = 20;
+
+#define MEDIA_A2DP_SNK_INTERFACE 1
+osal_timer g_a2dp_stream_accept_timer = {nullptr, nullptr, 0, 0};
+#define A2DP_STREAM_ACCEPT_TIMER_PERIOD 500
+AudioFormatConfig g_audio_format_config = {AUDIO_DEFAULT, 0, 0};
+static uint16_t g_sample_svr_handle = 0;
+static uint16_t g_sample_characteristic_handle = 0;
+static uint16_t g_diag_characteristic_handle = 0;
+static uint16_t g_diag_desc_handle = 0;
+constexpr uint16_t g_sample_adv_id = 2;
+static bd_addr_t g_bd_addr = { 0 };
+
+void BluetoothModel::SetBluetoothCalleridStatus(int16_t value)
+{
+ callerid = value;
+}
+
+int BluetoothModel::GetBluetoothCalleridStatus(void)
+{
+ return callerid;
+}
+
+BluetoothModel::BluetoothModel()
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::BluetoothModel");
+}
+
+BluetoothModel *BluetoothModel::GetInstance(void)
+{
+ static BluetoothModel instance;
+ return &instance;
+}
+
+char* BluetoothModel::getWatchName(void)
+{
+ return watchName;
+}
+
+void BluetoothModel::InitBluetoothInfo(void)
+{
+ errcode_t ret;
+ unsigned char nameLen = BD_NAME_LEN;
+ memset_s(watchName, sizeof(watchName), 0, sizeof(watchName));
+ ret = bluetooth_get_local_name((unsigned char *)watchName, &nameLen);
+ // 为了实验室测试需要,客户需要自己修改
+ if ((nameLen == strlen("WatchDemo") + 1) && (strcmp("WatchDemo", watchName) == 0)) {
+ uint32_t currentUs = uapi_tcxo_get_us();
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "currentUs 0x%x", currentUs);
+ // 设置蓝牙名称
+ (void)sprintf_s(watchName, sizeof(watchName), "LN%x", (currentUs & 0xFFFF));
+ ret = bluetooth_set_local_name((unsigned char*)watchName, strlen((char*)watchName) + 1);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bluetooth_set_local_name %s ret = %u", watchName, ret);
+
+ // 设置蓝牙地址
+ bd_addr_t addr = {{0x1C, 0x1D, 0x2B, 0x0, 0x0, 0x0} ,0};
+ addr.addr[3] = currentUs & 0xFF;
+ addr.addr[4] = (currentUs & 0XFF00) >> 8;
+ addr.addr[5] = currentUs & 0xFF;
+ ret = bluetooth_set_local_addr(addr.addr, BD_ADDR_LEN);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bluetooth_set_local_addr [0x%x:0x%x] ret = %u", addr.addr[0], addr.addr[1], ret);
+ } else {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "watchName: %s", watchName);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "nameLen: %u", nameLen);
+ }
+}
+
+void BluetoothModel::Init()
+{
+#ifndef SUPPORT_AUTO_OTA
+ errcode_t ret;
+
+ // 设置自动回连,ios一键双连依赖此配置
+ bts_feature_t bts_feature = { 0 };
+ bts_feature.bt_auto_reconnect_closed = 1;
+ ret = bts_set_features(&bts_feature);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bt bts_set_features ret = %u", ret);
+
+ ret = enable_bt_stack();
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "bt enable_bt_stack ret = %u", ret);
+
+ InitBluetoothInfo();
+ BtInitCallBacks();
+
+ InitBtHeadsetEvent(); // 蓝牙ct和tg适配初始化
+ PhoneServiceInit();
+ BtA2dpInit();
+#endif
+}
+
+void BluetoothModel::SetCaseListClear()
+{
+ btScansDevicesList_.clear();
+ SetUpConnedDevicesList();
+}
+
+// 检查扫描列表是否存在该设备
+bool BluetoothModel::CheckExistScanList(BluetoothCaseInfo caseInfo)
+{
+ std::list<BluetoothCaseInfo>::iterator node = btScansDevicesList_.begin();
+ if (btScansDevicesList_.empty()) {
+ return false;
+ }
+ while (node != btScansDevicesList_.end()) {
+ if ((caseInfo.addr[0] == node->addr[0]) && (caseInfo.addr[1] == node->addr[1])
+ && (caseInfo.addr[2] == node->addr[2]) && (caseInfo.addr[3] == node->addr[3])
+ && (caseInfo.addr[4] == node->addr[4]) && (caseInfo.addr[5] == node->addr[5])) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "true");
+ return true;
+ }
+ node++;
+ }
+ return false;
+}
+
+void BluetoothModel::SetUpListCase()
+{
+ SetCaseListClear();
+}
+
+std::list<BluetoothCaseInfo>& BluetoothModel::GetCase()
+{
+ return btScansDevicesList_;
+}
+
+void BluetoothModel::AddCase(BluetoothCaseInfo caseInfo)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AddCase::caseInfo addr: %02x%02x%02x%02x%02x%02x",
+ caseInfo.addr[5], caseInfo.addr[4], caseInfo.addr[3], /* mac下标 0 1 2 3 4 5 */
+ caseInfo.addr[2], caseInfo.addr[1], caseInfo.addr[0]);
+ if (btScansDevicesList_.size() >= BLUETOOTH_MAX_NUM) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "btScansDevicesList_.size is BLUETOOTH_MAX_NUM");
+ return;
+ } else {
+ btScansDevicesList_.push_back(caseInfo);
+ }
+}
+
+void BluetoothModel::SetScansCaseRssi(const bd_addr_t *bdAddr, int rssi)
+{
+ for (auto it = btScansDevicesList_.begin(); it != btScansDevicesList_.end(); it++) {
+ if ((it->addr[0] == bdAddr->addr[0]) && (it->addr[1] == bdAddr->addr[1])
+ && (it->addr[2] == bdAddr->addr[2]) && (it->addr[3] == bdAddr->addr[3])
+ && (it->addr[4] == bdAddr->addr[4]) && (it->addr[5] == bdAddr->addr[5])) {
+ it->temp = rssi;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "btScansDevicesList_ rssi:%d deviceName:%s", it->temp, it->deviceName);
+ }
+ }
+}
+
+
+bool CompBuletoothInfo(const BluetoothCaseInfo& a, const BluetoothCaseInfo& b)
+{
+ if (a.temp > b.temp) {
+ return true;
+ }
+ return false;
+}
+
+void BluetoothModel::SortScansCaseRssi()
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SortScansCaseRssi");
+ btScansDevicesList_.sort(CompBuletoothInfo);
+}
+
+void BluetoothModel::ResetScanDevicesCase(const BluetoothCaseInfo& caseInfo)
+{
+ for (auto it = btScansDevicesList_.begin(); it != btScansDevicesList_.end(); it++) {
+ if ((it->addr[0] == caseInfo.addr[0]) && (it->addr[1] == caseInfo.addr[1])
+ && (it->addr[2] == caseInfo.addr[2]) && (it->addr[3] == caseInfo.addr[3])
+ && (it->addr[4] == caseInfo.addr[4]) && (it->addr[5] == caseInfo.addr[5])) {
+ (void)memcpy_s(it->deviceName, BD_NAME_LEN,
+ caseInfo.deviceName, BD_NAME_LEN);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ResetConnedDevicesCase deviceName:%s", it->deviceName);
+ }
+ }
+}
+
+/* 已配对设备队列 */
+void BluetoothModel::SetConnedDevicesListClear()
+{
+ btConnedDevicesList_->Clear();
+}
+
+void BluetoothModel::SetUpConnedDevicesList()
+{
+ if (btConnedDevicesList_ == nullptr) {
+ btConnedDevicesList_ = new List<BluetoothCaseInfo>();
+ if (btConnedDevicesList_ == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BluetoothModel btConnedDevicesList_ new fail");
+ return;
+ }
+ SetConnedDevicesListClear();
+ unsigned int connedDevicesNum = 0;
+ bool ret = gap_get_paired_devices_num(&connedDevicesNum);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setup GetPariedDevicesNum ret = %d, num = %d", ret, connedDevicesNum);
+
+ gap_paired_device_info_t *devInfo = (gap_paired_device_info_t*)malloc(sizeof(gap_paired_device_info_t) *connedDevicesNum);
+ if (devInfo == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DevInfo malloc failed %u", sizeof(gap_paired_device_info_t) *connedDevicesNum);
+ return;
+ }
+ ret = gap_get_paired_devices_list(devInfo, (int *)&connedDevicesNum);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetUpConnedDevicesList gap_get_paired_devices_list ret = %d", ret);
+
+ BluetoothCaseInfo caseInfo{};
+ for (int i = 0; i < static_cast<int>(connedDevicesNum); ++i) {
+ if ((gap_get_device_class((const bd_addr_t *)devInfo[i].addr.addr) & 0x200) != 0) {
+ continue;
+ }
+ (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN,
+ devInfo[i].addr.addr, BD_ADDR_LEN);
+ (void)memcpy_s(caseInfo.deviceName, BD_NAME_LEN,
+ devInfo[i].device_name, BD_NAME_LEN);
+ AddConnedDevicesCase(caseInfo);
+ }
+ free(devInfo);
+ }
+}
+
+// 已连接设备队列
+void BluetoothModel::AddConnedDevicesCase(BluetoothCaseInfo caseInfo)
+{
+ if (btConnedDevicesList_ == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "btConnedDevicesList_ nullptr");
+ return;
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AddConnedDevicesCase::caseInfo addr: %02x%02x%02x%02x%02x%02x",
+ caseInfo.addr[5], caseInfo.addr[4], caseInfo.addr[3], /* mac下标 0 1 2 3 4 5 */
+ caseInfo.addr[2], caseInfo.addr[1], caseInfo.addr[0]);
+ if (btConnedDevicesList_->Size() >= BLUETOOTH_MAX_NUM) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "btConnedDevicesList_->Size is BLUETOOTH_MAX_NUM");
+ return;
+ } else {
+ btConnedDevicesList_->PushBack(caseInfo);
+ }
+}
+
+List<BluetoothCaseInfo>& BluetoothModel::GetConnedDevicesCase()
+{
+ // 确保已连接设备列表已经初始化
+ if (btConnedDevicesList_ == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetConnedDevicesCase: btConnedDevicesList_ is nullptr, calling SetUpConnedDevicesList");
+ SetUpConnedDevicesList();
+ }
+
+ // 如果仍然为空,返回一个静态空列表,防止野指针导致异常
+ if (btConnedDevicesList_ == nullptr) {
+ static List<BluetoothCaseInfo> emptyList;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetConnedDevicesCase: btConnedDevicesList_ still nullptr, return empty list");
+ return emptyList;
+ }
+
+ return *btConnedDevicesList_;
+}
+
+void BluetoothModel::SetBtStatus(void)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetBtStatus tempMacValue: %02x%02x%02x%02x%02x%02x",
+ tempMacValue.addr[5], tempMacValue.addr[4], tempMacValue.addr[3], /* mac챐 0 1 2 3 4 5 */
+ tempMacValue.addr[2], tempMacValue.addr[1], tempMacValue.addr[0]); /* mac챐 0 1 2 3 4 5 */
+ aclConnected = bt_is_acl_connected((const bd_addr_t*)&tempMacValue.addr);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "aclConnected %d", aclConnected);
+}
+
+bool BluetoothModel::GetAclConnected(void)
+{
+ return aclConnected;
+}
+
+void BluetoothModel::SetTempMacValue(BluetoothCaseInfo *caseInfo)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetTempMacValue: %02x%02x%02x%02x%02x%02x",
+ caseInfo->addr[5], caseInfo->addr[4], caseInfo->addr[3], /* mac챐 0 1 2 3 4 5 */
+ caseInfo->addr[2], caseInfo->addr[1], caseInfo->addr[0]); /* mac챐 0 1 2 3 4 5 */
+ (void)memcpy_s(tempMacValue.addr, BD_ADDR_LEN,
+ caseInfo->addr, BD_ADDR_LEN);
+ (void)memcpy_s(tempMacValue.deviceName, BD_NAME_LEN,
+ caseInfo->deviceName, BD_NAME_LEN);
+}
+
+BluetoothCaseInfo *BluetoothModel::GetTempMacValue(void)
+{
+ return &tempMacValue;
+}
+
+// 设置最后连接的蓝牙设备地址
+void BluetoothModel::SetLastConnedAddr(const bd_addr_t *addr)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置最后连接的蓝牙设备地址: %02X:%02X:%02X:%02X:%02X:%02X",
+ addr->addr[5], addr->addr[4], addr->addr[3], /* mac챐 0 1 2 3 4 5 */
+ addr->addr[2], addr->addr[1], addr->addr[0]); /* mac챐 0 1 2 3 4 5 */
+ (void)memcpy_s(lastConnedAddr.addr, BD_ADDR_LEN, addr->addr, BD_ADDR_LEN);
+ if (addr != nullptr) {
+ char lastConnedDeviceName[BD_NAME_LEN] = {0};
+ snprintf(lastConnedDeviceName, BD_NAME_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
+ addr->addr[5], addr->addr[4], addr->addr[3], /* mac챐 0 1 2 3 4 5 */
+ addr->addr[2], addr->addr[1], addr->addr[0]); /* mac챐 0 1 2 3 4 5 */
+ SetBoundDeviceMac(lastConnedDeviceName);
+ }
+}
+
+// 获取最后连接的蓝牙设备地址
+bd_addr_t *BluetoothModel::GetLastConnedAddr(void)
+{
+ return &lastConnedAddr;
+}
+
+void BluetoothModel::SetConnectionView(BluetoothItemView *item)
+{
+ selectItemView = item;
+}
+
+BluetoothItemView *BluetoothModel::GetConnectionView()
+{
+ return selectItemView;
+}
+
+
+void BluetoothModel::SetTagReconnectJump(bool tag)
+{
+ tagReconnectJump = tag;
+}
+
+bool BluetoothModel::GetTagReconnectJump(void)
+{
+ return tagReconnectJump;
+}
+
+void BluetoothModel::SetCurView(int16_t viewNum)
+{
+ curView = viewNum;
+}
+
+int BluetoothModel::GetCurView(void)
+{
+ return curView;
+}
+
+void BluetoothModel::SetTagConnectView(bool tag)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagConnectView:%d", tag);
+ tagConnectView = tag;
+}
+
+// 判断是否需要跳转连接成功\失败界面(已退出蓝牙模块)
+bool BluetoothModel::IsTagConnectView(void)
+{
+ return tagConnectView;
+}
+
+void BluetoothModel::SetTagDisconnectView(bool tag)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagDisconnectView:%d", tag);
+ tagDisconnectView = tag;
+}
+
+// 判断是否需要跳转连接失败界面
+bool BluetoothModel::IsTagDisconnectView(void)
+{
+ return tagDisconnectView;
+}
+
+void BluetoothModel::SetTagConnectNew(bool tag)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagConnectNew:%d", tag);
+ tagConnectNew = tag;
+}
+
+void BluetoothModel::SetTagReturnToDeviceListView(bool tag)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagReturnToDeviceListView:%d", tag);
+ tagReturnToDeviceListView = tag;
+}
+
+bool BluetoothModel::IsTagReturnToDeviceListView(void)
+{
+ return tagReturnToDeviceListView;
+}
+
+// 判断断开连接时是否需要马上连接新设备
+bool BluetoothModel::IsTagConnectNew(void)
+{
+ return tagConnectNew;
+}
+
+// 设置是否已点击设备请求连接
+void BluetoothModel::SetTagScanDeviceClicked(bool tag)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BluetoothModel::SetTagScanDeviceClicked:%d", tag);
+ tagScanDeviceClicked = tag;
+}
+
+// 判断是否已点击设备请求连接
+bool BluetoothModel::IsTagScanDeviceClicked(void)
+{
+ return tagScanDeviceClicked;
+}
+
+bool BluetoothModel::CheckExistConnedList(BluetoothCaseInfo caseInfo)
+{
+ ListNode<BluetoothCaseInfo> *node = btConnedDevicesList_ ->Begin();
+ if (node == nullptr) {
+ return false;
+ } else if ((caseInfo.addr[0] == 0) && (caseInfo.addr[1] == 0)
+ && (caseInfo.addr[2] == 0) && (caseInfo.addr[3] == 0)
+ && (caseInfo.addr[4] == 0) && (caseInfo.addr[5] == 0)) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CheckExistConnedList false addr: 000000000000");
+ return true;
+ }
+ while (node != btConnedDevicesList_ ->End()) {
+ if ((caseInfo.addr[0] == node->data_.addr[0]) && (caseInfo.addr[1] == node->data_.addr[1])
+ && (caseInfo.addr[2] == node->data_.addr[2]) && (caseInfo.addr[3] == node->data_.addr[3])
+ && (caseInfo.addr[4] == node->data_.addr[4]) && (caseInfo.addr[5] == node->data_.addr[5])) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CheckExistConnedList true");
+ return true;
+ }
+ node = node->next_;
+ }
+ return false;
+}
+
+bool BluetoothModel::FindNameByAddr(BluetoothCaseInfo &listInfo, BluetoothCaseInfo *caseInfo)
+{
+ if ((listInfo.addr[0] == caseInfo->addr[0]) && (listInfo.addr[1] == caseInfo->addr[1]) &&
+ (listInfo.addr[2] == caseInfo->addr[2]) && (listInfo.addr[3] == caseInfo->addr[3]) &&
+ (listInfo.addr[4] == caseInfo->addr[4]) && (listInfo.addr[5] == caseInfo->addr[5])) {
+ (void)memcpy_s(caseInfo->deviceName, BD_NAME_LEN, listInfo.deviceName, BD_NAME_LEN);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "FindNameFromList success, deviceName:%s", listInfo.deviceName);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool BluetoothModel::FindNameFromList(BluetoothCaseInfo *caseInfo)
+{
+ ListNode<BluetoothCaseInfo> *node = btConnedDevicesList_->Begin();
+ if (!btScansDevicesList_.empty()) {
+ for (auto it = btScansDevicesList_.begin(); it != btScansDevicesList_.end(); it++) {
+ if (FindNameByAddr(*it, caseInfo)) {
+ return true;
+ }
+ }
+ }
+ if (node != nullptr) {
+ while (node != btConnedDevicesList_->End()) {
+ if (FindNameByAddr(node->data_, caseInfo)) {
+ return true;
+ }
+ node = node->next_;
+ }
+ }
+ return false;
+}
+
+bool BluetoothModel::GetBluetoothAclState(void)
+{
+ if ((lastConnedAddr.addr[0] == 0) && (lastConnedAddr.addr[1] == 0) &&
+ (lastConnedAddr.addr[2] == 0) && (lastConnedAddr.addr[3] == 0) &&
+ (lastConnedAddr.addr[4] == 0) && (lastConnedAddr.addr[5] == 0)) {
+ return false;
+ } else {
+ return bt_is_acl_connected(&lastConnedAddr);
+ }
+}
+
+bool BluetoothModel::GetAdvStartState(void)
+{
+ return advStartState;
+}
+void BluetoothModel::SetAdvStartState(bool state)
+{
+ advStartState = state;
+}
+
+// 连接远程设备
+int BluetoothModel::ConnectRemoteDevice(const bd_addr_t *addr)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice: 准备连接设备 addr=%02x%02x%02x%02x%02x%02x",
+ addr->addr[5], addr->addr[4], addr->addr[3],
+ addr->addr[2], addr->addr[1], addr->addr[0]);
+ /* 恢厂后耳机连接要开启BT广播否则会导致AVRCP无法音量控制 */
+ bool ret = gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE, 60);
+ if (!ret) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice gap_br_set_bt_scan_mode ret = 0x%x", ret);
+ }
+ errcode_t retVal = gap_connect_remote_device(addr);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "连接远程设备 ret = 0x%x", retVal);
+ (void)memcpy_s(&remoteConnectAddr, sizeof(bd_addr_t), addr, sizeof(bd_addr_t));
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice: remoteConnectAddr已设置为 %02x%02x%02x%02x%02x%02x",
+ remoteConnectAddr.addr[5], remoteConnectAddr.addr[4], remoteConnectAddr.addr[3],
+ remoteConnectAddr.addr[2], remoteConnectAddr.addr[1], remoteConnectAddr.addr[0]);
+ return retVal;
+}
+
+// 断开远程设备
+int BluetoothModel::DisconnectRemoteDevice(void)
+{
+ bd_addr_t *lastAddr = BluetoothModel::GetInstance()->GetLastConnedAddr();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "断开远程设备 Addr: %02X:%02X:%02X:%02X:%02X:%02X",
+ lastAddr->addr[5], lastAddr->addr[4], lastAddr->addr[3], /* mac下标 0 1 2 3 4 5 */
+ lastAddr->addr[2], lastAddr->addr[1], lastAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */
+ errcode_t retVal = gap_disconnect_remote_device(lastAddr);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gap_disconnect_remote_device %d", retVal);
+ // 清空正在连接的设备地址,避免影响后续连接
+ (void)memset_s(&remoteConnectAddr, sizeof(bd_addr_t), 0, sizeof(bd_addr_t));
+ return retVal;
+}
+
+// 解绑本地设备
+int BluetoothModel::UnBindLocalDevice(void)
+{
+ bd_addr_t *lastAddr = BluetoothModel::GetInstance()->GetLastConnedAddr();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "解绑蓝牙设备 Addr: %02X:%02X:%02X:%02X:%02X:%02X",
+ lastAddr->addr[5], lastAddr->addr[4], lastAddr->addr[3], /* mac下标 0 1 2 3 4 5 */
+ lastAddr->addr[2], lastAddr->addr[1], lastAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */
+ bool ret = gap_remove_pair(lastAddr);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "gap_remove_pair %d", ret);
+ return ret;
+}
+
+/* 解析蓝牙地址字符串为 bd_addr_t 结构 */
+static int parse_bt_address(const char *addr_str, bd_addr_t *addr)
+{
+ if (addr_str == NULL || addr == NULL) {
+ return 0;
+ }
+
+ // 支持格式: "AA:BB:CC:DD:EE:FF" 或 "AABBCCDDEEFF"
+ unsigned int addr_bytes[6] = {0};
+ int count = sscanf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X",
+ &addr_bytes[0], &addr_bytes[1], &addr_bytes[2],
+ &addr_bytes[3], &addr_bytes[4], &addr_bytes[5]);
+
+ if (count != 6) {
+ // 尝试无冒号格式
+ count = sscanf(addr_str, "%02X%02X%02X%02X%02X%02X",
+ &addr_bytes[0], &addr_bytes[1], &addr_bytes[2],
+ &addr_bytes[3], &addr_bytes[4], &addr_bytes[5]);
+ if (count != 6) {
+ return 0;
+ }
+ }
+
+ // 蓝牙地址是反向存储的
+ addr->addr[0] = (unsigned char)addr_bytes[5];
+ addr->addr[1] = (unsigned char)addr_bytes[4];
+ addr->addr[2] = (unsigned char)addr_bytes[3];
+ addr->addr[3] = (unsigned char)addr_bytes[2];
+ addr->addr[4] = (unsigned char)addr_bytes[1];
+ addr->addr[5] = (unsigned char)addr_bytes[0];
+
+ return 1;
+}
+
+// 解绑远程设备
+int BluetoothModel::UnBindRemoteDevice(const char *mac)
+{
+ if (mac == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice mac is nullptr");
+ return 0;
+ }
+ bd_addr_t addr = {0};
+ if (parse_bt_address((char*)mac, &addr) != 1) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ERROR: Invalid Bluetooth address format");
+ return ERRCODE_FAIL;
+ }
+
+ // 如果设备已连接,先断开连接,然后再解绑
+ if (bt_is_acl_connected(&addr)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice: 设备已连接,先断开连接");
+ errcode_t disconnect_ret = gap_disconnect_remote_device(&addr);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice: gap_disconnect_remote_device ret=%d", disconnect_ret);
+ // 等待一小段时间,确保断开连接完成
+ LOS_Msleep(200);
+ }
+
+ // 执行解绑操作(移除配对关系)
+ bool ret = gap_remove_pair(&addr);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice: gap_remove_pair ret=%d", ret);
+ if(ret == true)
+ {
+ // 从已连接设备列表中移除该设备
+ if (btConnedDevicesList_ != nullptr) {
+ ListNode<BluetoothCaseInfo> *node = btConnedDevicesList_->Begin();
+ while (node != nullptr && node != btConnedDevicesList_->End()) {
+ if ((node->data_.addr[0] == addr.addr[0]) && (node->data_.addr[1] == addr.addr[1]) &&
+ (node->data_.addr[2] == addr.addr[2]) && (node->data_.addr[3] == addr.addr[3]) &&
+ (node->data_.addr[4] == addr.addr[4]) && (node->data_.addr[5] == addr.addr[5])) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice: 从列表中移除设备 %02x%02x%02x%02x%02x%02x",
+ addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0]);
+ ListNode<BluetoothCaseInfo> *nextNode = node->next_;
+ btConnedDevicesList_->Remove(node);
+ node = nextNode;
+ } else {
+ node = node->next_;
+ }
+ }
+ }
+
+ // 刷新设备列表视图
+ ThunderBirdBlueView *thunderBirdBlueView = ThunderBirdBlueView::GetInstance();
+ if (thunderBirdBlueView != nullptr) {
+ thunderBirdBlueView->RefreshDeviceList();
+ }
+
+ // 只有在已连接状态下才能发送状态报告
+ if (ln_ws_get_connection_state() == 2)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UnBindRemoteDevice gap_remove_pair ret = 0");
+ char *bluetoothStatus = "UNBIND_SUCCESS";
+ do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));
+ }
+ }
+ else
+ {
+ char *bluetoothStatus = "UNBIND_FAILED";
+ do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));
+ }
+ return ret;
+}
+
+// 设置绑定的本地设备MAC地址
+void BluetoothModel::SetBoundDeviceMac(const char *mac)
+{
+ if (mac != nullptr) {
+ (void)strcpy_s(boundDeviceMac, BD_NAME_LEN, mac);
+ }
+}
+
+// 获取绑定的本地设备MAC地址
+char *BluetoothModel::GetBoundDeviceMac(void)
+{
+ return boundDeviceMac;
+}
+
+// 设置最后连接的设备名称
+void BluetoothModel::SetLastConnedDeviceName(const char *name)
+{
+ if (name != nullptr) {
+ (void)strcpy_s(lastConnedDeviceName, BD_NAME_LEN, name);
+ }
+}
+
+// 获取最后连接的设备名称
+char *BluetoothModel::GetLastConnedDeviceName(void)
+{
+ return lastConnedDeviceName;
+}
+
+// 设置最后连接的设备电池电量
+void BluetoothModel::SetLastConnedDeviceBatteryLevel(int level)
+{
+ lastConnedDeviceBatteryLevel = level;
+}
+
+// 获取最后连接的设备电池电量
+int BluetoothModel::GetLastConnedDeviceBatteryLevel(void)
+{
+ return lastConnedDeviceBatteryLevel;
+}
+
+// 设置扫描状态
+void BluetoothModel::SetScanStatus(bool value)
+{
+ scanStart = value;
+}
+
+// 获取扫描状态
+bool BluetoothModel::GetScanStatus(void)
+{
+ return scanStart;
+}
+
+// 检查是否是正在连接的设备
+bool BluetoothModel::ConnectRemoteCheck(const bd_addr_t *addr)
+{
+ bool ret;
+ // 如果remoteConnectAddr为空(全0),说明没有明确的连接目标,允许A2DP连接
+ if ((remoteConnectAddr.addr[0] == 0) && (remoteConnectAddr.addr[1] == 0) &&
+ (remoteConnectAddr.addr[2] == 0) && (remoteConnectAddr.addr[3] == 0) &&
+ (remoteConnectAddr.addr[4] == 0) && (remoteConnectAddr.addr[5] == 0)) {
+ return true;
+ }
+ // 检查地址是否匹配
+ if ((remoteConnectAddr.addr[0] == addr->addr[0]) && (remoteConnectAddr.addr[1] == addr->addr[1]) &&
+ (remoteConnectAddr.addr[2] == addr->addr[2]) && (remoteConnectAddr.addr[3] == addr->addr[3]) &&
+ (remoteConnectAddr.addr[4] == addr->addr[4]) && (remoteConnectAddr.addr[5] == addr->addr[5])) {
+ ret = true;
+ (void)memset_s(&remoteConnectAddr, sizeof(bd_addr_t), 0, sizeof(bd_addr_t));
+ } else {
+ ret = false;
+ }
+ return ret;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 回调: gap_read_remote_rssi_value 接口的数据上报
+void BtGapReadRemoteRssiEventCallback(const bd_addr_t *bdAddr, int rssi, int status)
+{
+ UNUSED(status);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGapReadRemoteRssiEventCallback addr: %02x%02x%02x%02x%02x%02x",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */
+ BluetoothModel::GetInstance()->SetScansCaseRssi(bdAddr, rssi);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bt BtGapReadRemoteRssiEventCallback SetSortCaseRssi: %d status: %d", rssi, status);
+}
+
+// 回调:发现状态变化上报/扫描结束
+void BtGapDiscoveryStateChangedCallback(int status)
+{
+ UNUSED(status);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bt BtGapDiscoveryStateChangedCallback %d", status);
+}
+
+// 回调:发现设备上报处理
+void BluetoothModel::BtGapDiscoveryResultCallbakHandle(const bd_addr_t &bdAddr)
+{
+ BluetoothCaseInfo caseInfo{};
+ (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN);
+ unsigned char nameLen = BD_NAME_LEN;
+ bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发现蓝牙设备 : %d nameLen: %d name:%s",getNameRet, nameLen, caseInfo.deviceName);
+ if (nameLen == 0) { // 过滤未扫描到名字的设备
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "过滤未扫描到名字的设备");
+ return;
+ }
+ // 去重操作
+ bool tag = BluetoothModel::GetInstance()->CheckExistScanList(caseInfo);
+ if (!tag)
+ {
+ BluetoothModel::GetInstance()->AddCase(caseInfo); // 增加扫描设备信息
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckExistScanList true");
+ }
+
+ bool ret = gap_read_remote_rssi_value(&bdAddr); // 获取rssi
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "gap_read_remote_rssi_value ret = %d", ret);
+
+ tag = GetScanStatus();
+ if (tag) {
+ // 扫描状态下不立即跳转,等待定时器触发(至少10秒后)
+ // 只记录设备,由定时器控制跳转时机
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "扫描中,已发现 %d 个设备", btScansDevicesList_.size());
+ } else {
+ // 已在设备列表界面,刷新列表
+ ThunderBirdBlueView *thunderBirdBlueView = ThunderBirdBlueView::GetInstance();
+ if (thunderBirdBlueView == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderBirdBlueView nullptr");
+ return;
+ }
+ thunderBirdBlueView->RefreshDeviceList();
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtGapDiscoveryResultCallback end");
+}
+
+//蓝牙取消配对ui处理
+static void UnpairDevice(const bd_addr_t *bdAddr)
+{
+ if(ThunderBirdMainView::GetInstance()) {
+ int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+ ThunderBirdMainView::GetInstance()->ChangeView(currentView,
+ THUNDERBIRD_BLUEVIEW,
+ ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_SUCCESS_NEW);
+ }
+ return;
+}
+
+void BtGapPairStatusChangedCallback(const bd_addr_t *bdAddr, int status)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对状态变化 addr: ****%02x%02x%02x%02x status: %d\n",
+ bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], status); /* addr下标 0 1 2 3 */
+ if(status == GAP_PAIR_NONE){
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "取消配对");
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(UnpairDevice, bdAddr));
+ } else if(status == GAP_PAIR_PAIRING){
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "正在配对");
+ } else if(status == GAP_PAIR_PAIRED){
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对成功");
+ }
+}
+
+void BtGapPairRequestedCallback(const bd_addr_t *bdAddr)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对请求 addr: ****%02x%02x%02x%02x\n",
+ bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* addr下标 0 1 2 3 */
+}
+
+void BtGapPairConfirmedCallback(const bd_addr_t *bdAddr, int req_type, int number)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "配对确认 addr: ****%02x%02x%02x%02x req_type: %d number: %d\n",
+ bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], /* addr下标 0 1 2 3 */
+ req_type, number);
+}
+// 回调:远程电池等级变化上报
+void BtGapRemoteBatteryLevelChangedCallback(const bd_addr_t *bdAddr, int level)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "远程电池等级变化 addr: ****%02x%02x%02x%02x level: %d\n",
+ bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], level); /* addr下标 0 1 2 3 */
+}
+
+// 回调:扫描结果处理/发现结果上报
+void BtGapDiscoveryResultCallback(const bd_addr_t *bdAddr)
+{
+ if ((gap_get_device_class(bdAddr) & DEVICE_MAJOR_CLASS_PHONE) != 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发现结果: Mobile Phone Device");
+ return;
+ }
+
+ if (bdAddr == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "addr nullptr");
+ return;
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发现结果 addr: %02x:%02x:%02x:%02x:%02x:%02x",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(&BluetoothModel::BtGapDiscoveryResultCallbakHandle,
+ BluetoothModel::GetInstance(), *bdAddr));
+}
+
+void HandleBeforeChangeView()
+{
+ int curView = BluetoothModel::GetInstance()->GetCurView();
+ if (curView == BLUETOOTHEARPHONEVIEW) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView curView == BLUETOOTHEARPHONEVIEW");
+ BluetoothEarPhoneView *bluetoothEarPhoneView = BluetoothEarPhoneView::GetInstance();
+ if (bluetoothEarPhoneView == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView bluetoothEarPhoneView == nullptr");
+ return;
+ }
+ bluetoothEarPhoneView->BtAnimatorStop();
+ bluetoothEarPhoneView->StopBtDiscovery();
+ } else if (curView == BLUETOOTHEARLISTVIEW) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView curView == BLUETOOTHEARLISTVIEW");
+ BluetoothEarPhoneView *bluetoothEarPhone = BluetoothEarPhoneView::GetInstance();
+ if (bluetoothEarPhone == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView bluetoothEarPhoneView == nullptr");
+ return;
+ }
+ bluetoothEarPhone->StopBtDiscovery();
+ BluetoothItemView *pbItermView = BluetoothModel::GetInstance()->GetConnectionView();
+ if (pbItermView == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView The GetConnectionView get failed.");
+ return;
+ }
+ pbItermView->ConnectAnimatorStop();
+ BluetoothModel::GetInstance()->SetConnectionView(nullptr);
+ } else if (curView == BLUETOOTHRECONNECTVIEW) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView curView == BLUETOOTHRECONNECTVIEW");
+ BluetoothReconnectView *bluetoothReconnectView = BluetoothReconnectView::GetInstance();
+ if (bluetoothReconnectView == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HandleBeforeChangeView bluetoothReconnectView == nullptr");
+ return;
+ }
+ bluetoothReconnectView->BtReconnectStop();
+ }
+}
+
+// 回调:ACL连接成功
+static void ACLConnectionSuss(const bd_addr_t &bdAddr)
+{
+ BluetoothCaseInfo caseInfo;
+ (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN);
+ unsigned char nameLen = BD_NAME_LEN;
+ bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接成功 deviceName: %s", caseInfo.deviceName);
+ BluetoothModel::GetInstance()->SetLastConnedDeviceName((const char *)caseInfo.deviceName);
+ if(strcmp((const char *)caseInfo.deviceName, BluetoothModel::GetInstance()->GetLastConnedDeviceName()) == 0){
+
+ //亮屏操作
+ uapi_set_screen_on_api();
+
+ ThunderBirdMainView *thunderBirdMainView = ThunderBirdMainView::GetInstance();
+ if (thunderBirdMainView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderBirdMainView nullptr");
+ return;
+ }
+ int currentView = thunderBirdMainView->GetCurrentView();
+ thunderBirdMainView->ChangeView(
+ currentView,
+ THUNDERBIRD_BLUEVIEW,
+ ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_SUCCESS);
+ }
+}
+
+// 回调:ACL连接失败
+static void ACLConnectionFail(const bd_addr_t &bdAddr)
+{
+ // 如果当前正处于“切换到新耳机”的流程中(用户点了另一台设备准备自动重连),
+ // 就不要弹出“连接已断开”页面,直接走后续新设备连接流程,避免多余页面跳转。
+ BluetoothModel* btModel = BluetoothModel::GetInstance();
+ if (btModel != nullptr && (btModel->IsTagConnectNew() || btModel->IsTagScanDeviceClicked())) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "ACLConnectionFail: in switch-device flow, skip DISCONNECT_SUCCESS page");
+ // 清掉“需要自动连接新设备”的标记,由后续连接结果负责更新界面
+ btModel->SetTagConnectNew(false);
+ return;
+ }
+
+ BluetoothCaseInfo caseInfo;
+ (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN);
+ unsigned char nameLen = BD_NAME_LEN;
+ bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接断开 deviceName: %s", caseInfo.deviceName);
+ // 设备名为空不处理
+ if(strcmp((const char *)caseInfo.deviceName, "") == 0){
+ return;
+ }
+ if(strcmp((const char *)caseInfo.deviceName, BluetoothModel::GetInstance()->GetLastConnedDeviceName()) == 0)
+ {
+
+ //亮屏操作
+ uapi_set_screen_on_api();
+
+ ThunderBirdMainView *thunderBirdMainView = ThunderBirdMainView::GetInstance();
+ if (thunderBirdMainView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "thunderBirdMainView nullptr");
+ return;
+ }
+ int currentView = thunderBirdMainView->GetCurrentView();
+ thunderBirdMainView->ChangeView(
+ currentView,
+ THUNDERBIRD_BLUEVIEW,
+ ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_SUCCESS);
+ }
+}
+void BluetoothModel::BtGapAclStateChangedHandle(gap_acl_state_t state, unsigned int reason, const bd_addr_t &bdAddr)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtGapAclStateChangedHandle reason is %x", reason);
+ bool tag = BluetoothModel::GetInstance()->IsTagScanDeviceClicked();
+ if ((reason == 0x13) || (reason == 0x14) || (reason == 0x15) || (reason == 0x3D) || (reason == 0x08 && (!tag))) { // 连接断开
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "蓝牙设备主动断开连接 reason is %x", reason);
+ } else if (reason == 0x16) { // 主动断开连接
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "主动断开与蓝牙设备连接,reason is%x", reason);
+ BluetoothCaseInfo *onClickBtCaseInfo = BluetoothModel::GetInstance()->GetTempMacValue();
+ if (BluetoothModel::GetInstance()->IsTagConnectNew()) {
+ errcode_t retVal = ConnectRemoteDevice((const bd_addr_t *)&onClickBtCaseInfo->addr);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice retVal = %d", retVal);
+ }
+ } else if ((reason == 0xb) || (reason > 0x45)) { // 0xb:重复点击连接按钮 0x45:acl状态最大参数
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "reason is false.");
+ SetTagDisconnectView(false);
+ }
+ else if(reason == 0x2){
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接失败,链路连接被对端主动拒绝/未响应 reason is 0x2.");
+ // 检查是否是期望连接的设备
+ BluetoothCaseInfo *expectedDevice = GetTempMacValue();
+ bool isExpectedDevice = false;
+ if (expectedDevice != nullptr) {
+ isExpectedDevice = (memcmp(expectedDevice->addr, bdAddr.addr, BD_ADDR_LEN) == 0);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接失败: 期望设备=%02x%02x%02x%02x%02x%02x, 回调地址=%02x%02x%02x%02x%02x%02x, 匹配=%d",
+ expectedDevice->addr[5], expectedDevice->addr[4], expectedDevice->addr[3],
+ expectedDevice->addr[2], expectedDevice->addr[1], expectedDevice->addr[0],
+ bdAddr.addr[5], bdAddr.addr[4], bdAddr.addr[3],
+ bdAddr.addr[2], bdAddr.addr[1], bdAddr.addr[0],
+ isExpectedDevice);
+ }
+ // 清除连接状态标记(无论地址是否匹配,都清除,因为连接已失败)
+ SetTagScanDeviceClicked(false);
+ // 清空正在连接的设备地址
+ (void)memset_s(&remoteConnectAddr, sizeof(bd_addr_t), 0, sizeof(bd_addr_t));
+ // 刷新设备列表以停止"连接中"动画
+ ThunderBirdBlueView *thunderBirdBlueView = ThunderBirdBlueView::GetInstance();
+ if (thunderBirdBlueView != nullptr) {
+ thunderBirdBlueView->RefreshDeviceList();
+ }
+ if(ThunderBirdMainView::GetInstance()) {
+ int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+ ThunderBirdMainView::GetInstance()->ChangeView(currentView,
+ THUNDERBIRD_BLUEVIEW,
+ ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_FAILED);
+ }
+ return;
+ }
+
+ if ((state == GAP_ACL_STATE_CONNECTED) || (state == GAP_ACL_STATE_LE_CONNECTED)) {
+ SetLastConnedAddr(&bdAddr);
+ // 将数据存入设备列表
+ BluetoothCaseInfo *info = GetTempMacValue();
+ tag = CheckExistConnedList(*info);
+ if ((!tag) && (memcmp(info->addr, bdAddr.addr, BD_ADDR_LEN) == 0)) {
+ AddConnedDevicesCase(*info);
+ }
+ }
+ else
+ {
+ ACLConnectionFail(bdAddr);
+ }
+
+ if ((state == GAP_ACL_STATE_CONNECTED) || (state == GAP_ACL_STATE_LE_CONNECTED)) {
+ if (BluetoothModel::GetInstance()->ConnectRemoteCheck(&bdAddr)) {
+ int32_t retA2dp = a2dp_src_connect(&bdAddr);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "a2dp连接结果 result 0x%x", retA2dp);
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "忽略a2dp连接");
+ }
+ }
+}
+
+void ChangeBleConnectToMax()
+{
+ if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) {
+ gap_conn_param_update_t conn_param = { 0 };
+ conn_param.conn_handle = BLUETOOTH_CONN_HANDLE;
+ conn_param.interval_min = BLUETOOTH_INTERVAL_TOMAX_MIN;
+ conn_param.interval_max = BLUETOOTH_INTERVAL_TOMAX_MAX;
+ conn_param.slave_latency = BLUETOOTH_LATENCY;
+ conn_param.timeout_multiplier = BLUETOOTH_TIMEOUT_MUTIPLIER;
+ errcode_t ret = gap_ble_connect_param_update(&conn_param);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback change to max interval ret:%d : latency-min:%u latency-max:%u\n",
+ ret, conn_param.interval_min, conn_param.interval_max);
+ }
+}
+
+void ChangeBleConnectToDefault()
+{
+ if (msg_center_get_trans_channel() == DIAG_FRAME_FID_BT) {
+ gap_conn_param_update_t conn_param = { 0 };
+ conn_param.conn_handle = BLUETOOTH_CONN_HANDLE;
+ conn_param.interval_min = BLUETOOTH_INTERVAL_TODEFAULT_MIN;
+ conn_param.interval_max = BLUETOOTH_INTERVAL_TODEFAULT_MAX;
+ conn_param.slave_latency = BLUETOOTH_LATENCY;
+ conn_param.timeout_multiplier = BLUETOOTH_TIMEOUT_MUTIPLIER;
+ errcode_t ret = gap_ble_connect_param_update(&conn_param);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback change to default interval ret:%d : latency-min:%u latency-max:%u\n",
+ ret, conn_param.interval_min, conn_param.interval_max);
+ }
+}
+
+// 回调:ACL连接状态上报
+void GapAclStateChangedCallback(const bd_addr_t *bdAddr, gap_acl_state_t state, unsigned int reason)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ACL连接状态上报 state %d, reason %x succ or err", state, reason);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "addr: %02x%02x%02x%02x%02x%02x",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */
+
+ // 检查设备类型
+ uint32_t deviceClass = gap_get_device_class(bdAddr);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: deviceClass=0x%x, (class&0x200)=0x%x",
+ deviceClass, deviceClass & 0x200);
+
+ // 获取当前期望连接的设备地址
+ BluetoothModel* btModel = BluetoothModel::GetInstance();
+ BluetoothCaseInfo* expectedDevice = btModel->GetTempMacValue();
+ if (expectedDevice != nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: 期望连接的设备 addr=%02x%02x%02x%02x%02x%02x",
+ expectedDevice->addr[5], expectedDevice->addr[4], expectedDevice->addr[3],
+ expectedDevice->addr[2], expectedDevice->addr[1], expectedDevice->addr[0]);
+ }
+
+ static bd_addr_t gapAclConnectAddr{0}; /* 连接后保存手机地址,手表清除手机配对后查询不到class比较手机地址 */
+ if ((deviceClass & 0x200) != 0 || memcmp(gapAclConnectAddr.addr, bdAddr->addr, BD_ADDR_LEN) == 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: Mobile Phone Device (class&0x200=%d, matched=%d)",
+ (deviceClass & 0x200) != 0, memcmp(gapAclConnectAddr.addr, bdAddr->addr, BD_ADDR_LEN) == 0);
+ if (state == GAP_ACL_STATE_DISCONNECTED) {
+ /* 通知msg_center,ble状态仍用bt状态,此处不区分 */
+ // MsgCenterSendMsg(BT_DISCONNECTED_TO_MSGCENTER, 0, nullptr, 0);
+ // SendMsgToUIService(BT_DISCONNECTED_TO_UI, 0, nullptr, 0);
+ // send to ace network
+ // SetAclConnected(false);
+ // net_connect_status_change(NETWORK_TYPE_BLUETOOTH, CONNECTION_STATUS_DISCONNECTED);
+ } else if (state == GAP_ACL_STATE_CONNECTED) {
+ (void)memcpy_s(gapAclConnectAddr.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);
+ // MsgCenterSendMsg(BT_CONNECTED_TO_MSGCENTER, 0, nullptr, 0);
+ // SendMsgToUIService(BT_CONNECTED_TO_UI, 0, nullptr, 0);
+ // send to ace network
+ // SetAclConnected(true);
+#if defined(SUPPORT_LWIP) && defined(SUPPORT_BREDR)
+ // bt_pan_open();
+#endif
+ // net_connect_status_change(NETWORK_TYPE_BLUETOOTH, CONNECTION_STATUS_CONNECTED);
+ }
+ return;
+ }
+
+ GraphicService::GetInstance()->PostGraphicEvent(
+ std::bind(&BluetoothModel::BtGapAclStateChangedHandle, BluetoothModel::GetInstance(), state, reason, *bdAddr));
+}
+
+// 回调:远端设备名称变化
+void BtRemoteNameChangedCallback(const bd_addr_t *bdAddr, const unsigned char *deviceName, unsigned char length)
+{
+ if ((gap_get_device_class(bdAddr) & 0x200) != 0) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback: Mobile Phone Device");
+ return;
+ }
+ BluetoothCaseInfo caseInfo{};
+ if (bdAddr == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback addr nullptr");
+ return;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback addr: %02x%02x%02x%02x%02x%02x",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */
+
+ (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);
+ int ret = memcpy_s(caseInfo.deviceName, BD_NAME_LEN, deviceName, length);
+ if (ret != EOK) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BtRemoteNameChangedCallback memcpy fail!");
+ return;
+ }
+ BluetoothModel::GetInstance()->ResetScanDevicesCase(caseInfo);
+}
+
+void BtIsAcceptConnOnSafeModeCallback(const bd_addr_t *bdAddr, bool *res)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtIsAcceptConnOnSafeModeCallback addr: %02x%02x%02x%02x%02x%02x set *res true",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* addr下标 3 4 5 */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* addr下标 0 1 2 */
+ *res = true;
+}
+
+static void A2dpSrcConnectstateChanged(bd_addr_t *bdAddr, int connState)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "a2dp_src_connectStateChangedCallback addr: %02x%02x%02x%02x%02x%02x connState: %x",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* 5 4 3 idx */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], connState); /* 2 1 0 idx */
+ if ((gap_get_device_class(bdAddr) & 0x200) != 0) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "a2dp_src_connectstateChangedCb: Mobile Phone Device");
+ return;
+ }
+ if (connState == PROFILE_STATE_CONNECTED) {
+ uint32_t ret = avrcp_ct_connect(bdAddr);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "avrcp_ct_connect ret = 0x%x", ret);
+
+ set_a2dp_is_connect(true);
+ PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_CONNECTED);
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(ACLConnectionSuss, *bdAddr));
+ int earphoneConnectStatus = 1;
+ SendMsgToUIService(HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY, 0, &earphoneConnectStatus, sizeof(earphoneConnectStatus));
+ }
+
+ if (connState == PROFILE_STATE_DISCONNECTED) {
+
+
+ PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_DISCONNECTED);
+
+ set_a2dp_is_connect(false);
+
+
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(ACLConnectionFail, *bdAddr));
+ int earphoneConnectStatus = 0;
+ SendMsgToUIService(HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY, 0, &earphoneConnectStatus, sizeof(earphoneConnectStatus));
+ /* 实验室测试耳机回连场景,用户根据需要调整策略 */
+ bool ret = gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 60); // start scan
+ if (!ret) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "a2dp disc: gap_br_set_bt_scan_mode ret = 0x%x", ret);
+ }
+ }
+ //上报蓝牙耳机连接状态
+ GraphicService::GetInstance()-> PostGraphicEvent(std::bind(ln_bt_report_earphone_connection_status));
+}
+
+uint8_t A2dpSrcPlayingState=0;
+
+static void A2dpSrcPlayingStateChanged(bd_addr_t *bdAddr, int playState)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "A2dpSrcPlayingStateChangedCallback addr: %02x%02x%02x%02x%02x%02x playState: %x",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* 5 4 3 idx */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0], playState); /* 2 1 0 idx */
+ A2dpSrcPlayingState=playState;
+
+}
+
+uint8_t get_A2dpSrcPlayingStat(void)
+{
+ return A2dpSrcPlayingState;
+}
+
+static void A2dpSrcConfigureChanged(bd_addr_t *bdAddr, a2dp_codec_info_t *info)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "A2dpSrcConfigurationChangedCallback addr: %02x%02x%02x%02x%02x%02x ",
+ bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* 5 4 3 idx */
+ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* 2 1 0 idx */
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "codec_priority: %04x codec_type: %04x sample_rate: %02x bits_per_sample: %02x channel_mode: %02x ",
+ info->codec_priority, info->codec_type, info->sample_rate, info->bits_per_sample, info->channel_mode);
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "codec_specific1: %04x codec_specific2: %04x codec_specific3: %04x codec_specific4: %04x",
+ info->codec_specific1, info->codec_specific2, info->codec_specific3, info->codec_specific4);
+}
+
+static void BleConnStateChangeCallback(unsigned short connId, bd_addr_t *addr, gap_ble_conn_state_t connState,
+ gap_ble_pair_state_t pairState, gap_ble_disc_reason_t discReason)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnStateChangeCallback connId 0x%x, connState 0x%x, pairState 0x%x",
+ connId, connState, pairState);
+ if (GAP_BLE_STATE_DISCONNECTED == connState) { // restart ble adv when disconnected
+ /* 通知msg_center,ble状态仍用bt状态,此处不区分 */
+ MsgCenterSendMsg(BT_DISCONNECTED_TO_MSGCENTER, 0, nullptr, 0);
+ msg_center_set_ble_conn_state(GAP_BLE_STATE_DISCONNECTED);
+ // send to ace network
+ net_connect_status_change(NETWORK_TYPE_BLUETOOTH_LE, CONNECTION_STATUS_DISCONNECTED);
+ } else {
+ MsgCenterSendMsg(BT_CONNECTED_TO_MSGCENTER, 0, nullptr, 0);
+ msg_center_set_ble_conn_state(GAP_BLE_STATE_CONNECTED);
+ (void)memcpy_s(&g_bd_addr, sizeof(bd_addr_t), addr, sizeof(bd_addr_t));
+ // send to ace network
+ net_connect_status_change(NETWORK_TYPE_BLUETOOTH_LE, CONNECTION_STATUS_CONNECTED);
+ }
+ // send to ace network
+}
+
+static void BleAdvStartCallback(uint8_t advId, adv_status_t status)
+{
+ if (g_sample_adv_id == advId) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStartCallback advId: %d, status:%d\n", advId, status);
+ BluetoothModel::GetInstance()->SetAdvStartState(true);
+ }
+}
+
+static void BleAdvStopCallback(uint8_t advId, adv_status_t status)
+{
+ if (g_sample_adv_id == advId) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStopCallback advId: %d, status:%d\n", advId, status);
+ BluetoothModel::GetInstance()->SetAdvStartState(false);
+ }
+}
+
+static void BleAdvTerminateCallback(uint8_t advId, adv_status_t status)
+{
+ if (g_sample_adv_id == advId) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvTerminateCallback advId: %d, status:%d\n", advId, status);
+ BluetoothModel::GetInstance()->SetAdvStartState(false);
+ // 此处开广播是为了实验室测试需要,客户需要自己修改
+ BleAdvStart();
+ }
+}
+
+static void BtGattsServiceAddCallback(uint8_t serverId, bt_uuid_t *uuid, uint16_t srvcHandle, errcode_t status)
+{
+ if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t*)uuid->uuid) == 0xF01F)) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceAddCallback 0x%x 0x%x 0x%x",
+ status, serverId, srvcHandle);
+ uint16_t sample_id = 0xF11F;
+ uint16_t diag_id = 0xF21F;
+ gatts_add_chara_info_t character;
+ uint16_t value = 0;
+
+ memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t));
+ character.chara_uuid.uuid_len = sizeof(sample_id);
+ memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&sample_id, sizeof(sample_id));
+ character.permissions = GATT_ATTRIBUTE_PERMISSION_WRITE;
+ character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP;
+ character.value_len = (uint16_t)sizeof(value);
+ character.value = (uint8_t *)(&value);
+ int ret = gatts_add_characteristic(serverId, srvcHandle, &character);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_characteristic sample ret 0x%x", ret);
+
+ memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t));
+ character.chara_uuid.uuid_len = sizeof(diag_id);
+ memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&diag_id, sizeof(diag_id));
+ character.permissions = GATT_ATTRIBUTE_PERMISSION_WRITE | GATT_ATTRIBUTE_PERMISSION_READ;
+ character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP | GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY;
+ character.value_len = (uint16_t)sizeof(value);
+ character.value = (uint8_t *)(&value);
+
+ ret = gatts_add_characteristic(serverId, srvcHandle, &character);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_characteristic diag ret 0x%x", ret);
+
+ g_sample_svr_handle = srvcHandle;
+ }
+}
+
+static void BtGattsCharacteristicAddCallback(uint8_t serverId, bt_uuid_t *uuid, uint16_t srvcHandle, gatts_add_character_result_t *result, errcode_t status)
+{
+ if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t*)uuid->uuid) == 0xF11F)) {
+ g_sample_characteristic_handle = result->value_handle;
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsCharacteristicAddCallback 0x%x 0x%x 0x%x 0x%x",
+ status, serverId, srvcHandle, g_sample_characteristic_handle);
+ }
+ if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t*)uuid->uuid) == 0xF21F)) {
+ g_diag_characteristic_handle = result->value_handle;
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsCharacteristicAddCallback 0x%x 0x%x 0x%x 0x%x",
+ status, serverId, srvcHandle, g_diag_characteristic_handle);
+
+ uint8_t ccc_val[] = { 0x01, 0x00 };
+ uint16_t diag_desc = 0x0229;
+ gatts_add_desc_info_t descriptor;
+ memset_s(&descriptor, sizeof(gatts_add_desc_info_t), 0, sizeof(gatts_add_desc_info_t));
+ descriptor.desc_uuid.uuid_len = sizeof(diag_desc);
+ memcpy_s(descriptor.desc_uuid.uuid, sizeof(descriptor.desc_uuid.uuid), (char *)&diag_desc, sizeof(diag_desc));
+ descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE;
+ descriptor.value_len = (uint16_t)sizeof(ccc_val);
+ descriptor.value = ccc_val;
+ int ret = gatts_add_descriptor(serverId, srvcHandle, &descriptor);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_descriptor diag_desc ret 0x%x", ret);
+ }
+
+ if (g_sample_characteristic_handle != 0 && g_diag_characteristic_handle !=0 && g_diag_desc_handle != 0) {
+ int ret = gatts_start_service(serverId, srvcHandle);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_start_service ret 0x%x", ret);
+ }
+}
+
+static void BtGattsDescriptorAddCallback(uint8_t serverId, bt_uuid_t *uuid, uint16_t srvcHandle, uint16_t descriptorHandle, errcode_t status)
+{
+ if (g_sample_svr_handle == srvcHandle) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsDescriptorAddCallback 0x%x 0x%x 0x%x 0x%x",
+ status, serverId, srvcHandle, descriptorHandle);
+ g_diag_desc_handle = descriptorHandle;
+ }
+
+ if (g_sample_characteristic_handle != 0 && g_diag_characteristic_handle !=0 && g_diag_desc_handle != 0) {
+ int ret = gatts_start_service(serverId, srvcHandle);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_start_service ret 0x%x", ret);
+ }
+}
+
+static void BtGattsServiceStartCallback(uint8_t serverId, uint16_t srvcHandle, errcode_t status)
+{
+ if (g_sample_svr_handle == srvcHandle) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceStartCallback 0x%x 0x%x 0x%x", status, serverId, srvcHandle);
+ }
+}
+
+static void BtGattsServiceStopCallback(uint8_t serverId, uint16_t srvcHandle, errcode_t status)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceStopCallback 0x%x 0x%x 0x%x", status, serverId, srvcHandle);
+}
+
+static void BtGattsServiceDeleteCallback(uint8_t serverId, errcode_t status)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsServiceDeleteCallback 0x%x 0x%x", status, serverId);
+}
+
+static void BtGattsRequestReadCallback(uint8_t serverId, uint16_t connId, gatts_req_read_cb_t *readCbPara, errcode_t status)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGattsRequestReadCallback handle = %u", readCbPara->handle);
+}
+
+static void BtGattsRequestWriteCallback(uint8_t serverId, uint16_t connId, gatts_req_write_cb_t *writeCbPara, errcode_t status)
+{
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGattsRequestWriteCallback handle = %u", writeCbPara->handle);
+ if (g_sample_characteristic_handle == writeCbPara->handle) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "BtGattsRequestWriteCallback handle = %u", writeCbPara->handle);
+ if (writeCbPara->length == 9) {
+ if (memcmp("open ctkd", writeCbPara->value, writeCbPara->length) == 0) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "enable ctkd");
+ // 一键双连使能(依赖安全连接参数配置)
+ errcode_t ret = gap_ble_set_ctkd_enable(true);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gap_ble_set_ctkd_enable ret = %u", ret);
+
+ // 发起ble配对
+ ret = gap_ble_pair_remote_device(&g_bd_addr);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gap_ble_pair_remote_device ret = %u ", ret);
+ }
+ } else if (writeCbPara->length == 10) {
+ if (memcmp("close ctkd", writeCbPara->value, writeCbPara->length) == 0) {
+ // 一键双连去使能
+ errcode_t ret = gap_ble_set_ctkd_enable(false);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gap_ble_set_ctkd_disable ret = %u", ret);
+ }
+ }
+ } else if (g_diag_characteristic_handle == writeCbPara->handle) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "diag_gatt_write_req_cbk handle = %u", writeCbPara->handle);
+ diag_gatt_write_req_cbk(serverId, connId, writeCbPara, status);
+ } else if (g_diag_desc_handle == writeCbPara->handle) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "diag_gatt_set_handle handle = %u", writeCbPara->handle);
+ if ((writeCbPara->length == 2) && (*(char*)(writeCbPara->value) == 1)) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "open gatt channel");
+ diag_gatt_set_handle(serverId, connId, g_diag_characteristic_handle);
+ msg_center_set_trans_channel(DIAG_FRAME_FID_BT);
+ } else if ((writeCbPara->length == 2) && (*(char*)(writeCbPara->value) == 0)) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "close gatt channel");
+ diag_gatt_set_handle(0, 0, 0);
+ msg_center_set_trans_channel(DIAG_FRAME_FID_PHONE);
+ }
+ }
+}
+
+static void BtGattsMtuChangedCallback(uint8_t serverId, uint16_t connId, uint16_t mtuSize, errcode_t status)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BtGattsMtuChangedCallback connId = %u mtuSize = %u", connId, mtuSize);
+}
+
+static void BtA2dpSnkAcceptTimerStop(void)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "stop timer\n");
+ if (g_a2dp_stream_accept_timer.timer != nullptr) {
+ (void)osal_timer_stop(&g_a2dp_stream_accept_timer);
+ (void)osal_timer_destroy(&g_a2dp_stream_accept_timer);
+ g_a2dp_stream_accept_timer.timer = nullptr;
+ }
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "stop timer success!\n");
+}
+
+static void BtA2dpSnStartAcceptHandler(unsigned long data)
+{
+ UNUSED(data);
+ bd_addr_t active_bd_addr = a2dp_snk_get_active_device();
+ a2dp_snk_start_accept(&active_bd_addr);
+ BtA2dpSnkAcceptTimerStop();
+}
+
+static errcode_t BtA2dpSnkStartAcceptTimer(void)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "start timer\n");
+ if (g_a2dp_stream_accept_timer.timer != nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timer is running");
+ return ERRCODE_SUCC;
+ }
+
+ g_a2dp_stream_accept_timer.handler = BtA2dpSnStartAcceptHandler;
+ g_a2dp_stream_accept_timer.interval = A2DP_STREAM_ACCEPT_TIMER_PERIOD;
+
+ int32_t timer_ret = osal_timer_init(&g_a2dp_stream_accept_timer);
+ if (timer_ret != EOK) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "create timer error! ret: %x\n", timer_ret);
+ BtA2dpSnkAcceptTimerStop();
+ return ERRCODE_FAIL;
+ }
+ timer_ret = osal_timer_start(&g_a2dp_stream_accept_timer);
+ if (timer_ret != EOK) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "start timer error! ret: %x\n", timer_ret);
+ BtA2dpSnkAcceptTimerStop();
+ return ERRCODE_FAIL;
+ }
+ return ERRCODE_SUCC;
+}
+
+static int32_t BtA2dpSnkAudioCreate()
+{
+#if MEDIA_A2DP_SNK_INTERFACE
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "audioFormat %d channelCount %d sampleRate %d \n",
+ g_audio_format_config.audioFormat, g_audio_format_config.channelCount, g_audio_format_config.sampleRate);
+
+ int32_t ret = AudioManagerA2dpSinkSetParam(g_audio_format_config);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AudioManagerA2dpSinkSetParam ret %x\n", ret);
+ ret = AudioManagerA2dpSinkCreate();
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AudioManagerA2dpSinkCreate ret %x\n", ret);
+#endif
+ /* 起定时器接受音乐开始请求 */
+ (void)BtA2dpSnkStartAcceptTimer();
+ return 0;
+}
+
+static int32_t BtA2dpSnkAudioDestroy()
+{
+#if MEDIA_A2DP_SNK_INTERFACE
+ int32_t ret = AudioManagerA2dpSinkDestroy();
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "AudioManagerA2dpSinkDestroy ret %x\n", ret);
+#endif
+ return 0;
+}
+
+static void BtA2dpSnkConnectStateChangedCb(bd_addr_t *bd_addr, int conn_state)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x conn_state: %x\n",
+ bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0], conn_state); /* 3 2 1 0 idx */
+}
+
+static void BtA2dpSnkStartStreamReqCb(bd_addr_t *bd_addr)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x \n",
+ bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* 3 2 1 0 idx */
+ BtA2dpSnkAudioCreate();
+}
+
+static void BtA2dpSnkPlayingStateChangedCb(bd_addr_t *bd_addr, int playing_state)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x playing_state: %x\n",
+ bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0], playing_state); /* 3 2 1 0 idx */
+ if (playing_state == A2DP_NOT_PLAYING) {
+ BtA2dpSnkAudioDestroy();
+ }
+}
+
+static void BtA2dpSnkConfigChangedCb(bd_addr_t *bd_addr, a2dp_snk_codec_info_t *info)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "addr: ****%02x%02x%02x%02x ",
+ bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* 3 2 1 0 idx */
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,
+ "codec_priority: %04x codec_type: %04x sample_rate: %02x bits_per_sample: %02x channel_mode: %02x",
+ info->codec_priority, info->codec_type, info->sample_rate, info->bits_per_sample, info->channel_mode);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,
+ "codec_specific1: %04x codec_specific2: %04x codec_specific3: %04x codec_specific4: %04x\n",
+ (unsigned int)info->codec_specific1,
+ (unsigned int)info->codec_specific2,
+ (unsigned int)info->codec_specific3,
+ (unsigned int)info->codec_specific4);
+#if MEDIA_A2DP_SNK_INTERFACE
+ if (info->codec_type == A2DP_SNK_CODEC_TYPE_AAC) {
+ g_audio_format_config.audioFormat = AAC_LC;
+ } else {
+ g_audio_format_config.audioFormat = SBC;
+ }
+ /* channel count 1 or 2 */
+ g_audio_format_config.channelCount = (info->channel_mode == A2DP_SNK_CODEC_CHANNEL_MODE_NONE ? 1 : 2);
+
+ switch (info->sample_rate) {
+ case A2DP_SNK_CODEC_SAMPLE_RATE_48000:
+ g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE48000;
+ break;
+ case A2DP_SNK_CODEC_SAMPLE_RATE_88200:
+ g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE88200;
+ break;
+ case A2DP_SNK_CODEC_SAMPLE_RATE_96000:
+ g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE96000;
+ break;
+ default:
+ g_audio_format_config.sampleRate = BT_AUDIO_A2DP_SMAPLE_RATE44100;
+ break;
+ }
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "audioFormat %d channelCount %d sampleRate %d \n",
+ g_audio_format_config.audioFormat, g_audio_format_config.channelCount, g_audio_format_config.sampleRate);
+#endif
+}
+
+// 注册回调函数
+static gap_call_backs_t g_btGapCallBacks{};
+static a2dp_src_callbacks_t g_a2dpSrcCallbacks{};
+static gap_ble_callbacks_t g_gapBleCallbacks{};
+static gatts_callbacks_t g_btGattsCallbacks{};
+
+static a2dp_snk_callbacks_t g_a2dp_snk_callbacks = {
+ BtA2dpSnkConnectStateChangedCb,
+ BtA2dpSnkStartStreamReqCb,
+ BtA2dpSnkPlayingStateChangedCb,
+ BtA2dpSnkConfigChangedCb
+};
+
+static void BleConnectCallback(uint16_t conn_id, errcode_t status, const gap_ble_conn_param_update_t *param)
+{
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleConnectCallback conn_id:%u, interval-1:%u latency:%u timeout:%u\n",conn_id, param->interval, param->latency, param->timeout);
+}
+
+void BtInitCallBacks()
+{
+ g_btGapCallBacks.discovery_result_callback = BtGapDiscoveryResultCallback;
+ g_btGapCallBacks.discovery_state_changed_callback = BtGapDiscoveryStateChangedCallback;
+ g_btGapCallBacks.acl_state_changed_callbak = GapAclStateChangedCallback;
+ g_btGapCallBacks.read_remote_rssi_event_callback = BtGapReadRemoteRssiEventCallback;
+ g_btGapCallBacks.remote_name_changed_callback = BtRemoteNameChangedCallback;
+ g_btGapCallBacks.is_accept_conn_on_safe_mode_callback = BtIsAcceptConnOnSafeModeCallback;
+ g_btGapCallBacks.pair_status_changed_callback = BtGapPairStatusChangedCallback;
+ g_btGapCallBacks.pair_requested_callback = BtGapPairRequestedCallback;
+ g_btGapCallBacks.pair_confiremed_callback = BtGapPairConfirmedCallback;
+ g_btGapCallBacks.remote_battery_level_changed_callback = BtGapRemoteBatteryLevelChangedCallback;
+ gap_register_callbacks(&g_btGapCallBacks);
+
+}
+
+void BtA2dpInit(void)
+{
+ /* a2dp source */
+ g_a2dpSrcCallbacks.connectstate_changed_cb = A2dpSrcConnectstateChanged;
+ g_a2dpSrcCallbacks.configuration_changed_cb = A2dpSrcConfigureChanged;
+ g_a2dpSrcCallbacks.playing_state_changed_cb = A2dpSrcPlayingStateChanged;
+ a2dp_src_register_callbacks(&g_a2dpSrcCallbacks);
+ /* a2dp sink */
+ a2dp_snk_register_callbacks(&g_a2dp_snk_callbacks);
+}
+
+void BtInitCallBacksEx()
+{
+ g_gapBleCallbacks.conn_state_change_cb = BleConnStateChangeCallback;
+ g_gapBleCallbacks.start_adv_cb = BleAdvStartCallback;
+ g_gapBleCallbacks.stop_adv_cb = BleAdvStopCallback;
+ g_gapBleCallbacks.terminate_adv_cb = BleAdvTerminateCallback;
+ g_gapBleCallbacks.conn_param_update_cb = BleConnectCallback;
+ wrapper_gap_ble_register_callbacks(&g_gapBleCallbacks);
+
+ g_btGattsCallbacks.add_service_cb = BtGattsServiceAddCallback;
+ g_btGattsCallbacks.add_characteristic_cb = BtGattsCharacteristicAddCallback;
+ g_btGattsCallbacks.add_descriptor_cb = BtGattsDescriptorAddCallback;
+ g_btGattsCallbacks.start_service_cb = BtGattsServiceStartCallback;
+ g_btGattsCallbacks.stop_service_cb = BtGattsServiceStopCallback;
+ g_btGattsCallbacks.delete_service_cb = BtGattsServiceDeleteCallback;
+ g_btGattsCallbacks.read_request_cb = BtGattsRequestReadCallback;
+ g_btGattsCallbacks.write_request_cb = BtGattsRequestWriteCallback;
+ g_btGattsCallbacks.mtu_changed_cb = BtGattsMtuChangedCallback;
+ wrapper_gatts_register_callbacks(&g_btGattsCallbacks);
+}
+
+void BtInitGatts(void)
+{
+ uint16_t id = 0xF01F;
+ uint16_t ser_id = 0xFF1F;
+ uint8_t serverId = 0;
+ bt_uuid_t uuid;
+ int ret;
+
+ uuid.uuid_len = sizeof(ser_id);
+ memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&ser_id, sizeof(ser_id));
+ ret = wrapper_gatts_register_server(&uuid, &serverId); /* 注册gatt server */
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_register_server ret: 0x%x serverId = 0x%x", ret, serverId);
+
+ uuid.uuid_len = sizeof(id);
+ memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&id, sizeof(id));
+ ret = wrapper_gatts_add_service(serverId, &uuid, true);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "gatts_add_service ret: 0x%x", ret);
+
+ wrapper_gatts_service_start();
+}
+
+static uint8_t Char2Num(int8_t c)
+{
+ if (c >= '0' && c <= '9') {
+ return (uint8_t)(c - '0');
+ } else if (c >= 'A' && c <= 'F') {
+ return (uint8_t)(c - 'A' + TEN);
+ } else if (c >= 'a' && c <= 'f') {
+ return (uint8_t)(c - 'a' + TEN);
+ } else {
+ return 0xFF;
+ }
+}
+
+static uint32_t GenerateUuidFromString(const char *str, uint8_t len, bt_uuid_t *uuid_out)
+{
+ int slen = (int)strnlen(str, len);
+ bool new_uuid = false;
+ if (uuid_out == nullptr) {
+ return ERRCODE_INVALID_PARAM;
+ }
+
+ uuid_out->uuid_len = (uint8_t)slen / 2; /* 2: 2个字符组成一个字节,因此只取偶数个字符 */
+ for (int i = 0; i + 1 < slen; i += 2) { /* 2: 同上 */
+ uint8_t num1 = Char2Num(str[i]);
+ uint8_t num2 = Char2Num(str[i + 1]);
+ if (num1 == UINT8_MAX || num2 == UINT8_MAX) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "invalid input %c%c\n", str[i], str[i + 1]);
+ return ERRCODE_INVALID_PARAM;
+ }
+
+ uuid_out->uuid[i / 2] = (uint8_t)((num1 << BIT4) | num2); /* 2: 同上 */
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "%02x ", (uint8_t)(uuid_out->uuid[i / 2])); /* 2: 同上 */
+ }
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "\n");
+ return ERRCODE_SUCC;
+}
+
+void BtSppServerCreate(const char *spp_uuid, const char *name, uint8_t name_len)
+{
+ spp_create_socket_para_t param;
+ if (GenerateUuidFromString((const char *)spp_uuid, (uint8_t)strlen(spp_uuid), ¶m.uuid) != ERRCODE_SUCC) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "get uuid fail\n");
+ return;
+ }
+
+ param.socket_type = SPP_SOCKET_RFCOMM;
+ param.is_encrypt = true;
+
+ int ret = spp_server_create(¶m, name, name_len);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_create ret: %x\n", ret);
+}
+
+static int BtSppServerAcceptTaskBody(void *data)
+{
+ int server_id = (int)(intptr_t)data;
+ int ret = spp_server_accept(server_id);
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "spp_server_accept ret: %x, server_id: %d\r\n", ret, server_id);
+ return OSAL_SUCCESS;
+}
+
+/* 等待client连接 */
+void BtSppServerAccept(uint8_t server_id)
+{
+ osal_task *task = osal_kthread_create(BtSppServerAcceptTaskBody, (void *)(uintptr_t)server_id,
+ "spp_server_accept_task", BT_SPP_TASK_STACK_SIZE);
+ if (task == nullptr) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "create task fail\n");
+ return;
+ }
+
+ int ret = osal_kthread_set_priority(task, BT_SPP_TASK_PRI);
+ if (ret != OSAL_SUCCESS) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "set pri error: %08x\n", ret);
+ }
+}
+
+void BtInitSpp(void)
+{
+ char uuid[] = "1101";
+ char name[] = "COM1";
+ uint8_t name_len = strlen(name) + 1;
+ uint8_t server_id = 0;
+
+ /* 创建spp */
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "create spp server uuid=%s name=%s name_len=%d\n", uuid, name, name_len);
+ BtSppServerCreate(uuid, name, name_len);
+ BtSppServerAccept(server_id);
+}
+
+void BleAdvStart(void)
+{
+ int advId = g_sample_adv_id;
+ if (BluetoothModel::GetInstance()->GetAdvStartState()) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStart already started");
+ gap_ble_stop_adv(advId);
+ osDelay(50);
+ }
+ gap_ble_adv_params_t adv_para;
+ memset_s(&adv_para, sizeof(gap_ble_adv_params_t), 0, sizeof(gap_ble_adv_params_t));
+ adv_para.min_interval = 0x30;
+ adv_para.max_interval = 0x60;
+ adv_para.adv_type = GAP_BLE_ADV_CONN_SCAN_UNDIR;
+ adv_para.channel_map = 0x7;
+ adv_para.duration = 0;
+ gap_ble_set_adv_param(advId, &adv_para);
+ gap_ble_set_local_appearance(GAP_BLE_APPEARANCE_TYPE_GENERIC_WATCH);
+ errcode_t ret = gap_ble_start_adv(advId);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "BleAdvStart bt gap_ble_start_adv ret = 0x%x", ret);
+}
+
+#ifdef __cplusplus
+}
+#endif
+}