469 lines
18 KiB
C
469 lines
18 KiB
C
/*----------------------------------------------------------------------------
|
||
* 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, ¶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;
|
||
}
|