Files
kunlun/driver/extern/bluetooth/src/iot_bt_ext.c
2024-09-28 14:24:04 +08:00

743 lines
20 KiB
C

/****************************************************************************
*
* Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
*
* This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
* be copied by any method or incorporated into another program without
* the express written consent of Aerospace C.Power. This Information or any portion
* thereof remains the property of Aerospace C.Power. The Information contained herein
* is believed to be accurate and Aerospace C.Power assumes no responsibility or
* liability for its use in any way and conveys no license or title under
* any patent or copyright and makes no representation or warranty that this
* Information is free from patent or copyright infringement.
*
* ****************************************************************************/
#include "os_types.h"
#include "os_utils_api.h"
#include "os_mem_api.h"
#include "iot_config.h"
#include "iot_errno_api.h"
#include "iot_io_api.h"
#include "iot_config_api.h"
#include "iot_utils_api.h"
#include "iot_board_api.h"
#include "iot_task_api.h"
#include "iot_crc_api.h"
#include "iot_uart_h.h"
#include "iot_bt_ext_msg.h"
#include "iot_bt_ext.h"
#include "iot_bt_ext_upgrade.h"
#include "iot_bt_ext_dev_mgmt.h"
#if IOT_BT_EXT_ENABLE
/* for debug mode. default 0 */
#define IOT_BT_EXT_DEBUG 0
/* task priority */
#define IOT_BT_EXT_TASK_PRIO 7
/* task stack size */
#define IOT_BT_EXT_TASK_STACK_SIZE 512
/* task message count */
#define IOT_BT_EXT_TASK_MSG_COUNT 64
/* alarm timer period */
#define IOT_BT_EXT_ALARM_PERIOD_MS 1000
#define iot_bt_ext_ctxt_get() (g_bt_ext_ctxt)
static iot_bt_ext_ctxt_t *g_bt_ext_ctxt = NULL;
#if IOT_BT_EXT_DEBUG
#define iot_bt_ext_dbg(fmt, ...) iot_printf(fmt, ##__VA_ARGS__)
#else
#define iot_bt_ext_dbg(fmt, ...)
#endif
/* sub system config table */
static const iot_bt_ext_sub_cfg_t gc_bt_ext_sub_cfg_tbl[] = {
/* bt upgrade port config */
{
/* sub port id */
IOT_BT_EXT_PORT_UPGRADE,
/* sub port open function */
iot_bt_ext_upgrade_init,
/* sub port close function */
iot_bt_ext_upgrade_deinit,
/* sub port rx report callback function */
iot_bt_ext_upgrade_rx,
/* sub port alarm task callback function, implement by post messages */
iot_bt_ext_upgrade_timeover_cb,
},
/* bt device management port config */
{
/* sub port id */
IOT_BT_EXT_PORT_DEV_MGMT,
/* sub port open function */
iot_bt_ext_dm_open,
/* sub port close function */
iot_bt_ext_dm_close,
/* sub port rx report callback function */
iot_bt_ext_dm_rx,
/* sub port alarm task callback function, implement by post messages */
iot_bt_ext_dm_alarm_cb,
},
};
static void iot_bt_ext_data_print(uint8_t is_tx, uint16_t len, uint8_t *buf)
{
uint16_t i;
iot_printf("bt:is_tx=%d,len=%d. ", is_tx, len);
len = min(len, 32);
for (i = 0; i < len; i++) {
iot_printf("0x%02x ", *(buf + i));
}
iot_printf("\n");
}
void iot_bt_ext_clean_msg(uint16_t msg_type, uint16_t msg_id)
{
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
if (bt_ctxt) {
iot_task_clean_msg(bt_ctxt->task_hdl, msg_type, msg_id);
}
}
/* post message to task */
uint32_t iot_bt_ext_post_msg(uint16_t msg_type, uint16_t msg_id, void *data)
{
iot_task_msg_t *msg;
iot_bt_ext_msg_type_t *task_msg;
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
msg = iot_task_alloc_msg_with_reserved(bt_ctxt->task_hdl, 0);
if (NULL == msg) {
//IOT_ASSERT(0);
return ERR_NOMEM;
}
task_msg = (iot_bt_ext_msg_type_t *)msg;
task_msg->msg.type = msg_type;
task_msg->msg.id = msg_id;
task_msg->data = data;
iot_task_queue_msg(bt_ctxt->task_hdl, &task_msg->msg, 0);
return ERR_OK;
}
static iot_bt_ext_rpt_func_t iot_bt_ext_rpt_hdl_get(uint8_t port)
{
uint8_t i, offset;
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
/* sub port */
if (port < IOT_BT_EXT_PORT_USER_BASE) {
for (i = 0; i < bt_ctxt->sub_info.sub_num; i++) {
if (bt_ctxt->sub_info.cfg[i].port_id == port) {
return bt_ctxt->sub_info.cfg[i].rx_rpt_func;
}
}
} else { /* user port */
for (i = IOT_BT_EXT_PORT_USER_BASE; i < IOT_BT_EXT_PORT_USER_END; i++) {
offset = i - IOT_BT_EXT_PORT_USER_BASE;
if (bt_ctxt && (bt_ctxt->user_info[offset].port_id == port)) {
return bt_ctxt->user_info[offset].rx_rpt_func;
}
}
}
return NULL;
}
static void iot_bt_ext_rpt_handle(uint8_t port, iot_pkt_t *pkt)
{
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
if (!bt_ctxt) {
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
return;
}
iot_bt_ext_dbg("bt:%s. port=%d\n", __FUNCTION__, port);
iot_bt_ext_rpt_func_t func = iot_bt_ext_rpt_hdl_get(port);
if (func) {
func(pkt);
} else {
iot_printf("bt:port[%d] rpt not support\n", port);
iot_pkt_free(pkt);
}
}
static void iot_bt_ext_proto_parse(iot_pkt_t *pkt)
{
uint16_t crc_cal, len;
uint32_t err_no = 0;
uint8_t *buf;
iot_bt_ext_proto_start_t *proto_start;
iot_bt_ext_proto_hdr_t *proto_hdr;
iot_bt_ext_proto_end_t *proto_end;
if (!pkt) {
return;
}
buf = (uint8_t *)iot_pkt_data(pkt);
len = (uint16_t)iot_pkt_data_len(pkt);
iot_bt_ext_data_print(0, len, buf);
do {
/* check total len */
if (len < IOT_BT_EXT_PROTO_PACKET_MIN_LEN) {
err_no = (uint32_t)__LINE__;
break;
}
/* check start field */
proto_start = (iot_bt_ext_proto_start_t *)buf;
iot_bt_ext_dbg("bt:proto-start.0x%x-0x%x\n",
proto_start->start[0], proto_start->start[1]);
if ((IOT_BT_EXT_PROTO_START_CODE != proto_start->start[0])
|| (IOT_BT_EXT_PROTO_START_CODE != proto_start->start[1])) {
err_no = (uint32_t)__LINE__;
break;
}
/* check header field */
proto_hdr = (iot_bt_ext_proto_hdr_t *)(proto_start + 1);
iot_bt_ext_dbg("bt:proto-hdr.version:%d,port:%d,"
"crc=0x%x,len:%d\n",
proto_hdr->version, proto_hdr->port, proto_hdr->crc,
proto_hdr->length);
/* check version */ //TODO:
/* check port valid */
if (proto_hdr->port >= IOT_BT_EXT_PORT_USER_END) {
err_no = (uint32_t)__LINE__;
break;
}
/* check payload len */
if (proto_hdr->length > (len - IOT_BT_EXT_PROTO_PACKET_MIN_LEN)) {
err_no = (uint32_t)__LINE__;
break;
}
/* check payload crc */
crc_cal = iot_getcrc16((uint8_t *)(proto_hdr + 1), proto_hdr->length,
IOT_CRC16_TYPE_BT);
iot_bt_ext_dbg("bt:proto-src_crc=0x%x, cal_crc=0x%x\n",
proto_hdr->crc, crc_cal);
if (proto_hdr->crc != crc_cal) {
//err_no = (uint32_t)__LINE__;
//break;
}
/* check tail */
proto_end = (iot_bt_ext_proto_end_t *)((uint8_t *)(proto_hdr + 1) +
proto_hdr->length);
iot_bt_ext_dbg("bt:proto-end.0x%x-0x%x\n",
proto_end->end[0], proto_end->end[1]);
if ((IOT_BT_EXT_PROTO_END_CODE != proto_end->end[0])
|| (IOT_BT_EXT_PROTO_END_CODE != proto_end->end[1])) {
err_no = (uint32_t)__LINE__;
break;
}
/* set pkt data ptr for payload start */
iot_pkt_pull(pkt, sizeof(*proto_start) + sizeof(*proto_hdr));
/* set pkt tail ptr for payload end */
iot_pkt_shrink(pkt, sizeof(*proto_end));
iot_bt_ext_dbg("bt:proto_rpt_sub pkt_len=%d\n", iot_pkt_data_len(pkt));
/* report pkt */
iot_bt_ext_rpt_handle(proto_hdr->port, pkt);
} while(0);
if (err_no) {
iot_printf("bt:proto_parse.err=%d.\n", err_no);
iot_pkt_free(pkt);
}
}
/* protocol uart tx */
static void iot_bt_ext_send_handle(uint8_t port, iot_pkt_t *pkt)
{
uint16_t crc, len;
uint32_t err_no = 0;
iot_bt_ext_proto_start_t *proto_start;
iot_bt_ext_proto_hdr_t *proto_hdr;
iot_bt_ext_proto_end_t *proto_end;
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
do {
if ((NULL == bt_ctxt) || (NULL == pkt)) {
err_no = __LINE__;
break;
}
/* get input data len and crc */
len = (uint16_t)iot_pkt_data_len(pkt);
crc = iot_getcrc16(iot_pkt_data(pkt), len, IOT_CRC16_TYPE_BT);
/* set pkt data ptr */
proto_start = (iot_bt_ext_proto_start_t *)iot_pkt_push(pkt,
sizeof(iot_bt_ext_proto_start_t) + sizeof(iot_bt_ext_proto_hdr_t));
if (NULL == proto_start) {
err_no = __LINE__;
break;
}
/* set tail ptr */
if (NULL == iot_pkt_put(pkt, sizeof(iot_bt_ext_proto_end_t))) {
err_no = __LINE__;
break;
}
/* fill start code */
os_mem_set(proto_start, IOT_BT_EXT_PROTO_START_CODE,
sizeof(*proto_start));
/* fill proto header */
proto_hdr = (iot_bt_ext_proto_hdr_t *)(proto_start + 1);
proto_hdr->version = IOT_BT_EXT_PROTO_VERSION;
proto_hdr->port = port;
proto_hdr->length = len;
proto_hdr->crc = crc;
/* fill tail */
proto_end = (iot_bt_ext_proto_end_t *)((uint8_t *)(proto_hdr + 1)
+ len);
os_mem_set(proto_end, IOT_BT_EXT_PROTO_END_CODE, sizeof(*proto_end));
/* print output data */
iot_bt_ext_data_print(1, (uint16_t)iot_pkt_data_len(pkt),
(uint8_t *)iot_pkt_data(pkt));
/* send data */
iot_uart_send(bt_ctxt->peri_info.peri_hdl, pkt, NULL);
} while(0);
if (err_no) {
iot_bt_ext_dbg("bt:%s, err = %d\n", __FUNCTION__, err_no);
if (pkt) {
iot_pkt_free(pkt);
}
}
}
static void iot_bt_ext_msg_handle(iot_task_h task_h, iot_task_msg_t *msg)
{
iot_bt_ext_msg_type_t *msg_entry = (iot_bt_ext_msg_type_t *)msg;
switch (msg_entry->msg.type) {
case IOT_BT_EXT_MSG_TYPE_DATA_RX:
iot_bt_ext_proto_parse((iot_pkt_t *)msg_entry->data);
break;
case IOT_BT_EXT_MSG_TYPE_DATA_TX:
iot_bt_ext_send_handle((uint8_t)msg_entry->msg.id,
(iot_pkt_t *)msg_entry->data);
break;
case IOT_BT_EXT_MSG_TYPE_UPGRADE:
iot_bt_ext_upgrade_msg_handle((uint8_t)msg_entry->msg.id,
msg_entry->data);
break;
case IOT_BT_EXT_MSG_TYPE_DEV_MGMT:
iot_bt_ext_dm_msg_handle(msg_entry->msg.id, msg_entry->data);
break;
default:
break;
}
iot_task_free_msg(task_h, &(msg_entry->msg));
}
static void iot_bt_ext_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
{
iot_bt_ext_msg_type_t *msg_entry = (iot_bt_ext_msg_type_t *)msg;
switch (msg_entry->msg.type) {
case IOT_BT_EXT_MSG_TYPE_DATA_RX:
case IOT_BT_EXT_MSG_TYPE_DATA_TX:
if (msg_entry->data) {
iot_pkt_free((iot_pkt_t *)msg_entry->data);
}
break;
case IOT_BT_EXT_MSG_TYPE_UPGRADE:
case IOT_BT_EXT_MSG_TYPE_DEV_MGMT:
break;
default:
break;
}
iot_task_free_msg(task_h, &(msg_entry->msg));
}
static iot_task_h iot_bt_ext_task_init(void)
{
iot_task_config_t task_cfg = {0};
/* task config */
task_cfg.stack_size = IOT_BT_EXT_TASK_STACK_SIZE;
task_cfg.task_prio = IOT_BT_EXT_TASK_PRIO;
task_cfg.msg_size = sizeof(iot_bt_ext_msg_type_t);
task_cfg.msg_cnt = IOT_BT_EXT_TASK_MSG_COUNT;
task_cfg.queue_cnt = 1;
task_cfg.queue_cfg[0].quota = 0;
task_cfg.task_event_func = NULL;
task_cfg.msg_exe_func = iot_bt_ext_msg_handle;
task_cfg.msg_cancel_func = iot_bt_ext_msg_cancel;
return iot_task_create(IOT_DRIVER_MID, &task_cfg);
}
static void iot_bt_ext_peri_recv(uint8_t* buffer, uint32_t buffer_len,
bool_t is_full_frame, uint32_t invalid_data_len)
{
iot_pkt_t *pkt;
(void)invalid_data_len;
(void)is_full_frame;
iot_bt_ext_dbg("bt:%s-rx len %d\n", __FUNCTION__, buffer_len);
pkt = iot_pkt_alloc(buffer_len, IOT_DRIVER_MID);
if (pkt) {
os_mem_cpy(iot_pkt_put(pkt, buffer_len), buffer, buffer_len);
iot_bt_ext_post_msg(IOT_BT_EXT_MSG_TYPE_DATA_RX, 0, pkt);
}
}
static iot_uart_h iot_bt_ext_uart_init(iot_bt_ext_uart_cfg_t *cfg)
{
uint8_t uart_type;
iot_uart_h uart_hdl = NULL;
iot_frame_fmt fmt = { 0 };
fmt.preamble_code[0] = IOT_BT_EXT_PROTO_START_CODE;
fmt.preamble_code[1] = IOT_BT_EXT_PROTO_START_CODE;
fmt.preamble_codelen = IOT_BT_EXT_PROTO_START_LEN;
fmt.datalen_offset = sizeof(iot_bt_ext_proto_hdr_t)
- IOT_BT_EXT_PROTO_PL_LEN_FIELD_LEN;
fmt.datalen_size = IOT_BT_EXT_PROTO_PL_LEN_FIELD_LEN;
fmt.datalen_fix = 0;
fmt.backcode[0] = IOT_BT_EXT_PROTO_END_CODE;
fmt.backcode[1] = IOT_BT_EXT_PROTO_END_CODE;
fmt.backcode_offset = 0;
fmt.backcode_len = IOT_BT_EXT_PROTO_END_LEN;
fmt.frame_timeout = 20;
fmt.timeout_mode = TIMEOUT_PERDATA;
//TODO: will fix uart port
#if (HW_PLATFORM >= HW_PLATFORM_FPGA)
uart_type = UART_EXT_BT_PORT;
#else
uart_type = UART_IR_PORT; //TODO:
#endif
if (iot_board_get_uart(uart_type) >= IOT_UART_PORT_SUPP_MAX) {
return uart_hdl;
}
uart_hdl = iot_uart_open(iot_board_get_uart(uart_type),
iot_bt_ext_peri_recv, IOT_EXT_BT_PERI_BUF_LEN, &fmt);
if (uart_hdl && cfg) {
if (!iot_uart_set_config(uart_hdl, cfg->baud, (uint8_t)cfg->parity,
(uint8_t)cfg->data, (uint8_t)cfg->stop)) {
uart_hdl = (iot_uart_h)NULL;
}
}
return uart_hdl;
}
static void iot_bt_ext_alarm_inform(timer_id_t timer_id, void *arg)
{
uint8_t i;
iot_bt_ext_alarm_func_t alarm_func;
iot_bt_ext_ctxt_t *bt_ctxt;
(void)timer_id;
bt_ctxt = (iot_bt_ext_ctxt_t *)arg;
if (!bt_ctxt) {
return;
}
for (i = 0; i < bt_ctxt->sub_info.sub_num; i++) {
alarm_func = bt_ctxt->sub_info.cfg[i].alarm_func;
if (alarm_func) {
alarm_func((uint32_t)bt_ctxt->alarm_period);
}
}
}
static uint32_t iot_bt_ext_alarm_init(iot_bt_ext_ctxt_t *bt_ctxt)
{
if (!bt_ctxt) {
return ERR_INVAL;
}
bt_ctxt->alarm_timer = os_create_timer(IOT_DRIVER_MID, true,
(os_timer_func_t)iot_bt_ext_alarm_inform, bt_ctxt);
if (!bt_ctxt->alarm_timer) {
return ERR_FAIL;
}
bt_ctxt->alarm_period = IOT_BT_EXT_ALARM_PERIOD_MS;
return ERR_OK;
}
static void iot_bt_ext_alarm_start(iot_bt_ext_ctxt_t *bt_ctxt)
{
if (bt_ctxt && bt_ctxt->alarm_timer) {
if (0 == bt_ctxt->alarm_period) {
bt_ctxt->alarm_period = IOT_BT_EXT_ALARM_PERIOD_MS;
}
os_start_timer(bt_ctxt->alarm_timer, bt_ctxt->alarm_period);
}
}
static uint32_t iot_bt_ext_sub_open(iot_bt_ext_ctxt_t *bt_ctxt)
{
uint8_t i;
iot_bt_ext_sub_open_func_t func;
if (!bt_ctxt) {
return ERR_INVAL;
}
bt_ctxt->sub_info.sub_num = sizeof(gc_bt_ext_sub_cfg_tbl)
/ sizeof(gc_bt_ext_sub_cfg_tbl[0]);
bt_ctxt->sub_info.cfg = (iot_bt_ext_sub_cfg_t *)gc_bt_ext_sub_cfg_tbl;
for (i = 0; i < bt_ctxt->sub_info.sub_num; i++) {
func = bt_ctxt->sub_info.cfg[i].open_func;
if (func) {
if (ERR_OK != func()) {
break;
}
}
}
if (i < bt_ctxt->sub_info.sub_num) {
return ERR_FAIL;
}
return ERR_OK;
}
static void iot_bt_ext_sub_close(iot_bt_ext_ctxt_t *bt_ctxt)
{
uint8_t i;
iot_bt_ext_sub_close_func_t func;
if (bt_ctxt) {
return;
}
for (i = 0; i < bt_ctxt->sub_info.sub_num; i++) {
func = bt_ctxt->sub_info.cfg[i].close_func;
if (func) {
func();
}
}
bt_ctxt->sub_info.sub_num = 0;
bt_ctxt->sub_info.cfg = NULL;
}
iot_pkt_t *iot_bt_ext_send_pkt_get(uint32_t len)
{
iot_pkt_t *pkt;
if (NULL == iot_bt_ext_ctxt_get()) {
return NULL;
}
IOT_PKT_GET(pkt, IOT_BT_EXT_PROTO_PACKET_MIN_LEN + len,
sizeof(iot_bt_ext_proto_start_t) + sizeof(iot_bt_ext_proto_hdr_t),
IOT_DRIVER_MID);
return pkt;
}
uint32_t iot_bt_ext_rpt_register(uint8_t port, iot_bt_ext_rpt_func_t cb)
{
uint8_t offset;
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
/* check port valid */
if ((port < IOT_BT_EXT_PORT_USER_BASE)
|| (port >= IOT_BT_EXT_PORT_USER_END)) {
return ERR_INVAL;
}
if (bt_ctxt) {
offset = port - IOT_BT_EXT_PORT_USER_BASE;
bt_ctxt->user_info[offset].port_id = port;
bt_ctxt->user_info[offset].rx_rpt_func = cb;
iot_bt_ext_dbg("bt:%s. port=%d, func=0x%x\n",
__FUNCTION__, port, (uint32_t)cb);
return ERR_OK;
}
return ERR_NOT_READY;
}
void iot_bt_ext_send(uint8_t port, iot_pkt_t *pkt)
{
if (NULL == iot_bt_ext_ctxt_get()) {
return;
}
iot_bt_ext_post_msg(IOT_BT_EXT_MSG_TYPE_DATA_TX, port, pkt);
}
uint32_t iot_bt_ext_open(void)
{
uint32_t reason = 0;
if (g_bt_ext_ctxt) {
iot_printf("bt:exist\n");
return ERR_EXIST;
}
do {
/* check port id valid */
BUILD_BUG_ON((uint32_t)IOT_BT_EXT_PORT_SUB_NUM <=
(uint32_t)IOT_BT_EXT_PORT_USER_BASE);
/* alloc ctxt */
if (NULL == (g_bt_ext_ctxt = os_mem_malloc(IOT_DRIVER_MID,
sizeof(*g_bt_ext_ctxt)))) {
reason = (uint32_t)__LINE__;
break;
}
os_mem_set(g_bt_ext_ctxt, 0, sizeof(*g_bt_ext_ctxt));
/* init task ctxt */
g_bt_ext_ctxt->task_hdl = iot_bt_ext_task_init();
if (NULL == g_bt_ext_ctxt->task_hdl) {
reason = (uint32_t)__LINE__;
break;
}
/* init uart ctxt */
g_bt_ext_ctxt->peri_info.uart_cfg.parity = IOT_UART_PARITY_EVEN;
g_bt_ext_ctxt->peri_info.uart_cfg.data = 8;
g_bt_ext_ctxt->peri_info.uart_cfg.stop = 1;
g_bt_ext_ctxt->peri_info.uart_cfg.baud = 115200;
g_bt_ext_ctxt->peri_info.peri_hdl
= iot_bt_ext_uart_init(&g_bt_ext_ctxt->peri_info.uart_cfg);
if (NULL == g_bt_ext_ctxt->peri_info.peri_hdl) {
reason = (uint32_t)__LINE__;
break;
}
/* open sub module */
if (ERR_OK != iot_bt_ext_sub_open(g_bt_ext_ctxt)) {
reason = (uint32_t)__LINE__;
break;
}
if (ERR_OK != iot_bt_ext_alarm_init(g_bt_ext_ctxt)) {
reason = (uint32_t)__LINE__;
break;
}
} while(0);
iot_printf("bt:open-%d\n", reason);
if (reason) {
iot_bt_ext_close();
return ERR_FAIL;
} else {
iot_bt_ext_reset(IOT_BT_EXT_DM_BT_HW_RST);
/* start alarm timer */
iot_bt_ext_alarm_start(g_bt_ext_ctxt);
return ERR_OK;
}
}
uint32_t iot_bt_ext_close(void)
{
iot_bt_ext_ctxt_t *bt_ctxt = iot_bt_ext_ctxt_get();
if (NULL == bt_ctxt) {
return ERR_NOT_EXIST;
}
iot_bt_ext_sub_close(bt_ctxt);
/* release resources */
if (bt_ctxt->alarm_timer) {
os_delete_timer(bt_ctxt->alarm_timer);
bt_ctxt->alarm_timer = (timer_id_t)0;
}
if (bt_ctxt->peri_info.peri_hdl) {
iot_uart_close(bt_ctxt->peri_info.peri_hdl);
bt_ctxt->peri_info.peri_hdl = NULL;
}
if (bt_ctxt->task_hdl) {
iot_task_delete(bt_ctxt->task_hdl);
bt_ctxt->task_hdl = NULL;
}
os_mem_free(bt_ctxt);
g_bt_ext_ctxt = NULL;
iot_printf("bt:closed\n");
return ERR_OK;
}
#else /* IOT_BT_EXT_ENABLE */
iot_pkt_t *iot_bt_ext_send_pkt_get(uint32_t len)
{
(void)len;
return NULL;
}
void iot_bt_ext_send(uint8_t port, iot_pkt_t *pkt)
{
(void)port;
if (pkt) {
iot_pkt_free(pkt);
}
return;
}
uint32_t iot_bt_ext_rpt_register(uint8_t port, iot_bt_ext_rpt_func_t cb)
{
(void)port;
(void)cb;
return ERR_NOSUPP;
}
uint32_t iot_bt_ext_open(void)
{
return ERR_NOSUPP;
}
uint32_t iot_bt_ext_close(void)
{
return ERR_OK;
}
#endif /* IOT_BT_EXT_ENABLE */