/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2021. All rights reserved. * * Description: ble_api.c * * Author: even * * Create: 2022-08-04 *--------------------------------------------------------------------------*/ #include "sys_config.h" #include #include // #include "ble_data_transmission.h" #include "alipay_feature.h" #include "at_cmd_api.h" #include "ate_rx_manager.h" #include "ble_api.h" #include "ble_bas_client.h" #include "ble_fmp_locator.h" #include "ble_gatts_callbacks.h" #include "ble_port.h" #include "ble_port_protocol.h" #include "ble_pro_dis_client.h" // #include "bts_a2dp_source.h" #include "bts_avrcp_controller.h" #include "bts_avrcp_target.h" #include "bts_hfp_hf.h" #include "bts_uuid.h" #include "cmsis_os2.h" #include "osal_addr.h" #include "service_bt.h" #include "soc_osal.h" #include "sql_bt.h" #include "ble_port_hid_service.h" #include "ble_port_hfp_service.h" #include "ble_protocol_file_upload.h" #include "ble_protocol_file_download.h" #include "ble_protocol_ota_service.h" #include "bts_le_gap.h" #include "bts_feature.h" #include "sql_bt.h" #include "systick.h" #include "service_bt.h" #include "ohos_bt_gatt_client.h" #include "tjd_ble_ancs_server.h" // #include "ble_port_ancs_service.h" // #include "bt_audio_manager_wrapper.h" #define BLE_AT_FAIL 1 #define BLE_AT_SUCC 0 #define MALLOC_FAIL -1 // #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define ENABLE_STATIC_PRINT 0 #define static_print_error(...) sys_bt_log_e(__VA_ARGS__) //错误信息打印一般常开 #define static_print_warn(...) sys_bt_log_w(__VA_ARGS__) //警告信息打印一般常开 #if ENABLE_STATIC_PRINT #define static_print_debug(...) sys_bt_log_d(__VA_ARGS__) #define static_print_info(...) sys_bt_log_i(__VA_ARGS__) #else #define static_print_debug(...) #define static_print_info(...) #endif #define UUID_SIZE 16 #define MEMORY_MINI 1 #define GENE_ADV_ID 1 #define INVALID_SERVER_ID 1 #define CENTRAL_DEMO_MTU 23 #define GATT_CHARACTERISTIC_MAX_LENGTH 517 #define GATT_RX_MAX_LENGTH 64 #define MUT_SIZE 517 // #define BLE_NAME_LEN 11 #define PROTOCOL_FRAME_HEAD 0xAB #define PROTOCOL_FRAME_HEAD_2 0xAC #define TIMEOUT_MS 10000 // 超时时间,单位毫秒 /* Gatt service UUID */ #define GATT_SERVICE_ID 0xD018 /* Gatt Characteristic UUID */ #define GATT_CHARACTERISTIC_ID 0x012D #define GATT_CHARACTERISTIC_READ_ID 0x002D #define GATT_AT_CHARACTERISTIC_ID 0x022D // #define GATT_AT_CHARACTERISTIC_READ_ID 0x002D /* Client Characteristic Configuration UUID */ #define GATT_BLE_UUID_CLIENT_CHARACTERISTIC_CONF 0x0229 /* Gatt Characteristic max length */ #define GATT_BLE_ADV_ID 1 #define GATT_BLE_ADV_DATA_MAX_LENGTH 31 #define GATT_BLE_ADV_BLE_NAME_MAX_LENGTH 12 // 31-4-2-3-9 = 13 #define GATT_BLE_NAME_LENGTH 20 #define GATT_BLE_ADV_MAC_HEAD_LENTH 4 #define GATT_BLE_ADV_MAC_LENTH 8 #define GATT_BLE_ADV_TYPE_LENTH 3 #define GATT_BLE_ADV_UUID_LENTH 4 #define GATT_BLE_DEFAULT_NAME "18THALefun" #define GATT_BLE_DEFAULT_NAME_LEN 9 #define GAP_BLE_LOWPWR_INTERVAL_MIN 50 #define GAP_BLE_LOWPWR_INTERVAL_MAX 50 #define GAP_BLE_LOWPWR_LATENCY 10 #define GAP_BLE_LOWPWR_OUTTIME 500 #define GAP_BLE_FAST_INTERVAL_MIN 12 #define GAP_BLE_FAST_INTERVAL_MAX 12 #define GAP_BLE_FAST_LATENCY 5 #define GAP_BLE_FAST_OUTTIME 400 #define CONNECT_PARAM_UPDATE_TIME 15000 // 连接参数更新时间,单位ms /* Gatt service UUID */ #define ALIPAYY_SERVICE_ID 0x0238 #define BLE_UUID_AT_CMD_SERVICE 0xD218 /* Gatt Characteristic UUID */ #define ALIPAYY_CHARACTERISTIC_ID 0x024A #define ALIPAY_CHARACTERISTIC_MAX_LENGTH 256 /* HID service UUID */ #define BLE_UUID_HUMAN_INTERFACE_DEVICE 0x1218 #define uint16_to_byte(n) ((uint8_t)(n)), ((uint8_t)((n) >> 8)) /* HID information flag remote wakeup */ #define BLE_HID_INFO_FLAG_REMOTE_WAKE_UP_MSK 0x01 /* HID information flag normally connectable */ #define BLE_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK 0x02 /* HID information country code */ #define BLE_HID_INFO_COUNTRY_CODE 0x00 /* HID spec version 1.11 */ #define BLE_HID_VERSION 0x0101 /* HID input report id */ #define BLE_HID_REPORT_ID 1 /* HID input report type */ #define BLE_REPORT_REFERENCE_REPORT_TYPE_INPUT_REPORT 1 /* HID output report type */ #define BLE_REPORT_REFERENCE_REPORT_TYPE_OUTPUT_REPORT 2 /* HID gatt server id */ #define BLE_HID_SERVER_ID 1 /* HID ble connect id */ #define BLE_SINGLE_LINK_CONNECT_ID 1 /* HID gatt attribute num */ #define BLE_HID_ATTRIBUTE_NUM 10 /* HID gatt notification flag, do not need confirm */ #define GATT_NOTIFICATION_FLAG 0 /* HID gatt indication flag, need confirm */ #define GATT_INDICATION_FLAG 1 /* Report UUID */ #define BLE_UUID_REPORT 0x4D2A /* HID character value handle offset */ #define BLE_HID_CHARACTER_INPUT_REPORT_VALUE_HANDLE_OFFSET 8 #define pdFALSE ((BaseType_t)0) #define pdTRUE ((BaseType_t)1) #define pdPASS (pdTRUE) #define pdFAIL (pdFALSE) static time_t last_received_time = 0; // extern unsigned long g_ate_at_queue; // GATT 蓝牙模块全局变量 // static gap_ble_callbacks_t gatt_gapble_cbs; // static gatts_callbacks_t gatt_gatts_cbs; /* gatt server ID */ uint8_t g_server_id = INVALID_SERVER_ID; uint16_t gatt_server_id = 1; uint16_t g_server_conn_id = 0; uint16_t g_server_handle = 0; uint16_t g_tjd_alipay_handle = 0; uint16_t g_tjd_lefun_handle = 0; uint16_t g_tjd_at_handle = 0; uint8_t g_tjd_hid_server_id = 0; uint16_t g_tjd_hid_srv_handle = 0; /* hid input report att handle */ uint32_t g_tjd_hid_input_report_att_hdl = 0; bd_addr_t g_tjd_lastconned_addr = {0}; uint16_t g_tjd_hid_service_handle = 0; uint32_t g_tjd_ble_mtu_size = 0; static uint8_t g_character_buf[GATT_CHARACTERISTIC_MAX_LENGTH] = {0}; static uint8_t g_character_read_buf[GATT_CHARACTERISTIC_MAX_LENGTH] = {0}; static uint8_t g_rx_buf[GATT_RX_MAX_LENGTH] = {0}; bd_addr_t g_conn_addr = {0}; osSemaphoreId_t g_tjd_upload_file_done_sem = NULL; // Alipay 蓝牙模块全局变量 static uint16_t g_alipay_server_id = 1; static uint16_t g_at_server_id = 1; static uint8_t g_alipay_character_buf[ALIPAY_CHARACTERISTIC_MAX_LENGTH] = {0}; // static uint16_t gatt_server_id = 1; static uint16_t gatt_server_handle = 0; static uint16_t gatt_conn_id = 0; static uint8_t gatt_character_buf[GATT_CHARACTERISTIC_MAX_LENGTH] = {0}; static bool gatt_ble_init_flag = false; static const uint8_t gatt_adv_type[GATT_BLE_ADV_TYPE_LENTH] = {2, 1, 0}; // static const uint8_t gatt_adv_type[GATT_BLE_ADV_TYPE_LENTH] = {0x0e, 0xff}; static const uint8_t gatt_adv_uuid[GATT_BLE_ADV_UUID_LENTH] = {0x3, 0x3, 0x02, 0x38}; static gap_connect_state_callback_t g_gap_connect_state_callback = NULL; uint16_t server_handle_protocol = 0; uint16_t server_handle_alipay = 0; uint16_t server_handle_at = 0; void add_gatt_server_protocol(uint16_t server_id, uint16_t *handle); void add_gatt_server_alipay(uint16_t server_id, uint16_t *handle); void add_gatt_server_at(uint16_t server_id, uint16_t *handle); int32_t clion_id = 0; bool bt_linkStatus = false; typedef struct { uint8_t service_id; uint8_t conn_id; uint16_t attr_handle; uint8_t *value; uint16_t value_len; } notify_params_t; bool g_tjd_bt_adv_statue = false; bool g_tjd_bt_is_connected = false; bool g_tjd_ble_is_connected = false; bool g_tjd_ble_into_camera_flag = false; typedef struct { uint32_t buffer_data_len; uint8_t buffer[4150]; struct timespec last_time; uint8_t protoclo_title; //包头信息 uint8_t packet_index; //分包号,用于拼包 } ble_cmd_info_t; ble_cmd_info_t g_cmd_info = {0}; void ble_api_cmd_info_reset(void) { memset(&g_cmd_info, 0, sizeof(g_cmd_info)); } errcode_t ble_api_cmd_enable(void) { errcode_t ret = enable_ble(); static_print_debug("ble_enable ret(errcode_t): %x mac: ", ret); if (ret == ERRCODE_BT_SUCCESS) { static_print_debug("enable success"); } return ret; } errcode_t ble_api_cmd_disable(void) { errcode_t ret = disable_ble(); static_print_debug("ble_disable ret(errcode_t): %x mac: ", ret); if (ret == ERRCODE_BT_SUCCESS) { static_print_debug("disable success"); } return ret; } errcode_t ble_api_cmd_set_local_name(uint8_t *name, int len) { errcode_t ret = gap_ble_set_local_name(name, len); static_print_debug("ble_set_local_name inputName: \"%s\" inputLen: %d ret(errcode_t): %x", name, len, ret); return ret; } errcode_t ble_api_cmd_get_local_name(void) { uint8_t name[20] = {0}; uint8_t len = 0; errcode_t ret = gap_ble_get_local_name(name, &len); static_print_debug("ble_get_local_name inputName: \"%s\" inputLen: %d ret(errcode_t): %x", name, len, ret); return ret; } errcode_t ble_api_cmd_set_local_addr(const bd_addr_t *addr) { errcode_t ret = gap_ble_set_local_addr(addr); static_print_debug("ble_set_local_addr inputName: \"%s\" ret(errcode_t): %x", addr, ret); return ret; } errcode_t ble_api_cmd_get_local_addr(void) { bd_addr_t addr = {0}; errcode_t ret = gap_ble_get_local_addr(&addr); static_print_debug("gap_ble_get_local_addr addr: %x : %x : %x : %x : %x : %x ret(errcode_t): %x", addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0], ret); return ret; } errcode_t ble_api_cmd_get_bt_local_addr(void) { unsigned char mac_addr[6] = {0}; errcode_t ret = bluetooth_get_local_addr(mac_addr,6); static_print_debug("bluetooth_get_local_addr addr: %x : %x : %x : %x : %x : %x ret(errcode_t): %x", mac_addr[5], mac_addr[4], mac_addr[3], mac_addr[2], mac_addr[1], mac_addr[0], ret); return ret; } errcode_t ble_api_cmd_set_adv_data(uint8_t adv_id, const gap_ble_config_adv_data_t *data) { errcode_t ret = gap_ble_set_adv_data(adv_id, data); static_print_debug("ble_set_adv_data ret(errcode_t): %x mac: ", ret); return ret; } errcode_t ble_api_cmd_start_adv(uint8_t adv_id) { errcode_t ret = gap_ble_start_adv(adv_id); static_print_debug("ble_start_adv ret(errcode_t): %x mac: ", ret); return ret; } void tjd_ble_upload_file(const char *file_name, uint8_t file_type) { tjd_ble_protocol_upload_file_description(file_name, file_type); static_print_debug("ble_upload_file file_name: %s", file_name); } void tjd_ble_request_gps(void) { uint8_t pack_head = 0x5B; tjd_ble_protocol_send_lefun_data(&pack_head,NULL,0,REQUEST_GPS_INFORMATION); static_print_debug("ble_request_gps"); } void tjd_ble_request_synchrodata(void) { uint8_t pack_head = 0x5B; tjd_ble_protocol_send_lefun_data(&pack_head,NULL,0,REQUEST_SYNCHRONOUS_DATA); static_print_debug("ble_request_synchrodata"); } void tjd_ble_request_flover(void) { uint8_t pack_head = 0x5B; tjd_ble_protocol_send_lefun_data(&pack_head,NULL,0,REQUEST_LUCKY_CLOVER_DATA); static_print_debug("ble_request_gps"); } bool ble_api_cmd_start_discovery(void) { // errcode_t re = gap_ble_stop_adv(GATT_BLE_ADV_ID); // static_print_debug("gap_ble_stop_adv ret(errcode_t): %x mac: ", re); if (is_bt_discovering(BT_TRANSPORT_BR_EDR)) { gap_br_cancel_discovery(); osDelay(50); } tjd_reset_found_dev_list(); (void)gap_br_set_inquiry_paramters(DEVICE_MAJOR_CLASS_AUDIO_VIDEO, 250); bool ret = gap_br_start_discovery(); static_print_debug("gap_br_start_discovery ret(errcode_t): %d mac: ", ret); return ret; } bool ble_api_cmd_stop_discovery(void) { if (is_bt_discovering(BT_TRANSPORT_BR_EDR)) { return gap_br_cancel_discovery(); } return false; } void tjd_ble_remove_all_pairs(void) { errcode_t ret = gap_ble_remove_all_pairs(); static_print_warn("gap_ble_remove_all_pairs ret(errcode_t): %d", ret); if(gap_remove_all_pairs()){ static_print_warn("gap_remove_all_pairs success"); }else{ static_print_warn("gap_remove_all_pairs failed"); } if(bluetooth_factory_reset()){ static_print_warn("bluetooth_factory_reset success"); }else { static_print_warn("bluetooth_factory_reset failed"); } } void tjd_set_lastconned_addr(const bd_addr_t *bd_addr) { int ret = memcpy_s(&g_tjd_lastconned_addr, sizeof(bd_addr_t), bd_addr, sizeof(bd_addr_t)); static_print_debug("tjd_set_lastconned_addr [] %d", ret); } void ble_api_cmd_show_scan_list(void) { tjd_update_found_dev_list(); tjd_show_found_dev_list(); } // /* set adv data. */ static void svr_gap_ble_adv_data_set(int adv_id) { uint8_t ble_name[GATT_BLE_NAME_LENGTH] = {0}; uint8_t ble_name_len = GATT_BLE_NAME_LENGTH; uint8_t adv_data[GATT_BLE_ADV_DATA_MAX_LENGTH] = {0}; uint8_t adv_data_len = 0; uint8_t ble_data_name[GATT_BLE_ADV_BLE_NAME_MAX_LENGTH + 1] = {0}; // +TYPE LENGTH uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; uint8_t adv_mac_head[GATT_BLE_ADV_MAC_LENTH] = {0x9, 0x16, 0x02, 0x38}; gap_ble_config_adv_data_t adv_data_info; memset_s(&adv_data_info, sizeof(gap_ble_config_adv_data_t), 0, sizeof(gap_ble_config_adv_data_t)); // int32_t ret = gap_ble_get_local_name(ble_name, &ble_name_len); errcode_t ret = bluetooth_get_local_name(ble_name, &ble_name_len); if (ret != 0 || ble_name_len == 0) { static_print_debug("gap_ble_get_local_name fail, name:%s,len:%u,ret:%u.", ble_name, ble_name_len, ret); memset_s(ble_name, GATT_BLE_NAME_LENGTH, 0, GATT_BLE_NAME_LENGTH); memcpy_s(ble_name, GATT_BLE_NAME_LENGTH, GATT_BLE_DEFAULT_NAME, GATT_BLE_DEFAULT_NAME_LEN); ble_name_len = GATT_BLE_DEFAULT_NAME_LEN + 1; } static_print_debug("gap_ble_get_local_name name:%s,len:%u,ret:%u.", ble_name, ble_name_len, ret); // bd_addr_t addr_info; unsigned char mac_addr[BT_MAC_LEN] = {0}; ret = bluetooth_get_local_addr(mac_addr,BT_MAC_LEN); // ret = gap_ble_get_local_addr(&addr_info); static_print_debug("gap_ble_get_local_addr, ret:%u.", ret); memcpy_s(adv_data, sizeof(gatt_adv_type), gatt_adv_type, sizeof(gatt_adv_type)); adv_data_len = sizeof(gatt_adv_type); if (ble_name_len > GATT_BLE_ADV_BLE_NAME_MAX_LENGTH) { ble_name_len = GATT_BLE_ADV_BLE_NAME_MAX_LENGTH; } ble_data_name[0] = ble_name_len; ble_data_name[1] = 0x9; memcpy_s(&ble_data_name[2], ble_name_len - 1, ble_name, ble_name_len - 1); memcpy_s(adv_data + adv_data_len, ble_name_len + 1, ble_data_name, ble_name_len + 1); adv_data_len = adv_data_len + ble_name_len + 1; // memcpy_s(adv_data + adv_data_len, sizeof(gatt_adv_uuid), gatt_adv_uuid, sizeof(gatt_adv_uuid)); // adv_data_len = adv_data_len + sizeof(gatt_adv_uuid); int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { // ble_data_mac_switch[--k] = addr_info.addr[i]; ble_data_mac_switch[--k] = mac_addr[i]; } static_print_debug("ble_info:%02x:%02x:%02x:%02x:%02x:%02x", ble_data_mac_switch[0], ble_data_mac_switch[1], ble_data_mac_switch[2], ble_data_mac_switch[3], ble_data_mac_switch[4], ble_data_mac_switch[5]); uint8_t adv_mac_head_1[GATT_BLE_ADV_MAC_LENTH] = {0x0e, 0xff}; memcpy_s(adv_mac_head_1 + 2, BD_ADDR_LEN, ble_data_mac_switch, BD_ADDR_LEN); // 1.包头(2字节) + MAC地址(6字节) memcpy_s(adv_data + adv_data_len, sizeof(adv_mac_head_1), adv_mac_head_1, sizeof(adv_mac_head_1)); adv_data_len = adv_data_len + sizeof(adv_mac_head_1); // 3. TJD厂商号(4个字节) eg. 0x544a444a // uint8_t tjd_uuid[4] = {0x54, 0x4a, 0x44, 0x4a}; uint8_t tjd_uuid[4] = {0x54, 0x48, 0x53, 0x41}; memcpy_s(adv_data + adv_data_len, sizeof(tjd_uuid), tjd_uuid, sizeof(tjd_uuid)); adv_data_len = adv_data_len + sizeof(tjd_uuid); // 4. 设备类型(1个字节) eg. 0x00 uint8_t dev_type = 0x01; adv_data[adv_data_len++] = dev_type; // 5. 项目ID(2个字节) eg. 0x3757 uint8_t project_id[2] = {0x37, 0x57}; memcpy_s(adv_data + adv_data_len, sizeof(project_id), project_id, sizeof(project_id)); adv_data_len = adv_data_len + sizeof(project_id); // // 6. 设备类型(4个字节) eg. 0x0319C103 // uint8_t dev_type_info[4] = {0x03, 0x19, 0xC1, 0x03}; // memcpy_s(adv_data + adv_data_len, sizeof(dev_type_info), dev_type_info, sizeof(dev_type_info)); // adv_data_len = adv_data_len + sizeof(dev_type_info); adv_data_info.adv_data = adv_data; adv_data_info.adv_length = adv_data_len; static_print_debug("adv_data_info.adv_length:%u.", adv_data_len); // for(int i = 0; i < adv_data_len; i++) { // static_print_debug("%02x ", adv_data_info.adv_data[i]); // } gap_ble_set_adv_data(adv_id, &adv_data_info); return; } static void sample_gap_ble_enable_changed_callback(errcode_t status) { static_print_debug("gap_ble_enable_changed_callback status: %d", status); } static void sample_gap_ble_disable_changed_callback(errcode_t status) { static_print_debug("gap_ble_disable_changed_callback status: %d", status); } static void sample_gap_set_adv_param_changed_callback(uint8_t adv_id, errcode_t status) { static_print_debug("gap_set_adv_param_changed_callback adv_id: %u status: \"%d\"", adv_id, status); } static void sample_gap_start_adv_changed_callback(uint8_t adv_id, adv_status_t status) { static_print_debug("gap_start_adv_changed_callback adv_id: %u status: \"%d\"", adv_id, status); if(adv_id == GATT_BLE_ADV_ID){ tjd_svr_gatt_set_adv_start_state(true); } } static void svr_bt_gatts_service_add_cb(uint8_t server_id, bt_uuid_t *uuid, uint16_t handle, errcode_t status) { static_print_debug("svr_bt_gatts_service_add_cb"); /* static_print_debug("BtGattsServiceAddCallback 0x%x 0x%x 0x%x 0x%x", status, server_id, handle, *((uint16_t *)uuid->uuid)); int ret; if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == GATT_SERVICE_ID)) { uint16_t id = GATT_CHARACTERISTIC_ID; 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(id); memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&id, sizeof(id)); character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP | GATT_CHARACTER_PROPERTY_BIT_WRITE; character.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; character.value = g_character_buf; ret = gatts_add_characteristic(server_id, handle, &character); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } static_print_debug("gatts_add_characteristic success, ret:%u.", ret); uint16_t read_id = GATT_CHARACTERISTIC_READ_ID; gatts_add_chara_info_t character_read; memset_s(&character_read, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); character_read.chara_uuid.uuid_len = sizeof(read_id); memcpy_s(character_read.chara_uuid.uuid, sizeof(character_read.chara_uuid.uuid), (char *)&read_id, sizeof(read_id)); character_read.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character_read.properties = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY; character_read.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; character_read.value = g_character_read_buf; ret = gatts_add_characteristic(server_id, handle, &character_read); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } static_print_debug("gatts_add_characteristic success, ret:%u.", ret); } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == ALIPAYY_SERVICE_ID)) { g_alipay_server_id = server_id; // 添加alipay characteristic uint16_t read_id = ALIPAYY_CHARACTERISTIC_ID; gatts_add_chara_info_t character; memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); character.chara_uuid.uuid_len = sizeof(read_id); memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&read_id, sizeof(read_id)); character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character.properties = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_WRITE | GATT_CHARACTER_PROPERTY_BIT_NOTIFY; character.value_len = ALIPAY_CHARACTERISTIC_MAX_LENGTH; character.value = g_alipay_character_buf; ret = gatts_add_characteristic(server_id, handle, &character); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } static_print_debug("gatts_add_characteristic success, ret:%u.", ret); } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == BLE_UUID_HUMAN_INTERFACE_DEVICE)) { g_tjd_hid_service_handle = handle; // tjd_ble_hid_add_characters_and_descriptors(server_id, handle); // gatts_start_service(server_id, handle); } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == BLE_UUID_AT_CMD_SERVICE)) { g_at_server_id = server_id; // 添加at characteristic uint16_t id = GATT_AT_CHARACTERISTIC_ID; 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(id); memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&id, sizeof(id)); character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP | GATT_CHARACTER_PROPERTY_BIT_WRITE; character.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; character.value = g_character_buf; ret = gatts_add_characteristic(server_id, handle, &character); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } static_print_debug("gatts_add_characteristic success, ret:%u.", ret); // uint16_t read_id = GATT_CHARACTERISTIC_READ_ID; // gatts_add_chara_info_t character_read; // memset_s(&character_read, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); // character_read.chara_uuid.uuid_len = sizeof(read_id); // memcpy_s(character_read.chara_uuid.uuid, sizeof(character_read.chara_uuid.uuid), (char *)&read_id, // sizeof(read_id)); // character_read.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; // character_read.properties = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY; // character_read.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; // character_read.value = g_character_read_buf; // ret = gatts_add_characteristic(server_id, handle, &character_read); // if (ret != ERRCODE_SUCC) { // static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); // } // static_print_debug("gatts_add_characteristic success, ret:%u.", ret); } */ } static void svr_gatt_bt_gatts_characteristic_add_cb(uint8_t server_id, bt_uuid_t *uuid, uint16_t srv_handle, gatts_add_character_result_t *result, errcode_t status) { static_print_debug("svr_gatt_bt_gatts_characteristic_add_cb"); /* static_print_debug("BtGattsCharacteristicAddCallback 0x%x 0x%x 0x%x 0x%x 0x%x , uuid: 0x%x uuid_len: %u", status, server_id, srv_handle, result->handle, result->value_handle, *((uint16_t *)uuid->uuid), uuid->uuid_len); if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == GATT_CHARACTERISTIC_ID)) { g_tjd_lefun_handle = result->value_handle; uint8_t bas_ccc_val[] = {0x01, 0x00}; bt_uuid_t ccc_uuid = {0}; bts_data_to_uuid_len2(0x2902, &ccc_uuid); gatts_add_desc_info_t descriptor; descriptor.desc_uuid = ccc_uuid; descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor.value_len = (uint16_t)sizeof(bas_ccc_val); descriptor.value = bas_ccc_val; int ret = 0; ret = gatts_add_descriptor(server_id, srv_handle, &descriptor); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor fail, ret:%u.", ret); } bd_addr_t addr_info; gatts_add_desc_info_t descriptor_ap; gap_ble_get_local_addr(&addr_info); bts_data_to_uuid_len2(0x4b02, &ccc_uuid); descriptor_ap.desc_uuid = ccc_uuid; descriptor_ap.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor_ap.value_len = BD_ADDR_LEN; uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { ble_data_mac_switch[--k] = addr_info.addr[i]; } descriptor_ap.value = ble_data_mac_switch; ret = gatts_add_descriptor(server_id, srv_handle, &descriptor_ap); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor second fail, ret:%u.", ret); } static_print_debug("gatts_add_descriptor success, ret:%u.", ret); ret = gatts_start_service(server_id, srv_handle); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_start_service fail, ret:%u.", ret); } static_print_debug("gatts_start_service success, ret:%u.", ret); } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == ALIPAYY_CHARACTERISTIC_ID)) { g_tjd_alipay_handle = result->value_handle; uint8_t bas_ccc_val[] = {0x01, 0x00}; bt_uuid_t ccc_uuid = {0}; bts_data_to_uuid_len2(0x2902, &ccc_uuid); gatts_add_desc_info_t descriptor; descriptor.desc_uuid = ccc_uuid; descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor.value_len = (uint16_t)sizeof(bas_ccc_val); descriptor.value = bas_ccc_val; int ret = 0; ret = gatts_add_descriptor(server_id, srv_handle, &descriptor); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor fail, ret:%u.", ret); } bd_addr_t addr_info; gatts_add_desc_info_t descriptor_ap; gap_ble_get_local_addr(&addr_info); bts_data_to_uuid_len2(0x4b02, &ccc_uuid); descriptor_ap.desc_uuid = ccc_uuid; descriptor_ap.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor_ap.value_len = BD_ADDR_LEN; uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { ble_data_mac_switch[--k] = addr_info.addr[i]; } descriptor_ap.value = ble_data_mac_switch; ret = gatts_add_descriptor(server_id, srv_handle, &descriptor_ap); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor second fail, ret:%u.", ret); } ret = gatts_start_service(server_id, srv_handle); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_start_service fail, ret:%u.", ret); } } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == GATT_CHARACTERISTIC_READ_ID)) { g_server_handle = result->value_handle; } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == BLE_UUID_REPORT)) { if ((srv_handle == 0) || (g_tjd_hid_service_handle != srv_handle)) { static_print_debug("[hid][ERROR]add report error, service_handle:%d", srv_handle); return; } g_tjd_hid_server_id = server_id; g_tjd_hid_srv_handle = srv_handle; static_print_debug("[hid][INFO]add report success, server_id : %d, service_handle:%d", g_tjd_hid_server_id ,g_tjd_hid_srv_handle); g_tjd_hid_input_report_att_hdl = srv_handle + BLE_HID_CHARACTER_INPUT_REPORT_VALUE_HANDLE_OFFSET; // gatts_start_service(server_id, srv_handle); } else if ((uuid->uuid_len == sizeof(uint16_t)) && (*((uint16_t *)uuid->uuid) == GATT_AT_CHARACTERISTIC_ID)) { g_tjd_at_handle = result->value_handle; // errcode_t ret1 = gatts_set_mtu_size(server_id,64); // static_print_debug("gatts_set_mtu_size ret:%d", ret1); uint8_t bas_ccc_val[] = {0x01, 0x00}; bt_uuid_t ccc_uuid = {0}; bts_data_to_uuid_len2(0x2902, &ccc_uuid); gatts_add_desc_info_t descriptor; descriptor.desc_uuid = ccc_uuid; descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor.value_len = (uint16_t)sizeof(bas_ccc_val); descriptor.value = bas_ccc_val; int ret = 0; ret = gatts_add_descriptor(server_id, srv_handle, &descriptor); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor fail, ret:%u.", ret); } bd_addr_t addr_info; gatts_add_desc_info_t descriptor_ap; gap_ble_get_local_addr(&addr_info); bts_data_to_uuid_len2(0x4b02, &ccc_uuid); descriptor_ap.desc_uuid = ccc_uuid; descriptor_ap.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor_ap.value_len = BD_ADDR_LEN; uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { ble_data_mac_switch[--k] = addr_info.addr[i]; } descriptor_ap.value = ble_data_mac_switch; ret = gatts_add_descriptor(server_id, srv_handle, &descriptor_ap); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor second fail, ret:%u.", ret); } static_print_debug("gatts_add_descriptor success, ret:%u.", ret); ret = gatts_start_service(server_id, srv_handle); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_start_service fail, ret:%u.", ret); } static_print_debug("gatts_start_service success, ret:%u.", ret); } */ } static void svr_bt_gatts_write_request_cb(uint8_t server_id, uint16_t conn_id, gatts_req_write_cb_t *write_cb_para, errcode_t status) { static_print_info(" svr_bt_gatts_write_request_cb(len:%d):\r\n",write_cb_para->length); #if 0 for(int i = 0 ; i < write_cb_para->length ; ){ static_print_info("%02x", write_cb_para->value[i]); i++; if(i % 10 == 0){ static_print_info("\r\n"); } if(i>=20){ break;} } static_print_info("\r\n"); #endif tjd_connect_param_update(); tjd_service_connect_param_send_star(); if (write_cb_para->handle == g_tjd_alipay_handle) { uint8_t *msg_data = write_cb_para->value; errcode_t ret = svr_alipay_msg_write(ALIPAY_MSG_BT, msg_data, write_cb_para->length, false); if (ret != ERRCODE_SUCC) { static_print_debug("svr_alipay_msg_write fail, ret:%u.", ret); } return; } if (write_cb_para->handle == g_tjd_at_handle && strncmp((char *)write_cb_para->value, "AT^", 3) == 0) { static_print_debug("get AT^ cmd"); tjd_ate_send_at_msg(write_cb_para->value, write_cb_para->length); return; } if(write_cb_para->handle == g_tjd_lefun_handle){ // time_t current_time = time(NULL); struct timespec time = {0}; clock_gettime(CLOCK_MONOTONIC, &time); if(g_cmd_info.packet_index == write_cb_para->value[0]){ memcpy(&g_cmd_info.buffer[g_cmd_info.buffer_data_len], &write_cb_para->value[1], write_cb_para->length - 1); g_cmd_info.buffer_data_len += write_cb_para->length - 1; g_cmd_info.packet_index++; }else if(write_cb_para->value[0] == PROTOCOL_FRAME_HEAD || write_cb_para->value[0] == PROTOCOL_FRAME_HEAD_2){ memcpy(&g_cmd_info.buffer[g_cmd_info.buffer_data_len], write_cb_para->value, write_cb_para->length); g_cmd_info.buffer_data_len += write_cb_para->length; }else if(strncmp((const char *)write_cb_para->value, "AT^",3) == 0){ memcpy(&g_cmd_info.buffer[g_cmd_info.buffer_data_len], write_cb_para->value, write_cb_para->length); g_cmd_info.buffer_data_len += write_cb_para->length; }else{ // 解析失败,重置状态并记录错误 static_print_warn("Resolution failed. Reset the status"); static_print_debug("write_cb_para->value: "); for(int i = 0; i < write_cb_para->length;) { static_print_info("%x ", write_cb_para->value[i]); i++; if(i % 10 == 0){ static_print_info("\n"); } if(i>=20) { break; } } static_print_info("\n"); g_cmd_info.packet_index = 0; g_cmd_info.buffer_data_len = 0; memset(g_cmd_info.buffer, 0, sizeof(g_cmd_info.buffer)); g_cmd_info.last_time = time; return; } if(g_cmd_info.buffer[0] == PROTOCOL_FRAME_HEAD && (g_cmd_info.buffer_data_len == g_cmd_info.buffer[1] || g_cmd_info.buffer[1] == 0x30)){ uint16_t length = g_cmd_info.buffer[1]; g_cmd_info.buffer_data_len = 0; g_cmd_info.protoclo_title = PROTOCOL_RES_FRAME_HEAD; tjd_ble_protocol_ctrlcmd_ab(server_id, conn_id, g_cmd_info.buffer , length); memset(g_cmd_info.buffer, 0, sizeof(g_cmd_info.buffer)); g_cmd_info.last_time = time; // 更新最后接收时间 return; }else if(g_cmd_info.buffer[0] == PROTOCOL_FRAME_HEAD_2 && g_cmd_info.buffer_data_len == (g_cmd_info.buffer[1] << 8 | g_cmd_info.buffer[2])){ uint16_t length = g_cmd_info.buffer[1] << 8 | g_cmd_info.buffer[2]; g_cmd_info.buffer_data_len = 0; g_cmd_info.protoclo_title = PROTOCOL_RES_FRAME_HEAD_2; tjd_ble_protocol_ctrlcmd_ac(server_id, conn_id, g_cmd_info.buffer , length); memset(g_cmd_info.buffer, 0, sizeof(g_cmd_info.buffer)); g_cmd_info.packet_index = 0; g_cmd_info.last_time = time; // 更新最后接收时间 return; }else if(strncmp((char *)g_cmd_info.buffer, "AT^", 3) == 0) { static_print_debug("get AT^ cmd"); tjd_ate_send_at_msg(g_cmd_info.buffer, g_cmd_info.buffer_data_len); memset(g_cmd_info.buffer, 0, sizeof(g_cmd_info.buffer)); g_cmd_info.buffer_data_len = 0; g_cmd_info.last_time = time; // 更新最后接收时间 return; } } } static void svr_bt_gatts_read_request_cb(uint8_t server_id, uint16_t conn_id, gatts_req_read_cb_t *cb_para, errcode_t status) { static_print_debug("[BLE]server read req server: %u status: %u conn_id:%hu handle: %hu ", server_id, status, conn_id, cb_para->handle); } static void svr_bt_gatts_service_start_cb(uint8_t server_id, uint16_t srv_handle, errcode_t status) { if(srv_handle == server_handle_protocol){ add_gatt_server_alipay(server_id, &server_handle_alipay); }else if(srv_handle == server_handle_alipay){ add_gatt_server_at(server_id, &server_handle_at); } static_print_debug("BtGattsServiceStartCallback 0x%x 0x%x 0x%x", status, server_id, srv_handle); } static void svr_bt_gatts_mtu_change_cbk(uint8_t server_id, uint16_t conn_id, uint32_t mtu_size, errcode_t status) { static_print_debug("BtGattsService mtu change server: %u status: %u conn_id: %hu mtu_size: %u ", server_id, status, conn_id, mtu_size); g_tjd_ble_mtu_size = mtu_size; static_print_debug("g_tjd_ble_mtu_size: %u ", g_tjd_ble_mtu_size); } static void ble_server_descriptor_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, uint16_t handle, errcode_t status) { static_print_debug("[BLE]server add descriptor server: %u status: %u srv_hdl: %hu desc_hdl: %hu " "uuid_len:%u, uuid: ", server_id, status, service_handle, handle, uuid->uuid_len); } static void ble_server_service_delete_cbk(uint8_t server_id, errcode_t status) { static_print_debug("[BLE]server delete service server: %u status: %u ", server_id, status); } static void ble_server_service_stop_cbk(uint8_t server_id, uint16_t handle, errcode_t status) { static_print_debug("[BLE]server stop service server: %u status: %u handle: %hu ", server_id, status, handle); } static void sample_gap_ble_conn_state_change_cbk(uint16_t conn_id, bd_addr_t *addr, gap_acl_state_t conn_state, gap_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) { errcode_t update_ret; if (addr == NULL) { static_print_debug("gap_ble_conn_state_change_cbk addr is null "); return; } static_print_debug("ConnectStateChanged conn_id:%u addr:0x%02x:%02x:%02x:%02x:%02x:%02x addr_type:%u" "conn_state:%d pair_state:%d", conn_id, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], addr->addr[4], addr->addr[5], addr->type, conn_state, pair_state); g_server_conn_id = conn_id; memcpy_s(g_conn_addr.addr, sizeof(g_conn_addr.addr), addr->addr, sizeof(addr->addr)); switch (conn_state) { case GAP_ACL_STATE_CONNECTED: if (g_gap_connect_state_callback != NULL) { g_gap_connect_state_callback(GAP_ACL_STATE_DISCONNECTED); } static_print_debug("ConnectStateChanged GAP_ACL_STATE_CONNECTED"); g_tjd_ble_is_connected = false; svr_gap_ble_adv_data_set(GATT_BLE_ADV_ID); osDelay(100); svr_ble_adv_start(); tjd_set_lastconned_addr(addr); tjd_service_ble_sync_data_close(); tjd_ota_breakpoint_callback(); tjd_service_connect_param_send_stop(); gap_ble_set_ctkd_enable(false); break; case GAP_ACL_STATE_DISCONNECTED: if (g_gap_connect_state_callback != NULL) { g_gap_connect_state_callback(GAP_ACL_STATE_CONNECTED); } static_print_debug("ConnectStateChanged GAP_ACL_STATE_DISCONNECTED"); g_tjd_ble_is_connected = true; tjd_service_ble_sync_data_open(); if(!g_tjd_bt_adv_statue){ gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE,180); } tjd_set_lastconned_addr(addr); gattc_exchange_mtu_req(clion_id,conn_id,MUT_SIZE); ble_ancs_client_setup_service(clion_id,conn_id); if(!bt_is_acl_connected(addr)){ errcode_t ret = gap_ble_connect_remote_device(addr); if(ret != ERRCODE_SUCC){ static_print_debug("gap_ble_connect_remote_device fail, ret:%u.", ret); }else{ // static_print_debug("gap_ble_connect_remote_device success, ret:%u.", ret); // ret = gattc_exchange_mtu_req(clion_id,conn_id,MUT_SIZE); // static_print_debug("gattc_exchange_mtu_req ret:%x", ret); // bt_uuid_t service_uuid = {0}; // service_uuid.uuid_len = BT_UUID_MAX_LEN; // /* ANCS服务UUID,小端序 */ // uint8_t ancs_uuid[BT_UUID_MAX_LEN] = { // 0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79}; // if (memcpy_s(service_uuid.uuid, BT_UUID_MAX_LEN, ancs_uuid, BT_UUID_MAX_LEN) != EOK) { // static_print_error("[btsrv][ERROR] uuid memcpy fail!\r\n"); // } // ret = gattc_discovery_service(clion_id,conn_id,&service_uuid); // static_print_debug("gattc_discovery_service ancs srv , ret:%x", ret); } } gap_conn_param_update_t conn_param = { 0 }; conn_param.conn_handle = conn_id; /* param 0: conn_handle */ conn_param.interval_min = GAP_BLE_LOWPWR_INTERVAL_MIN; /* param 1: interval_min */ conn_param.interval_max = GAP_BLE_LOWPWR_INTERVAL_MAX; /* param 2: interval_max */ conn_param.slave_latency = GAP_BLE_LOWPWR_LATENCY; /* param 3: slave_latency */ conn_param.timeout_multiplier = GAP_BLE_LOWPWR_OUTTIME; /* param 4: timeout_multiplier */ update_ret = gap_ble_connect_param_update(&conn_param); static_print_debug("gap ble update connection parameters ret: %u", update_ret); break; case GAP_ACL_STATE_LE_CONNECTED: static_print_debug("ConnectStateChanged GAP_ACL_STATE_LE_CONNECTED"); tjd_set_lastconned_addr(addr); g_tjd_ble_is_connected = true; gap_ble_stop_adv(GATT_BLE_ADV_ID); break; case GAP_ACL_STATE_LE_DISCONNECTED: static_print_debug("ConnectStateChanged GAP_ACL_STATE_LE_DISCONNECTED"); tjd_set_lastconned_addr(addr); g_tjd_ble_is_connected = false; svr_ble_adv_start(); break; } // errcode_t ret = gap_connect_remote_device(addr); // if(ret != ERRCODE_SUCC) { // static_print_debug("gap_connect_remote_device fail, ret:%x.", ret); // return; // } // if (conn_state == 1 || conn_state == 3) { /* 断连时,清理 client profile的远端列表 */ // static_print_debug("ConnectStateChanged disc_reason:%x", disc_reason); // sql_bt_set_bind(0); // static_print_debug("sql_bt_set_bind 0"); // svr_ble_adv_start(); // // gap_ble_stop_adv(GATT_BLE_ADV_ID); // // static_print_debug("gap_ble_stop_adv "); // // gap_ble_start_adv(GATT_BLE_ADV_ID); // // static_print_debug("gap_ble_start_adv "); // } else if (conn_state == 0 || conn_state == GAP_ACL_STATE_LE_CONNECTED) { /* 连接成功时,添加 client // profile的远端列表 */ // static_print_debug("ConnectStateChanged conn_state:%d pair_state:%d", conn_state, pair_state); // sql_bt_set_bind(1); // static_print_debug("sql_bt_set_bind 1"); // sql_bt_set_phone_name(addr->addr, sizeof(addr->addr)); // } } /* 设置安全参数 params: bondable io_capability sc_enable sc_mode */ static errcode_t gatt_ble_set_sec_param(uint8_t bondable, uint8_t io_capability, uint8_t sc_enable, uint8_t sc_mode) { gap_ble_sec_params_t sec_params = {0}; sec_params.bondable = bondable; sec_params.io_capability = io_capability; sec_params.sc_enable = sc_enable; sec_params.sc_mode = sc_mode; errcode_t ret = gap_ble_set_sec_param(&sec_params); static_print_debug("gap ble set sec param ret(errcode_t): %x", ret); return ret; } static void sample_gap_ble_set_adv_data_callback(uint8_t adv_id, errcode_t status) { static_print_debug("gap_ble_set_adv_data_callback adv_id: %d status: %d", adv_id, status); } // static void sample_gap_ble_scan_result_cbk(const gap_scan_result_data_t *scan_result_data) // { // if (scan_result_data == NULL) { // static_print_debug("gap_ble_scan_result_cbk scan_result_data is null "); // return; // } // static_print_debug("addr_type: %u addr:0x%02x:%02x:%02x:%02x:%02x:%02x.", scan_result_data->addr.type, // scan_result_data->addr.addr[0], scan_result_data->addr.addr[1], scan_result_data->addr.addr[2], // scan_result_data->addr.addr[3], scan_result_data->addr.addr[4], scan_result_data->addr.addr[5]); // } static void sample_gap_ble_connect_param_update_cbk(uint16_t conn_id, errcode_t status, const gap_ble_conn_param_update_t *param) { static_print_debug("connect param changed conn_id:%u status:%u", conn_id, status); if (param != NULL) { static_print_debug(" interval:%u latency:%u timeout:%u", param->interval, param->latency, param->timeout); } } static void sample_gap_ble_auth_complete_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status, const ble_auth_info_evt_t* evt) { static_print_debug("auth_complete_cbk conn_id:%u status:0x%x", conn_id, status); if (addr != NULL) { static_print_debug("addr:0x%02x:**:**:**:%02x:%02x addr_type:%u", addr->addr[0], addr->addr[4], addr->addr[5], addr->type); } if (evt != NULL) { static_print_debug("ltk_len:%u ltk:", evt->ltk_len); for (uint8_t i = 0; i < evt->ltk_len; i++) { static_print_info("%02x", evt->ltk[i]); } static_print_info("\r\n"); } } static void sample_gap_ble_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status) { static_print_debug("pair_result_cbk conn_id:%u status:0x%x", conn_id, status); if (addr != NULL) { static_print_debug("addr:0x%02x:**:**:**:%02x:%02x addr_type:%u", addr->addr[0], addr->addr[4], addr->addr[5], addr->type); } } static void sample_gap_ble_read_rssi_cb_cbk(uint16_t conn_id, int8_t rssi, errcode_t status) { static_print_debug("read_rssi_cb conn_id:%u status:0x%x rssi:%u", conn_id, status, rssi); } static void sample_gap_ble_scan_result_cbk(gap_scan_result_data_t *scan_result_data) { if (scan_result_data == NULL) { static_print_debug("scan_result_data is null"); return; } static_print_debug("event_type:%u addr_type: %u addr:0x%02x:**:**:**:%02x:%02x adv_len:%u.", scan_result_data->event_type, scan_result_data->addr.type, scan_result_data->addr.addr[0], scan_result_data->addr.addr[4], scan_result_data->addr.addr[5], scan_result_data->adv_len); } static void sample_gap_ble_set_scan_param_cbk(errcode_t status) { static_print_debug("SetScanParameterCallback status: %u", status); } static void sample_gap_ble_stop_adv_cbk(uint8_t adv_id, adv_status_t status) { static_print_debug("stop_adv_cbk adv_id: %u status: %d", adv_id, status); if(adv_id == GATT_BLE_ADV_ID){ tjd_svr_gatt_set_adv_start_state(false); } } static void sample_gap_ble_terminate_adv_cbk(uint8_t adv_id, adv_status_t status) { static_print_debug("terminate_adv_cbk adv_id: %u status: %d", adv_id, status); if(adv_id == GATT_BLE_ADV_ID){ tjd_svr_gatt_set_adv_start_state(false); } } void tjd_add_descriptor_protocol(uint16_t sever_id, uint16_t sever_handle) { uint8_t bas_ccc_val[] = {0x01, 0x00}; bt_uuid_t ccc_uuid = {0}; bts_data_to_uuid_len2(0x2902, &ccc_uuid); gatts_add_desc_info_t descriptor; descriptor.desc_uuid = ccc_uuid; descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor.value_len = (uint16_t)sizeof(bas_ccc_val); descriptor.value = bas_ccc_val; int ret = 0; uint16_t handle = 0; ret = gatts_add_descriptor_sync(sever_id, sever_handle, &descriptor, &handle); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor fail, ret:%u.", ret); } bd_addr_t addr_info; gatts_add_desc_info_t descriptor_ap; gap_ble_get_local_addr(&addr_info); bts_data_to_uuid_len2(0x4b02, &ccc_uuid); descriptor_ap.desc_uuid = ccc_uuid; descriptor_ap.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor_ap.value_len = BD_ADDR_LEN; uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { ble_data_mac_switch[--k] = addr_info.addr[i]; } descriptor_ap.value = ble_data_mac_switch; uint16_t handle_ap = 0; ret = gatts_add_descriptor_sync(sever_id, sever_handle, &descriptor_ap, &handle_ap); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor second fail, ret:%u.", ret); } } void tjd_add_characters_descriptor_protocol(uint16_t sever_id, uint16_t sever_handle) { errcode_t ret; uint16_t id = GATT_CHARACTERISTIC_ID; gatts_add_chara_info_t character; uint16_t value = 0; gatts_add_character_result_t result = {0}; memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); character.chara_uuid.uuid_len = sizeof(id); memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&id, sizeof(id)); character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP | GATT_CHARACTER_PROPERTY_BIT_WRITE; character.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; character.value = g_character_buf; ret = gatts_add_characteristic_sync(sever_id, sever_handle, &character, &result); //注册特征 if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } g_tjd_lefun_handle = result.value_handle; // tjd_add_descriptor_protocol(sever_id, sever_handle); //注册描述符 uint16_t read_id = GATT_CHARACTERISTIC_READ_ID; gatts_add_chara_info_t character_read; gatts_add_character_result_t result_read = {0}; memset_s(&character_read, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); character_read.chara_uuid.uuid_len = sizeof(read_id); memcpy_s(character_read.chara_uuid.uuid, sizeof(character_read.chara_uuid.uuid), (char *)&read_id, sizeof(read_id)); character_read.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character_read.properties = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY; character_read.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; character_read.value = g_character_read_buf; ret = gatts_add_characteristic_sync(sever_id, sever_handle, &character_read, &result_read); //注册特征 if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } g_server_handle = result_read.value_handle; tjd_add_descriptor_protocol(sever_id, sever_handle); //注册描述符 } void tjd_add_descriptor_alipay(uint16_t sever_id, uint16_t sever_handle) { uint8_t bas_ccc_val[] = {0x01, 0x00}; bt_uuid_t ccc_uuid = {0}; bts_data_to_uuid_len2(0x2902, &ccc_uuid); gatts_add_desc_info_t descriptor; descriptor.desc_uuid = ccc_uuid; descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor.value_len = (uint16_t)sizeof(bas_ccc_val); descriptor.value = bas_ccc_val; int ret = 0; uint16_t handle = 0; ret = gatts_add_descriptor_sync(sever_id, sever_handle, &descriptor, &handle); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor fail, ret:%u.", ret); } bd_addr_t addr_info; gatts_add_desc_info_t descriptor_ap; gap_ble_get_local_addr(&addr_info); bts_data_to_uuid_len2(0x4b02, &ccc_uuid); descriptor_ap.desc_uuid = ccc_uuid; descriptor_ap.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor_ap.value_len = BD_ADDR_LEN; uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { ble_data_mac_switch[--k] = addr_info.addr[i]; } descriptor_ap.value = ble_data_mac_switch; uint16_t handle_ap = 0; ret = gatts_add_descriptor_sync(sever_id, sever_handle, &descriptor_ap, &handle_ap); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor second fail, ret:%u.", ret); } } void tjd_add_characters_descriptor_alipay(uint16_t sever_id, uint16_t sever_handle) { int ret = 0; gatts_add_character_result_t result = {0}; g_alipay_server_id = sever_id; // 添加alipay characteristic uint16_t read_id = ALIPAYY_CHARACTERISTIC_ID; gatts_add_chara_info_t character; memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); character.chara_uuid.uuid_len = sizeof(read_id); memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&read_id, sizeof(read_id)); character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character.properties = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_WRITE | GATT_CHARACTER_PROPERTY_BIT_NOTIFY; character.value_len = ALIPAY_CHARACTERISTIC_MAX_LENGTH; character.value = g_alipay_character_buf; ret = gatts_add_characteristic_sync(sever_id, sever_handle, &character, &result); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } g_tjd_alipay_handle = result.value_handle; tjd_add_descriptor_alipay(sever_id, sever_handle); } void tjd_add_descriptor_at(uint16_t sever_id, uint16_t sever_handle) { // errcode_t ret1 = gatts_set_mtu_size(server_id,64); // static_print_debug("gatts_set_mtu_size ret:%d", ret1); uint8_t bas_ccc_val[] = {0x01, 0x00}; bt_uuid_t ccc_uuid = {0}; bts_data_to_uuid_len2(0x2902, &ccc_uuid); gatts_add_desc_info_t descriptor; descriptor.desc_uuid = ccc_uuid; descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor.value_len = (uint16_t)sizeof(bas_ccc_val); descriptor.value = bas_ccc_val; int ret = 0; uint16_t handle = 0; ret = gatts_add_descriptor_sync(sever_id, sever_handle, &descriptor, &handle); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor fail, ret:%u.", ret); } bd_addr_t addr_info; gatts_add_desc_info_t descriptor_ap; gap_ble_get_local_addr(&addr_info); bts_data_to_uuid_len2(0x4b02, &ccc_uuid); descriptor_ap.desc_uuid = ccc_uuid; descriptor_ap.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; descriptor_ap.value_len = BD_ADDR_LEN; uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; int k = BD_ADDR_LEN; for (int i = 0; i < BD_ADDR_LEN; i++) { ble_data_mac_switch[--k] = addr_info.addr[i]; } descriptor_ap.value = ble_data_mac_switch; uint16_t handle_ap = 0; ret = gatts_add_descriptor_sync(sever_id, sever_handle, &descriptor_ap, &handle_ap); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_descriptor second fail, ret:%u.", ret); } } void tjd_add_characters_descriptor_at(uint16_t sever_id, uint16_t sever_handle) { g_at_server_id = sever_id; // 添加at characteristic uint16_t id = GATT_AT_CHARACTERISTIC_ID; gatts_add_chara_info_t character; uint16_t value = 0; gatts_add_character_result_t result = {0}; int ret = 0; memset_s(&character, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); character.chara_uuid.uuid_len = sizeof(id); memcpy_s(character.chara_uuid.uuid, sizeof(character.chara_uuid.uuid), (char *)&id, sizeof(id)); character.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; character.properties = GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP | GATT_CHARACTER_PROPERTY_BIT_WRITE; character.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; character.value = g_character_buf; ret = gatts_add_characteristic_sync(sever_id, sever_handle, &character, &result); if (ret != ERRCODE_SUCC) { static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); } // uint16_t read_id = GATT_CHARACTERISTIC_READ_ID; // gatts_add_chara_info_t character_read; // memset_s(&character_read, sizeof(gatts_add_chara_info_t), 0, sizeof(gatts_add_chara_info_t)); // character_read.chara_uuid.uuid_len = sizeof(read_id); // memcpy_s(character_read.chara_uuid.uuid, sizeof(character_read.chara_uuid.uuid), (char *)&read_id, // sizeof(read_id)); // character_read.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; // character_read.properties = GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY; // character_read.value_len = GATT_CHARACTERISTIC_MAX_LENGTH; // character_read.value = g_character_read_buf; // ret = gatts_add_characteristic(server_id, handle, &character_read); // if (ret != ERRCODE_SUCC) { // static_print_debug("gatts_add_characteristic fail, ret:%u.", ret); // } // static_print_debug("gatts_add_characteristic success, ret:%u.", ret); g_tjd_at_handle = result.value_handle; tjd_add_descriptor_at(sever_id, sever_handle); } void add_gatt_server_protocol(uint16_t server_id, uint16_t *handle) { //注册协议GATT服务 errcode_t ret = 0; bt_uuid_t uuid; uint16_t service_id = GATT_SERVICE_ID; gatt_server_id = server_id; memset(&uuid, 0, sizeof(bt_uuid_t)); uuid.uuid_len = sizeof(service_id); memcpy(uuid.uuid, &service_id, sizeof(service_id)); ret = gatts_add_service_sync(server_id, &uuid, true, handle); if (ret != ERRCODE_SUCC) { static_print_error("gatts_add_app_service ret:%u.", ret); } tjd_add_characters_descriptor_protocol(server_id, *handle); //特征+描述 gatts_start_service(server_id, *handle); } void add_gatt_server_alipay(uint16_t server_id, uint16_t *handle) { // 注册支付宝GATT服务 errcode_t ret = 0; bt_uuid_t uuid; uint16_t service_id = ALIPAYY_SERVICE_ID; memset(&uuid, 0, sizeof(bt_uuid_t)); // g_alipay_server_id = server_id; uuid.uuid_len = sizeof(service_id); memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&service_id, sizeof(service_id)); ret = gatts_add_service_sync(server_id, &uuid, true, handle); if (ret != ERRCODE_SUCC) { static_print_error("gatts_add_alipay_service ret:%u.", ret); } tjd_add_characters_descriptor_alipay(server_id, *handle); //特征+描述 gatts_start_service(server_id, *handle); } void add_gatt_server_at(uint16_t server_id, uint16_t *handle) { //注册接收AT指令的服务 errcode_t ret = 0; bt_uuid_t uuid; uint16_t service_id = BLE_UUID_AT_CMD_SERVICE; memset(&uuid, 0, sizeof(bt_uuid_t)); // g_alipay_server_id = server_id; uuid.uuid_len = sizeof(service_id); memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&service_id, sizeof(service_id)); ret = gatts_add_service_sync(server_id, &uuid, true, handle); if (ret != ERRCODE_SUCC) { static_print_error("gatts_add_alipay_service ret:%u.", ret); } tjd_add_characters_descriptor_at(server_id, *handle); //特征+描述 gatts_start_service(server_id, *handle); } /* @brief GAP 打开双模蓝牙BT开关。 * @param void * @return 执行结果错误码 */ errcode_t tjd_ble_api_cmd_open(void) { // 设置自动回连,ios一键双连依赖此配置 bts_feature_t bts_feature = { 0 }; bts_feature.bt_auto_reconnect_closed = 0; errcode_t ret = bts_set_features(&bts_feature); // 初始化bt链路 // BT使能 ret = enable_bt_stack(); static_print_debug("enable_bt ret(errcode_t): %x", ret); if (ret != BLE_AT_SUCC) return ret; register_gap_service_callback(); tjd_ble_protocol_file_download_callback_init(); tjd_ble_protocol_file_download_transfer_reset(); tjd_ble_protocol_file_upload_callback_init(); gap_ble_callbacks_t ble_cb = { .set_adv_data_cb = sample_gap_ble_set_adv_data_callback, .ble_enable_cb = sample_gap_ble_enable_changed_callback, .set_adv_param_cb = sample_gap_set_adv_param_changed_callback, .start_adv_cb = sample_gap_start_adv_changed_callback, .conn_state_change_cb = sample_gap_ble_conn_state_change_cbk, .conn_param_update_cb = sample_gap_ble_connect_param_update_cbk, .auth_complete_cb = sample_gap_ble_auth_complete_cbk, .ble_disable_cb = sample_gap_ble_disable_changed_callback, .pair_result_cb = sample_gap_ble_pair_result_cbk, .read_rssi_cb = sample_gap_ble_read_rssi_cb_cbk, .scan_result_cb = sample_gap_ble_scan_result_cbk, .set_scan_param_cb = sample_gap_ble_set_scan_param_cbk, .stop_adv_cb = sample_gap_ble_stop_adv_cbk, .terminate_adv_cb = sample_gap_ble_terminate_adv_cbk, }; gatts_callbacks_t gatt_cb = { .add_service_cb = svr_bt_gatts_service_add_cb, .add_characteristic_cb = svr_gatt_bt_gatts_characteristic_add_cb, .start_service_cb = svr_bt_gatts_service_start_cb, .write_request_cb = svr_bt_gatts_write_request_cb, .read_request_cb = svr_bt_gatts_read_request_cb, .mtu_changed_cb = svr_bt_gatts_mtu_change_cbk, .add_descriptor_cb = ble_server_descriptor_add_cbk, .delete_service_cb = ble_server_service_delete_cbk, .stop_service_cb = ble_server_service_stop_cbk, }; int callbacks_ret = gap_ble_register_callbacks(&ble_cb); static_print_debug("gap ble reg cbk ret %x", callbacks_ret); callbacks_ret = gatts_register_callbacks(&gatt_cb); static_print_debug("gatts reg cbk ret %x", callbacks_ret); // register_hfp_hf_servers_callback(); // register_a2dpsrc_servers_callbacks(); // register_a2dpsnk_servers_callback(); // register_avrcp_ct_servers_callbacks(); // register_avrcp_tg_servers_callbacks(); register_bt_avrcp_tg_bts_callback(); register_hfp_hf_servers_callbacks(); ble_client_register_gatt_callbacks(); tjd_ble_ancs_client_register_cbk(); tjd_music_mutex_init(); tjd_ble_mutex_init(); //设置手表名称 uint8_t *local_name = (uint8_t *)malloc(sizeof(TJD_PCB_NAME) + sizeof(TJD_BLE_NAME_PREFIX) + 1); if (local_name == NULL) { static_print_debug("malloc local_name faile"); return MALLOC_FAIL; } memset_s(local_name, sizeof(local_name), 0, sizeof(local_name)); sprintf((char *)local_name, "%s%s-T", TJD_PCB_NAME, TJD_BLE_NAME_PREFIX); static_print_debug("local name : %s", local_name); ret = bluetooth_set_local_name((const unsigned char *)local_name, strlen((const char *)local_name) + 1); static_print_debug("bt_set_local_name ret(errcode_t): %x mac: ", ret); // if (ret != BLE_AT_SUCC) // return ret; //获取手表名称 // uint8_t get_local_name[14] = {0}; // uint8_t length = sizeof(TJD_PCB_NAME) + sizeof(TJD_BLE_NAME_PREFIX); // ret = bluetooth_get_local_name(get_local_name, &length); // static_print_debug("bt_get_local_name ret(errcode_t): %x mac: local name : %s , length : %d", ret, get_local_name, // length); // if (ret != BLE_AT_SUCC) // return ret; bd_addr_t addr = {0}; uint8_t mac_addr[MAC_ADDR_LEN] = {0}; if (tjd_service_nv_read_mac_addr(mac_addr) == ERRCODE_SUCC) { static_print_info("The MAC address is: "); for (int i = 0; i < 6; i++) { static_print_info("%02x", mac_addr[i]); if (i < 5) { static_print_info(":"); } } static_print_info("\n"); memcpy_s(addr.addr, sizeof(addr.addr), mac_addr, sizeof(addr.addr)); static_print_debug("addr.addr: %x:%x:%x:%x:%x:%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]); }else{ uint8_t *mac_addr = sql_bt_get_mac_addr(); memcpy_s(addr.addr, sizeof(addr.addr), mac_addr, sizeof(addr.addr)); static_print_debug("addr.addr: %x:%x:%x:%x:%x:%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]); } // uint8_t ble_data_mac_switch[BD_ADDR_LEN] = {0}; // int k = BD_ADDR_LEN; // for (int i = 0; i < BD_ADDR_LEN; i++) { // ble_data_mac_switch[--k] = addr.addr[i]; // } // errcode_t res = bluetooth_set_local_addr(addr.addr, sizeof(addr.addr)); // errcode_t res = bluetooth_set_local_addr(ble_data_mac_switch, sizeof(ble_data_mac_switch)); errcode_t res = bluetooth_set_local_addr(addr.addr, BD_ADDR_LEN); if (res != BLE_AT_SUCC) { static_print_error("bluetooth_set_local_addr fail"); return ERRCODE_FAIL; }else{ static_print_debug("bluetooth_set_local_addr succ"); uint8_t mac_addr[6] = {0}; res = bluetooth_get_local_addr(mac_addr, sizeof(mac_addr)); static_print_debug("br mac_addr: %x:%x:%x:%x:%x:%x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); if (res != BLE_AT_SUCC) { static_print_error("bluetooth_get_local_addr fail"); return ERRCODE_FAIL; }else{ static_print_debug("bluetooth_get_local_addr succ"); } } // res = gap_ble_set_local_addr(&addr); // if (res == BLE_AT_SUCC) { // static_print_debug("bluetooth_set_local_addr OK"); // bd_addr_t addr = {0}; // res = gap_ble_get_local_addr(&addr); // static_print_debug("ble mac: %x:%x:%x:%x:%x:%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]); // if (res != BLE_AT_SUCC) // return res; // } else { // static_print_error("bluetooth_set_local_addr fail"); // return ERRCODE_FAIL; // } //设置ble名称 // memset_s(local_name, sizeof(local_name), 0, sizeof(local_name)); char ble_name[BLE_NAME_LEN] = {0}; sql_bt_get_ble_name(ble_name); static_print_debug("strlen(ble_name) : %d",strlen(ble_name)); if(strlen(ble_name) != 0){ ret = bluetooth_set_local_name((const uint8_t *)ble_name, strlen(ble_name) + 1); static_print_debug("bluetooth_set_local_name ret(errcode_t): %x , ble_name : %s", ret, ble_name); // ret = gap_ble_set_local_name((const uint8_t *)ble_name, strlen(ble_name) + 1); // static_print_debug("gap_ble_set_local_name ret(errcode_t): %x , ble_name : %s", ret, ble_name); }else{ ret = bluetooth_set_local_name((const uint8_t *)"TH18ALefun", strlen(ble_name) + 1); static_print_debug("bluetooth_set_local_name ret(errcode_t): %x , ble_name : %s", ret, ble_name); // ret = gap_ble_set_local_name((const uint8_t *)"TH18ALefun", strlen(ble_name) + 1); // static_print_debug("gap_ble_set_local_name ret(errcode_t): %x , ble_name : %s", ret, ble_name); } // sql_bt_get_ble_name(ble_name); // sprintf((char *)local_name, "%s%s", TJD_PCB_NAME, TJD_BLE_NAME_PREFIX); // // ret = gap_ble_set_local_name(local_name, strlen((const char *)local_name) + 1); // free(local_name); // local_name = NULL; // if (ret != BLE_AT_SUCC) // return ret; // 2.3 设置设备的可发现模式 bool set_scan_mode = gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 1000); if (set_scan_mode == false) { static_print_debug("ble_gap_br_set_bt_scan_mode faile"); return ret; } // 2.4 创建GATT服务 uint16_t service_id = GATT_SERVICE_ID; uint8_t server_id = INVALID_SERVER_ID; bt_uuid_t uuid; uuid.uuid_len = sizeof(service_id); memcpy(uuid.uuid, &service_id, sizeof(service_id)); ret = gatts_register_server(&uuid, &server_id); /* 注册gatt server */ static_print_debug("ble_gatts_register_server ret(errcode_t): %x mac: ", ret); if (ret != BLE_AT_SUCC) return ret; //注册协议GATT服务 add_gatt_server_protocol(server_id, &server_handle_protocol); //注册HID服务 // service_id = BLE_UUID_HUMAN_INTERFACE_DEVICE; // memset(&uuid, 0, sizeof(bt_uuid_t)); // // g_alipay_server_id = server_id; // uuid.uuid_len = sizeof(service_id); // memcpy_s(uuid.uuid, sizeof(uuid.uuid), (char *)&service_id, sizeof(service_id)); // ret = gatts_add_service(server_id, &uuid, true); // if (ret != ERRCODE_SUCC) { // static_print_error("gatts_add_hid_service ret:%u.", ret); // } //注册客户端 uint16_t client_id = 0xD020; BtUuid appUuid; appUuid.uuidLen = sizeof(client_id); appUuid.uuid = (char *)malloc(appUuid.uuidLen); memcpy(appUuid.uuid, &client_id, sizeof(client_id)); clion_id = BleGattcRegister(appUuid); static_print_debug("clion_id = %d ",clion_id); free(appUuid.uuid); //SPP初始化 // ble_spp_servers_init(); int adv_id = GATT_BLE_ADV_ID; 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 = 0x640; adv_para.max_interval = 0x960; adv_para.adv_type = GAP_BLE_ADV_CONN_SCAN_UNDIR; adv_para.channel_map = 0x7; adv_para.duration = 0; adv_para.tx_power = 0; gap_ble_set_adv_param(adv_id, &adv_para); // 3.1 设置广播数据 svr_gap_ble_adv_data_set(adv_id); // smp加密 gatt_ble_set_sec_param(1, GAP_BLE_IO_CAPABILITY_NOINPUTNOOUTPUT, 1, GAP_BLE_GAP_SECURITY_MODE1_LEVEL3); // ret = gap_ble_set_ctkd_enable(false); // static_print_debug("gap_ble_set_ctkd_enable ret = %u", ret); // 3.2 打开广播 svr_ble_adv_start(); return ret; } /* @brief GAP 关闭单模蓝牙BLE开关。 * @param void * @return 执行结果错误码 */ errcode_t ble_api_cmd_close(void) { // 1.去使能蓝牙协议栈 tjd_music_mutex_deinit(); tjd_ble_mutex_deinit(); errcode_t ret = disable_bt_stack(); if (ret != ERRCODE_BT_SUCCESS) { static_print_debug("disable ble faile"); return BLE_AT_FAIL; } static_print_debug("diable ble success"); return ret; } /* @brief GATT 向对端发送通知或指示。 * @param uint8_t *data, 数据 uint16_t data_len 数据长度 * @return 执行结果错误码 */ errcode_t svr_bt_gatts_notify(uint8_t *data, uint16_t data_len) { gatts_ntf_ind_t data_info; data_info.attr_handle = g_server_handle; data_info.value = data; data_info.value_len = data_len; errcode_t ret = gatts_notify_indicate(g_server_id, gatt_conn_id, &data_info); static_print_debug("gatts_notify_indicate ret:0x%x. serverid:%u,conn_id:%u,handle:%u.", ret, g_server_id, gatt_conn_id, g_server_handle); return ret; } void tjd_bt_set_mac_addr(void) { bd_addr_t addr = {0}; uint8_t mac_addr[MAC_ADDR_LEN] = {0}; if (tjd_service_nv_read_mac_addr(mac_addr) == ERRCODE_SUCC) { static_print_info("The MAC address is: "); for (int i = 0; i < 6; i++) { static_print_info("%02x", mac_addr[i]); if (i < 5) { static_print_info(":"); } } static_print_info("\n"); memcpy_s(addr.addr, sizeof(addr.addr), mac_addr, sizeof(addr.addr)); static_print_debug("addr.addr: %x:%x:%x:%x:%x:%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]); }else{ uint8_t soc_id[20]; // 20 is soc id length uapi_soc_read_id(soc_id, 20); // 20 is soc id length // bd_addr_t addr = {.type = 0, .addr = {soc_id[5], soc_id[4], soc_id[7], soc_id[6], soc_id[11], soc_id[10]}}; addr.addr[0] = soc_id[5]; addr.addr[1] = soc_id[4]; addr.addr[2] = soc_id[7]; addr.addr[3] = soc_id[6]; addr.addr[4] = soc_id[11]; addr.addr[5] = soc_id[10]; static_print_debug("addr.addr: %x:%x:%x:%x:%x:%x", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]); } sql_bt_set_mac_addr(addr.addr, sizeof(addr.addr)); } bool tjd_get_bt_statue(void) { if(!g_tjd_bt_is_connected && !g_tjd_bt_adv_statue){ return false; } return true; } bool tjd_get_bt_adv_statue(void) { return g_tjd_bt_adv_statue; } bool tjd_get_bt_is_connect(void) { return g_tjd_bt_is_connected; } bool tjd_get_ble_is_connect(void) { return g_tjd_ble_is_connected; } bool tjd_get_ble_into_camera_flag(void) { return g_tjd_ble_into_camera_flag; } bool tjd_get_ble_is_link_to_app(void) { return bt_linkStatus; } void tjd_alipay_bt_gatts_noyify(uint8_t *data, uint16_t data_len) { gatts_ntf_ind_t data_info; data_info.attr_handle = g_tjd_alipay_handle; data_info.value = data; data_info.value_len = data_len; errcode_t ret = gatts_notify_indicate(gatt_server_id, g_server_conn_id, &data_info); static_print_debug("gatts_notify_indicate ret:0x%x. serverid:%u,conn_id:%u,handle:%u.", ret, gatt_server_id, g_server_conn_id, g_tjd_alipay_handle); } void tjd_get_gatt_server_conn_handle_id(uint8_t *server_id, uint16_t *conn_id, uint16_t *handle) { if (server_id == NULL || conn_id == NULL || handle == NULL) { return; } *server_id = gatt_server_id; *conn_id = g_server_conn_id; *handle = g_server_handle; } bd_addr_t *tjd_get_lastconned_addr(void) { return &g_tjd_lastconned_addr; } /* device向host发送数据:input report */ errcode_t tjd_ble_hid_server_send_input_report(void *data, uint8_t len) { gatts_ntf_ind_t param = {0}; uint8_t *report_data = (uint8_t *)data; param.attr_handle = (uint16_t)g_tjd_hid_input_report_att_hdl; // param.attr_handle = 0x22; param.value_len = len; param.value = malloc(len); if (param.value == NULL) { static_print_debug("[hid][ERROR]send input report new fail"); return ERRCODE_BT_MALLOC_FAIL; } if (memcpy_s(param.value, param.value_len, report_data, len) != EOK) { static_print_debug("[hid][ERROR]send input report memcpy fail"); free(param.value); return ERRCODE_BT_FAIL; } // errcode_t ret = gatts_notify_indicate(gatt_server_id, BLE_SINGLE_LINK_CONNECT_ID, ¶m); errcode_t ret = gatts_notify_indicate(gatt_server_id, g_server_conn_id, ¶m); if (ret != ERRCODE_SUCC) { static_print_debug("[hid][ERROR]send input report gatts_notify_indicate fail"); } static_print_debug("[hid][INFO]send input report ret:0x%x, serverid:%u,conn_id:%u,handle:0x%02x.", ret, gatt_server_id, g_server_conn_id, param.attr_handle); static_print_debug("[hid][INFO]send input report data"); for(int i = 0; i < len; i++) { static_print_debug("[%d]:0x%02x.", i, report_data[i]); } free(param.value); return ERRCODE_BT_SUCCESS; } uint32_t tjd_ble_get_mtu_size(void) { return g_tjd_ble_mtu_size; } void tjd_open_bluetooth_only(void) { //打开BT蓝牙广播 gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE,180); // osDelay(50); // errcode_t ret = gap_connect_remote_device(tjd_get_lastconned_addr()); // static_print_debug("gap_connect_remote_device ret:0x%x", ret); } void tjd_close_bluetooth_only(void) { //断开BT连接 gap_disconnect_remote_device(tjd_get_lastconned_addr()); //关闭蓝牙广播 gap_br_set_bt_scan_mode(GAP_SCAN_MODE_NONE,30); } uint8_t tjd_ble_get_hid_service_id(void) { return g_tjd_hid_server_id; } uint16_t tjd_ble_get_hid_srv_handle(void) { return g_tjd_hid_srv_handle; } void tjd_test_dial_config_json_file(void) { custom_dial_parameter_t dial_param = {0}; dial_param.setting_mode = 1; dial_param.images_number = 0; dial_param.switching_mode = 0; tjd_service_save_dial_parameter(&dial_param); } void register_gap_connect_state_callback_t(gap_connect_state_callback_t callback) { g_gap_connect_state_callback = callback; } void unregister_gap_connect_state_callback_t(void) { g_gap_connect_state_callback = NULL; } // uint16_t tjd_ble_get_lefun_handle(void) // { // return g_tjd_lefun_handle; // } #define SLOW 0 #define FAST 1 bool ble_connect_param_mode = SLOW; void tjd_connect_param_update(void) { gap_ble_conn_param_update_t g_conn_param = { 0 }; gap_ble_get_connection_param(g_server_conn_id, &g_conn_param); if(g_conn_param.interval >= GAP_BLE_LOWPWR_INTERVAL_MIN){ // 连接参数更新 if(ble_connect_param_mode == SLOW){ printf("fast param update!!! \r\n"); ble_connect_param_mode = FAST; gap_conn_param_update_t conn_param = { 0 }; conn_param.conn_handle = g_server_conn_id; conn_param.interval_min = GAP_BLE_FAST_INTERVAL_MIN; conn_param.interval_max = GAP_BLE_FAST_INTERVAL_MAX; conn_param.slave_latency = GAP_BLE_FAST_LATENCY; conn_param.timeout_multiplier = GAP_BLE_FAST_OUTTIME; gap_ble_connect_param_update(&conn_param); } } } errcode_t tjd_connect_param_revert(void) { errcode_t revert_ret = false; gap_ble_conn_param_update_t g_conn_param = { 0 }; gap_ble_get_connection_param(g_server_conn_id, &g_conn_param); if(g_conn_param.interval < GAP_BLE_LOWPWR_INTERVAL_MIN){ // 连接参数回退 revert_ret = true; printf("revert param update!!! \r\n"); gap_conn_param_update_t conn_param = { 0 }; conn_param.conn_handle = g_server_conn_id; conn_param.interval_min = GAP_BLE_LOWPWR_INTERVAL_MIN; conn_param.interval_max = GAP_BLE_LOWPWR_INTERVAL_MAX; conn_param.slave_latency = GAP_BLE_LOWPWR_LATENCY; conn_param.timeout_multiplier = GAP_BLE_LOWPWR_OUTTIME; gap_ble_connect_param_update(&conn_param); } return revert_ret; } int tjd_service_connect_param_handle(void) { struct timespec time = {0}; clock_gettime(CLOCK_MONOTONIC, &time); if(time.tv_sec - g_cmd_info.last_time.tv_sec >= CONNECT_PARAM_UPDATE_TIME/1000){ ble_connect_param_mode = SLOW; if(tjd_connect_param_revert()){ //回退成功关闭消息队列 return 0; } } return CONNECT_PARAM_UPDATE_TIME; } void tjd_service_connect_param_send_star(void) { queue_default_info_t data = {tjd_service_connect_param_handle, NULL, CONNECT_PARAM_UPDATE_TIME, NULL}; osal_msg_queue_write_copy(tjd_task_service_timer_get_queue_id(), (void *)&data, sizeof(queue_default_info_t), 0); } void tjd_service_connect_param_send_stop(void) { queue_default_info_t data = {tjd_service_connect_param_handle, NULL, 0, NULL}; osal_msg_queue_write_copy(tjd_task_service_timer_get_queue_id(), (void *)&data, sizeof(queue_default_info_t), 0); }