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

469 lines
18 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_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 <stdlib.h>
#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, &param.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(&param, 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;
}