/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2021. All rights reserved. * * Description: ble_port.c * * Author: even * * Create: 2024-05-20 *--------------------------- */ #include "ble_port.h" #include "audio_base_type.h" #include "audio_errors.h" #include "ble_api.h" #include "bts_avrcp_controller.h" #include "bts_hfp_hf.h" #include "bts_uuid.h" #include "osal_addr.h" #include "osal_list.h" #include "osal_task.h" #include "service_bt.h" #include "soc_errno.h" #include "sql_bt.h" #include "sys_config.h" #include #define ENABLE_STATIC_PRINT 1 #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 INVALID_SERVER_ID 0 #ifndef EOK #define EOK 0 #endif #define OSAL_SUCCESS 0 #define GATT_BLE_ADV_ID 1 extern bool g_tjd_bt_is_connected; extern bool g_tjd_ble_is_connected; extern bool g_tjd_ble_into_camera_flag; extern bool g_tjd_bt_adv_statue; /* gatt server ID */ static uint8_t g_hid_server_id = INVALID_SERVER_ID; static bool gatt_adv_start_state = false; /* spp server*/ #define SPP_SOCKET_RFCOMM 0x0 #define SPP_BLE_DEFAULT_NAME "WatchSPP" #define SPP_BLE_DEFAULT_NAME_LEN 9 #define SAMPLE_SPP_TASK_STACK_SIZE 2048 #define SAMPLE_SPP_TASK_PRI 20 #define SAMPLE_SPP_FILE_PATH_MAX_LEN 1024 #define SAMPLE_SPP_FILE_IO_BUF_LEN 128 #define SAMPLE_SPP_FILE_IO_TIMEOUT 120 static int spp_server_id = INVALID_SERVER_ID; static int spp_client_id = INVALID_SERVER_ID; void sample_gap_pair_request_callback(const bd_addr_t *bdAddr) { static_print_debug("BtGapPairRequestedCallback addr: %02x%02x%02x%02x%02x%02x", bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* addr下标 0 1 2 3 */ // errcode_t ret = gap_connect_remote_device(bdAddr); // if (ret != ERRCODE_SUCC) { // static_print_debug("gap_connect_remote_device fail, ret:%x.", ret); // return; // } errcode_t ret = gap_reconnect_media_device(bdAddr); static_print_debug("gap_reconnect_media_device ret:%x.", ret); } static void sample_gap_acl_state_changed_callback(const bd_addr_t *bd_addr, gap_acl_state_t state, unsigned int reason) { if (bd_addr == NULL) { static_print_debug("sample_gap_acl_state_changed_callback bd_addr is null "); return; } static_print_debug("gap_acl_state_changed_callback addr: "); for (int i = BD_ADDR_LEN - 1; i >= 0; i--) { static_print_info("%02x", bd_addr->addr[i]); } static_print_info("\r\n"); // errcode_t ret = gap_ble_connect_remote_device(bd_addr); // static_print_debug("gap_connect_remote_device ret(bool): %u", ret); static_print_debug("gap_acl_state_changed state: %d reason: %x ", state, reason); int device_class = 0; if ((state == GAP_ACL_STATE_DISCONNECTED) || (state == GAP_ACL_STATE_LE_DISCONNECTED)) { static_print_debug("GAP_ACL_STATE_DISCONNECTED"); // sql_bt_set_bind(0); // static_print_debug("sql_bt_set_bind 0"); // svr_ble_adv_start(); g_tjd_bt_is_connected = false; // if(reason != 0x16){ // errcode_t ret = gap_connect_remote_device(bd_addr); // static_print_debug("gap_connect_remote_device ret(errcode_t): %x", ret); // } // 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 ((state == GAP_ACL_STATE_CONNECTED) || (state == GAP_ACL_STATE_LE_CONNECTED)) { // int ret = a2dp_snk_get_device_connect_state(bd_addr); // static_print_debug("a2dp_src_get_device_connect_state ret(int): %x", ret); tjd_set_lastconned_addr(bd_addr); g_tjd_bt_is_connected = true; if (avrcp_ct_get_device_connect_state(bd_addr) == PROFILE_STATE_DISCONNECTED) { /* 连接建立成功后,主动建立AVRCP连接 */ static_print_debug("call avrcp_ct_connect"); int conn_ret = avrcp_ct_connect(bd_addr); static_print_debug("avrcp_ct_connect ret(int): %x", conn_ret); } // g_tjd_bt_is_connected = true; // BluetoothCaseInfo caseinfo = {0}; // memcpy_s(caseinfo.addr, BD_ADDR_LEN, bd_addr->addr, BD_ADDR_LEN); // bool tag = tjd_is_pair_dev_exist(caseinfo); // if(!tag){ // add_node_to_pair_dev_list(caseinfo); // } device_class = gap_get_device_class(bd_addr); static_print_debug(" state: %d reason: %x cod: %x", state, reason, device_class); if (device_class == HEADSET_COD_1 || device_class == HEADSET_COD_2 || device_class == HEADSET_COD_3) { int ret = a2dp_src_connect(bd_addr); static_print_debug("a2dp_src_connect ret(int): %x", ret); sql_bt_set_headset_lastconnect_addr(bd_addr->addr, sizeof(bd_addr->addr)); tjd_set_headset_last_connected_addr(bd_addr); } // if((device_class & 0x200) != 0){ // int ret = a2dp_snk_connect(bd_addr); // if(ret != ERRCODE_SUCC) { // static_print_debug("a2dp_snk_connect fail, ret:%x.", ret); // } // if (avrcp_tg_get_device_connect_state(bd_addr) == PROFILE_STATE_DISCONNECTED) { // /* 连接建立成功后,主动建立AVRCP连接 */ // static_print_debug("call avrcp_ct_connect"); // int conn_ret = avrcp_tg_connect(bd_addr); // static_print_debug("avrcp_tg_connect ret(int): %x", conn_ret); // } // } } } static void sample_gap_discovery_result_callback(const bd_addr_t *bd_addr) { if (bd_addr == NULL) { static_print_debug("sample_gap_discovery_result_callback bd_addr is null "); return; } static_print_debug("gap_discovery_result_callback"); unsigned char length = BD_NAME_LEN; unsigned char *device_name = (unsigned char *)(void *)malloc(length); if (device_name == NULL) { static_print_debug("gap_discovery_result_callback malloc error!"); return; } (void)memset_s(device_name, length, 0, length); bool isPaired = gap_get_pair_state(bd_addr); bool isConnected = bt_is_acl_connected(bd_addr); bool ret1 = gap_get_device_name(bd_addr, device_name, &length); int cod = gap_get_device_class(bd_addr); bool ret2 = gap_read_remote_rssi_value(bd_addr); static_print_debug("gap_discovery_result_callback addr: ****%02x%02x%02x%02x ", bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* addr下标 0 1 2 3 */ static_print_debug("cod: %x getNameRet: %x getRssiRet: %x ", cod, ret1, ret2); if (ret1) { static_print_debug("nameLen: %u name: \"%s\"", length, device_name); } if (length > 0) { tjd_add_node_to_found_dev_list(bd_addr, device_name, isPaired, isConnected, cod, ret2); } free(device_name); device_name = NULL; } static void sample_gap_local_device_name_changed_callback(const unsigned char *device_name, unsigned char length) { static_print_debug("gap_local_device_name_changed_callback length: %u name: \"%s\"", length, device_name); } static void sample_gap_local_device_addr_changed_callback(const bd_addr_t *bd_addr) { static_print_debug("gap_local_device_addr_changed_callback addr: ****%02x%02x%02x%02x", bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* addr下标 0 1 2 3 */ } static void sample_gap_scan_mode_changed_callback(int mode) { static_print_debug("gap_scan_mode_changed_callback mode: %d", mode); if(mode == GAP_SCAN_MODE_NONE){ g_tjd_bt_adv_statue = false; }else{ g_tjd_bt_adv_statue = true; } // if(mode == GAP_SCAN_MODE_NONE) { // //设置设备的可发现模式 // bool set_scan_mode = gap_br_set_bt_scan_mode(GAP_SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE, 60); // if (set_scan_mode == false) { // static_print_debug("ble_gap_br_set_bt_scan_mode faile"); // } // } } static void sample_gap_state_changed_callback(const int transport, const int status) { static_print_debug("gap_state_changed_callback transport: %d status: %d", transport, status); } static void sample_gap_discovery_state_changed_callback(int status) { static_print_debug("gap_discovery_state_changed_callback status: %d", status); } static void sample_gap_is_accept_conn_on_safe_mode_callback(const bd_addr_t *bd_addr, bool *res) { static_print_debug("is_accept_conn_on_safe_mode_callback addr: ****%02x%02x%02x%02x set *res true", bd_addr->addr[3], bd_addr->addr[2], /* addr下标 2 3 */ bd_addr->addr[1], bd_addr->addr[0]); /* addr下标 0 1 */ *res = true; } static void bt_gap_pair_confirmed_callback(const bd_addr_t *bd_addr, int req_type, int number) { static_print_debug("addr: ****%02x%02x%02x%02x req_type: %d number: %d", bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0], req_type, number); /* 3 2 1 0 idx */ } static void sample_gap_pair_status_changed_callback(const bd_addr_t *bd_addr, int status) { static_print_debug("gap_pair_status_changed_callback addr: ****%02x%02x%02x%02x status: %d", bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0], status); /* addr下标 0 1 2 3 */ } static void sample_gap_read_remote_rssi_event_callback(const bd_addr_t *bd_addr, int rssi, int status) { static_print_debug("gap_read_remote_rssi_event_callback addr: ****%02x%02x%02x%02x rssi: %d status: %d", bd_addr->addr[3], bd_addr->addr[2], /* addr下标 2 3 */ bd_addr->addr[1], bd_addr->addr[0], rssi, status); /* addr下标 0 1 */ if (status == ERRCODE_BT_SUCCESS) { tjd_update_found_dev_node_rssi(bd_addr, rssi); } } static void sample_gap_remote_alias_changed_callback(const bd_addr_t *bd_addr, const unsigned char *alias, unsigned char length) { static_print_debug("gap_remote_alias_changed_callback addr: ****%02x%02x%02x%02x length: %u alias: \"%s\"", bd_addr->addr[3], bd_addr->addr[2], /* addr下标 2 3 */ bd_addr->addr[1], bd_addr->addr[0], length, alias); /* addr下标 0 1 */ } static void sample_gap_remote_battery_level_changed_callback(const bd_addr_t *bd_addr, int battery_level) { static_print_debug("gap_remote_battery_level_changed_callback addr: ****%02x%02x%02x%02x battery_level: %d", bd_addr->addr[3], bd_addr->addr[2], /* addr下标 2 3 */ bd_addr->addr[1], bd_addr->addr[0], battery_level); /* addr下标 0 1 */ } static void sample_gap_remote_cod_changed_callback(const bd_addr_t *bd_addr, int cod) { static_print_debug("gap_remote_cod_changed_callback addr: ****%02x%02x%02x%02x cod: %d", bd_addr->addr[3], bd_addr->addr[2], /* addr下标 2 3 */ bd_addr->addr[1], bd_addr->addr[0], cod); /* addr下标 0 1 */ } static void sample_gap_remote_name_changed_callback(const bd_addr_t *bd_addr, const unsigned char *device_name, unsigned char length) { static_print_debug("gap_remote_name_changed_callback addr: ****%02x%02x%02x%02x length: %u device_name: \"%s\"", bd_addr->addr[3], bd_addr->addr[2], /* addr下标 2 3 */ bd_addr->addr[1], bd_addr->addr[0], length, device_name); /* addr下标 0 1 */ } static void sample_gap_remote_uuid_changed_callback(const bd_addr_t *bd_addr, bt_uuid_t uuid) { static_print_debug("gap_remote_uuid_changed_callback addr: ****%02x%02x%02x%02x uuid: ", bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* addr下标 0 1 2 3 */ for (int i = 0; i < uuid.uuid_len; i++) { static_print_info("%02x", uuid.uuid[i]); } static_print_info("\r\n"); } void register_gap_service_callback(void) { gap_call_backs_t cb = { .state_change_callback = sample_gap_state_changed_callback, .pair_requested_callback = sample_gap_pair_request_callback, .acl_state_changed_callbak = sample_gap_acl_state_changed_callback, .discovery_result_callback = sample_gap_discovery_result_callback, .device_name_changed_callback = sample_gap_local_device_name_changed_callback, .device_addr_changed_callback = sample_gap_local_device_addr_changed_callback, .scan_mode_changed_callback = sample_gap_scan_mode_changed_callback, .discovery_state_changed_callback = sample_gap_discovery_state_changed_callback, .is_accept_conn_on_safe_mode_callback = sample_gap_is_accept_conn_on_safe_mode_callback, .pair_confiremed_callback = bt_gap_pair_confirmed_callback, .pair_status_changed_callback = sample_gap_pair_status_changed_callback, .read_remote_rssi_event_callback = sample_gap_read_remote_rssi_event_callback, .remote_alias_changed_callback = sample_gap_remote_alias_changed_callback, .remote_battery_level_changed_callback = sample_gap_remote_battery_level_changed_callback, .remote_cod_changed_callback = sample_gap_remote_cod_changed_callback, .remote_name_changed_callback = sample_gap_remote_name_changed_callback, .remote_uuid_changed_callback = sample_gap_remote_uuid_changed_callback, }; int callbacks_ret = gap_register_callbacks(&cb); static_print_debug("gap reg cbk ret %x", callbacks_ret); } bool tjd_svr_gatt_get_adv_start_state(void) { return gatt_adv_start_state; } void tjd_svr_gatt_set_adv_start_state(bool state) { gatt_adv_start_state = state; } void svr_gatty_ble_adv_stop(void) { gap_ble_stop_adv(GATT_BLE_ADV_ID); } void svr_ble_adv_start(void) { uint8_t adv_id = GATT_BLE_ADV_ID; if (tjd_svr_gatt_get_adv_start_state()) { static_print_debug("BleAdvStart already started"); gap_ble_stop_adv(adv_id); osDelay(50); } // gap_ble_stop_adv(adv_id); // osDelay(50); // gap_ble_set_local_appearance(GAP_BLE_APPEARANCE_TYPE_GENERIC_WATCH); // svr_gap_ble_adv_data_set(adv_id); errcode_t ret = gap_ble_start_adv(adv_id); static_print_debug("svr_ble_adv_start bt gap_ble_start_adv ret = 0x%x", ret); } /* HFP HF Server */ static void sample_handle_hfp_connection_state_changed(const bd_addr_t *bd_addr, profile_connect_state_t state) { static_print_debug("handle_hfp_connection_state_changed callback ba_addr: %p ", bd_addr); static_print_debug("state: %d", state); } void register_hfp_hf_servers_callback(void) { hfp_hf_callbacks_t g_sample_hfp_hf_callbacks = { .conn_state_changed_cb = sample_handle_hfp_connection_state_changed, }; int ret = hfp_hf_register_callbacks(&g_sample_hfp_hf_callbacks); static_print_debug("hfp_hf_register_callbacks ret(int): %x", ret); } /* *********************************************************** * SPP SERVERS */ int ble_spp_servers_create(const char *name, uint8_t name_len) { spp_create_socket_para_t param = {0}; bts_data_to_uuid_len2(0x1101, ¶m.uuid); param.socket_type = SPP_SOCKET_RFCOMM; param.is_encrypt = true; // char * name = SPP_BLE_DEFAULT_NAME; // uint8_t name_len = SPP_BLE_DEFAULT_NAME_LEN; int ret = spp_server_create(¶m, name, name_len); if (ret == SPP_INVALID_ID) { // 创建Server失败,返回非法ID static_print_debug("[spp][INFO]create spp server faile invalid_id:%d", ret); return ret; } // 创建Server成功,返回Server ID static_print_debug("[spp][INFO]create spp server success server_id:%d", ret); return ret; } static int sample_spp_server_accept_task_body(const void *data) { int server_id = (int)(intptr_t)data; static_print_debug("server_id: %x", server_id); spp_client_id = spp_server_accept(server_id); static_print_debug("spp_server_accept ret: %x", spp_client_id); return OSAL_SUCCESS; } /* 等待client连接 */ void spp_cmd_server_accept(uint32_t server_id) { osal_task *task = osal_kthread_create(sample_spp_server_accept_task_body, (void *)(uintptr_t)server_id, "spp_server_accept_task", SAMPLE_SPP_TASK_STACK_SIZE); if (task == NULL) { static_print_debug("create task fail"); return; } int ret = osal_kthread_set_priority(task, SAMPLE_SPP_TASK_PRI); if (ret != OSAL_SUCCESS) { static_print_debug("set pri error: %08x", ret); } static_print_debug("create task success."); } static void sample_spp_proc_apk_data(int32_t client_id, uint8_t *data, uint16_t data_len) { if (data == NULL) { static_print_debug("read_buf is empty"); return; } if (data_len > 0) { static_print_debug("rcv spp msg from client:%d, data : %s , data_len=%u", client_id, data, data_len); } } static void sample_spp_conn_state_changed_callback(uint8_t client_id, profile_connect_state_t state) { if (state == PROFILE_STATE_CONNECTED) { static_print_debug("client:%u connected", client_id); } else { static_print_debug("client:%u disconnected", client_id); } } void ble_spp_servers_init(void) { spp_callbacks_t spp_cb = { .receive_data_cb = sample_spp_proc_apk_data, .conn_state_changed_cb = sample_spp_conn_state_changed_callback, }; errcode_t ret = (errcode_t)spp_register_callbacks(&spp_cb); spp_server_id = ble_spp_servers_create((const char *)SPP_BLE_DEFAULT_NAME, (uint8_t)SPP_BLE_DEFAULT_NAME_LEN); if (spp_server_id == SPP_INVALID_ID) { static_print_error("[spp][error]create spp server faile invalid_id:%d", spp_server_id); return; } static_print_debug("spp server create success"); spp_cmd_server_accept(spp_server_id); return; } errcode_t ble_spp_send_data(uint8_t *data, uint16_t len) { if (spp_client_id == -1) { static_print_error("[spp][error]spp_client_id is invalid"); return (errcode_t)-1; } errcode_t ret = spp_write(spp_client_id, (const char *)data, len); if (ret == SPP_INVALID_ID) { static_print_error("[spp][error]spp_write fail"); } static_print_debug("[spp][info]send data len:%d", ret); return ret; }