mcu_hi3321_watch/tjd/ble/ble_api.c
2025-05-26 20:15:20 +08:00

1896 lines
79 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* 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 <stdlib.h>
#include <time.h>
// #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, &param);
errcode_t ret = gatts_notify_indicate(gatt_server_id, g_server_conn_id, &param);
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);
}