NDK 蓝牙开发指南¶
本文主要通过一些示例,介绍蓝牙应用开发过程中常用的方法以及可能遇到的问题。
1 基础指标¶
1.1 功耗¶
蓝牙在不同的工作模式下功耗如下表所示:
测试条件:
基于例程
nimble\samples\ble_periph_hr
发射功率:0 dBm,广播数据:11 Bytes,PAN1070和PAN1010发射功率和广播数据一致;
测试配置:
CONFIG_SOC_DCDC_PAN1070
,CONFIG_PM_ENABLE
,CONFIG_LOW_SPEED_CLOCK_SRC
测试选项:LOW_POWER_TESET_CI_100MS
和LOW_POWER_TESET_CI_1000MS

PAN1070UA1A EVB 核心板功耗测试数据¶

PAN1070UA1A EVB 核心板配置latency功耗测试数据¶

PAN1010S9FA EVB 核心板功耗测试数据¶
2 开发流程¶
2.2 参考相关例程¶
蓝牙开发需要了解一些蓝牙协议相关的知识,可以参考蓝牙协议规范,网上也有很多协议的介绍,此处不作赘述。
当前SDK中提供了一些蓝牙相关的例程,涵盖了central、peripheral等。
在进行蓝牙开发之前,建议先看一下相关的文档,磨刀不误砍柴工,相信这些例程会对你的开发有所帮助。
2.3 了解蓝牙app代码的基本框架¶
2.3.1 蓝牙初始化¶
我们以ble_periph_hr
为例。芯片上电启动以后,进入main()
函数, 然后执行用户初始化函数setup()
, 在setup() 函数中调用 app_ble_init()
函数初始化和启动蓝牙
int main(void)
{
/* user initialization entry. */
setup();
/**
* "main()" is a thread if CONFIG_OS_EN=1
* "main()" is a main entry if CONFIG_OS_EN=0
*
* If the user is using the main thread, you need t·····o enable the following code
* and add the user's processing logic to the "loop()" function.
*/
#if 0
while(1)
{
loop();
}
#endif
}
/**
*******************************************************************************
* @brief user initialization entry
*******************************************************************************
*/
void setup(void)
{
/* ble stack initialization. */
app_ble_init();
/**
* TODO: user add application initialization code in here.
*/
}
void app_ble_init(void)
{
/* BLE Stack Initialization. */
pan_ble_stack_init(app_ble_pre_init_cb, app_ble_enabled_cb);
}
pan_ble_stack_init()
函数是ble stack初始化和启动函数,该函数将自动创建ble thread以处理蓝牙相关的数据和事件。 这个函数提供了两个回调函数,如下:
ble_stack_pre_init_cb
ble stack 预初始化回调, 这个回调用于在ble stack启动之前初始化一些与ble stack相关的参数,例如设置mac address/ 注册 GATT services / 初始化SDP等 。
注意:mac address设置 / GATT services 注册/ SDP初始化 必须在这个回调中完成。
ble_stack_enabled_cb
该回调指示ble stack已经启动完成,用户可以在这个回调中启动adv或者scan或者干一些其他的事。
2.3.2 蓝牙广播或者扫描¶
广播函数:
app_ble_gap_event
是 ble event处理回调。
void app_ble_advertise_start(void)
{
struct ble_gap_adv_params adv_params;
struct ble_hs_adv_fields fields;
int rc;
(void)rc; //remove compiler warning
/* set advertising data. */
memset(&fields, 0, sizeof(fields));
fields.flags = BLE_HS_ADV_F_DISC_GEN |
BLE_HS_ADV_F_BREDR_UNSUP;
fields.name = (uint8_t *)device_name;
fields.name_len = strlen(device_name);
fields.name_is_complete = 1;
fields.uuids16 = (ble_uuid16_t[]) {
BLE_UUID16_INIT(BLE_SVC_HRS_UUID16),
};
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
rc = ble_gap_adv_set_fields(&fields);
if (rc != 0) {
APP_LOG_ERR("setting advertisement data failed; rc=%d\n", rc);
app_assert(rc == 0);
}
/* set advertising parameter. */
memset(&adv_params, 0, sizeof(adv_params));
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(CONFIG_ADV_INTRVL_MS);
adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(CONFIG_ADV_INTRVL_MS + 10);
/* start adv with "adv_params" */
rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params,
app_ble_gap_event, NULL);
if (rc != 0) {
APP_LOG_ERR("enabling advertisement failed; rc=%d\n", rc);
return;
}
APP_LOG_INFO("BLE adv start...\n");
}
扫描函数:
app_ble_gap_event
是 ble event处理回调。
void app_ble_scan_start(void)
{
struct ble_gap_disc_params disc_params;
int rc;
(void)rc; //remove compiler warning
/* set scan parameter. */
disc_params.passive = 1;
disc_params.itvl = BLE_GAP_SCAN_ITVL_MS(60);
disc_params.window = BLE_GAP_SCAN_WIN_MS(50);
disc_params.filter_policy = 0;
disc_params.limited = 0;
disc_params.filter_duplicates = 0;
/* start scan with "disc_params" */
rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, app_ble_gap_event, NULL);
if (rc != 0) {
APP_LOG_ERR("Error initiating GAP discovery procedure; rc=%d\r\n", rc);
}
APP_LOG_INFO("scan starting\r\n");
}
2.3.3 GATT服务注册¶
GATT服务注册如下:
void app_ble_svc_init(void)
{
/* Register DIS service */
ble_svc_dis_init();
/* Register HRS service */
ble_svc_hrs_init();
/* register call-back(options) */
ble_hs_cfg.gatts_register_cb = app_ble_svr_register_cb;
ble_hs_cfg.gatts_register_arg = NULL;
}
NDK 提供了一系列的配置文件供用户使用:
如果用户要使用的service在profiles中有实现,可以直接添加相关的实现文件,然后调用初始化函数即可注册;
如果用户使用的service在profiles中没有实现,用户需要自己添加service的实现,可以参考profiles文件中的任意一个service的实现。
2.3.4 GAP事件处理¶
Nimble提供了一系列的事件供用户使用。用户需要注册ble event处理回调(ble event处理回调在start adv或者start scan时注册,参看”2.3.2 蓝牙广播或者扫描”的相关内容)。需要注意的是:在adv和scan启动时注册的GAP event回调可以是同一个函数,也可以是不同的函数,具体使用哪一个由用户根据自己的习惯来。
Nimble GAP事件如下:
#define BLE_GAP_EVENT_CONNECT 0 /*!< connection complete event. */
#define BLE_GAP_EVENT_DISCONNECT 1 /*!< disconnection complete event */
/* Reserved 2 */
#define BLE_GAP_EVENT_CONN_UPDATE 3 /*!< connection parameter update complete event. */
#define BLE_GAP_EVENT_CONN_UPDATE_REQ 4 /*!< RX LL connection param req */
#define BLE_GAP_EVENT_L2CAP_UPDATE_REQ 5 /*!< RX slave L2cap connection update req. */
#define BLE_GAP_EVENT_TERM_FAILURE 6 /*!< */
#define BLE_GAP_EVENT_DISC 7 /*!< adv report event */
#define BLE_GAP_EVENT_DISC_COMPLETE 8 /*!< scan duration expired event */
#define BLE_GAP_EVENT_ADV_COMPLETE 9 /*!< adv duration expired event */
#define BLE_GAP_EVENT_ENC_CHANGE 10 /*!< Encrypt Changed event */
#define BLE_GAP_EVENT_PASSKEY_ACTION 11 /*!< PinCode display/request event */
#define BLE_GAP_EVENT_NOTIFY_RX 12 /*!< Central Rx notify event. */
#define BLE_GAP_EVENT_NOTIFY_TX 13 /*!< Peripheral Tx notify cmpl event. */
#define BLE_GAP_EVENT_SUBSCRIBE 14 /*!< Enable/Disable Peripheral Notify & Indicate status event. */
#define BLE_GAP_EVENT_MTU 15 /*!< MTU update complete event. */
#define BLE_GAP_EVENT_IDENTITY_RESOLVED 16 /*!< indicate peer address is RPA event. */
#define BLE_GAP_EVENT_REPEAT_PAIRING 17 /*!< The user is asked whether to delete the existing pair info to create a new pair. */
#define BLE_GAP_EVENT_PHY_UPDATE_COMPLETE 18 /*!< PHY update complete event. */
#define BLE_GAP_EVENT_EXT_DISC 19 /*!< extended adv report event. */
#define BLE_GAP_EVENT_PERIODIC_SYNC 20 /*!< period adv sync event. */
#define BLE_GAP_EVENT_PERIODIC_REPORT 21 /*!< period adv report event. */
#define BLE_GAP_EVENT_PERIODIC_SYNC_LOST 22 /*!< period adv sync loss event. */
#define BLE_GAP_EVENT_SCAN_REQ_RCVD 23 /*!< rx scan req event. */
#define BLE_GAP_EVENT_PERIODIC_TRANSFER 24 /*!< */
#define BLE_GAP_EVENT_PATHLOSS_THRESHOLD 25 /*!< */
#define BLE_GAP_EVENT_TRANSMIT_POWER 26 /*!< */
GAP event 回调如下:
int app_ble_gap_event(struct ble_gap_event *event, void *arg)
{
struct ble_gap_conn_desc out_desc;
switch (event->type)
{
case BLE_GAP_EVENT_CONNECT:
APP_LOG_INFO("connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed",
event->connect.status);
if (event->connect.status != 0) {
app_ble_advertise_start();
conn_handle = 0xFFFF;
break;
}
ble_gap_conn_find(event->conn_update.conn_handle, &out_desc);
APP_LOG("\t-peer_ota_addr:%s(at:%d)\r\n"
"\t-peer_id_addr:%s(at:%d)\r\n"
"\t-conn_intvl:%d us\r\n"
"\t-latency:%d\r\n"
"\t-to:%d ms\r\n",
addr_to_str(out_desc.peer_ota_addr.val),
out_desc.peer_ota_addr.type,
addr_to_str(out_desc.peer_id_addr.val),
out_desc.peer_id_addr.type,
out_desc.conn_itvl*1250,
out_desc.conn_latency,
out_desc.supervision_timeout*10);
conn_handle = event->connect.conn_handle;
break;
case BLE_GAP_EVENT_DISCONNECT:
APP_LOG_INFO("disconnect; reason=0x%02x\n", (uint8_t)event->disconnect.reason & 0xff);
conn_handle = 0xFFFF;
app_ble_advertise_start();
break;
case BLE_GAP_EVENT_ADV_COMPLETE:
APP_LOG_INFO("adv duration expired - restart adv\n");
app_ble_advertise_start();
break;
case BLE_GAP_EVENT_SUBSCRIBE:
APP_LOG_INFO("subscribe event; cur_notify=%d, val_handle=%d\n",
event->subscribe.cur_notify, hrs_hrm_handle);
if(event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_WRITE)
{
if (event->subscribe.attr_handle == hrs_hrm_handle) {
notify_state = event->subscribe.cur_notify;
app_ble_hr_tx_timer_start();
}
else if (event->subscribe.attr_handle != hrs_hrm_handle) {
notify_state = event->subscribe.cur_notify;
app_ble_hr_tx_timer_stop();
}
}
// indicate user that connection terminate.
else if(event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_TERM){
notify_state = false;
app_ble_hr_tx_timer_stop();
}
break;
case BLE_GAP_EVENT_NOTIFY_TX:
APP_LOG_INFO("notify ok\n");
break;
case BLE_GAP_EVENT_MTU:
APP_LOG_INFO("mtu update event; conn_handle=%d mtu=%d\n",
event->mtu.conn_handle,
event->mtu.value);
break;
case BLE_GAP_EVENT_CONN_UPDATE:
{
ble_gap_conn_find(event->conn_update.conn_handle, &out_desc);
APP_LOG_INFO("conn upd cmpl: conn_handle:%d, itvl:%d us, latency:%d, to:%d ms\n",
out_desc.conn_handle,
out_desc.conn_itvl * 1250,
out_desc.conn_latency,
out_desc.supervision_timeout*10);
break;
}
default:
break;
}
return 0;
}
3 使能PA功能¶
有些用户希望在RF 天线端外挂PA以增强 RF 距离,这里详细描述在 ble 应用中如何添加PA支持。
3.1 软件接口¶
为了使用PA功能,用户需要在启动蓝牙功能之前使能PA
,使能PA需要调用如下API:
void pan_misc_set_pa_enable(uint8_t en);
具体用法如下:
void app_ble_pre_init_cb(void)
{
....
// Enable PA
pan_misc_set_pa_enable(1);
}
注:
P03 控制 PA 的 TX
P04 控制 PA 的 RX
4 BLE 常用API简介¶
4.1 GAP API¶
以下接口均可在 SDK ble_gap.h中找到,本节主要对一些常用接口 做了简要说明,具体细节用户可以到ble_gap.h中参看函数声明信息,了解函数的具体用法。
4.1.1 ble_gap_adv_start¶
函数原型:
int ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
int32_t duration_ms,
const struct ble_gap_adv_params *adv_params,
ble_gap_event_fn *cb, void *cb_arg);
功能说明:
该函数用于启动 ble adv, 函数参数的具体用法请参看 SDK ble_gap.h
4.1.4 ble_gap_adv_set_data¶
函数原型:
int ble_gap_adv_set_data(const uint8_t *data, int data_len);
功能说明:
该函数用于设置 adv 数据,adv数据格式应该按照蓝牙spec的要求的 LTV 格式和数据类型来。
4.1.5 ble_gap_adv_set_fields¶
函数原型:
int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *rsp_fields);
功能说明:
该函数用于设置 adv 数据, 它是对ble_gap_adv_set_data() 接口的包装,使用更加方便,函数形参 rsp_fields 是按照蓝牙spec要求列出了大部分支持的数据类型,用户在不需要参看蓝牙spec的情况下也能简单的设置 adv 数据。
4.1.6 ble_gap_adv_rsp_set_data¶
函数原型:
int ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len);
功能说明:
该函数用于设置scan rsp 数据,数据格式应该按照蓝牙spec的要求的 LTV 格式和数据类型来。
4.1.7 ble_gap_adv_rsp_set_fields¶
函数原型:
int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields);
功能说明:
该函数用设置scan rsp 数据,它是对 ble_gap_adv_rsp_set_data() 接口的包装,使用更加方便,函数形参 rsp_fields 是按照蓝牙spec要求列出了大部分支持的数据类型,用户在不需要参看蓝牙spec的情况下也能简单的设置 adv 数据。
4.1.8 ble_gap_disc¶
函数原型:
int ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms,
const struct ble_gap_disc_params *disc_params,
ble_gap_event_fn *cb, void *cb_arg);
功能说明:
该函数用于启动 scan 。
4.1.11 ble_gap_connect¶
函数原型:
int ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
int32_t duration_ms,
const struct ble_gap_conn_params *params,
ble_gap_event_fn *cb, void *cb_arg);
功能说明:
该函数用于 master 设备启动 连接 过程。
4.1.14 ble_gap_terminate¶
函数原型:
int ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason);
功能说明:
该函数用于主动断开一个 BLE 连接。
4.1.15 ble_gap_conn_find¶
函数原型:
int ble_gap_conn_find(uint16_t handle, struct ble_gap_conn_desc *out_desc);
功能说明:
该函数用于通过 handle 获取某个连接的信息,例如地址,连接参数等。
4.1.16 ble_gap_conn_find_by_addr¶
函数原型:
int ble_gap_conn_find_by_addr(const ble_addr_t *addr,
struct ble_gap_conn_desc *out_desc);
功能说明:
该函数用于通过 addr 获取某个连接的信息,例如地址,连接参数等。
4.1.17 ble_gap_wl_set¶
函数原型:
int ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count);
功能说明:
该函数用于设置白名单。
4.1.18 ble_gap_update_params¶
函数原型:
int ble_gap_update_params(uint16_t conn_handle,
const struct ble_gap_upd_params *params);
功能说明:
该函数用于更新某个连接的连接参数。
4.1.19 ble_gap_set_data_len¶
函数原型:
int ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time);
功能说明:
该函数用于更新controller data length.
4.1.20 ble_gap_security_initiate¶
函数原型:
int ble_gap_security_initiate(uint16_t conn_handle);
功能说明:
对于master,该函数用于启动pair过程;对于slave,该函数用于启动安全请求。
4.1.21 ble_gap_conn_rssi¶
函数原型:
int ble_gap_conn_rssi(uint16_t conn_handle, int8_t *out_rssi);
功能说明:
该函数用于获取连接过程中RF RX型号强度RSSI值。
4.1.22 ble_gap_unpair¶
函数原型:
int ble_gap_unpair(const ble_addr_t *peer_addr);
功能说明:
该函数用于解配对一个设备,该设备的配对信息将从flash中移除。
4.1.23 ble_gap_unpair_oldest_peer¶
函数原型:
int ble_gap_unpair_oldest_peer(void);
功能说明:
该接口用于从flash中删除最旧的设备的配对信息。
4.1.24 ble_gap_unpair_oldest_except¶
函数原型:
int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr);
功能说明:
该函数用于从flash删除除给定设备外的最旧的设备配对信息。
4.1.25 ble_gap_read_le_phy¶
函数原型:
int ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy);
功能说明:
该函数用于读取某个连接使用的PHY参数。
4.1.26 ble_gap_set_prefered_default_le_phy¶
函数原型:
int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask,
uint8_t rx_phys_mask);
功能说明:
该函数用于在连接创建之前,设置推荐的默认PHY参数到ble controller。
4.1.27 ble_gap_set_prefered_le_phy¶
函数原型:
int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
uint8_t rx_phys_mask, uint16_t phy_opts);
功能说明:
该函数用于设置某个连接的PHY参数。
4.2 GATT API¶
以下接口均可在 SDK ble_gatt.h中找到,本节主要对一些常用接口 做了简要说明,具体细节用户可以到ble_gatt.h中参看函数声明信息,了解函数的具体用法。
4.2.1 ble_gattc_exchange_mtu¶
函数原型:
int ble_gattc_exchange_mtu(uint16_t conn_handle,
ble_gatt_mtu_fn *cb, void *cb_arg);
功能说明:
该函数用于客户端更新MTU。
4.2.2 ble_gattc_read¶
函数原型:
int ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle,
ble_gatt_attr_fn *cb, void *cb_arg);
功能说明:
该函数用于客户端读 ATT 数据。
4.2.3 ble_gattc_read_by_uuid¶
函数原型:
int ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
uint16_t end_handle, const ble_uuid_t *uuid,
ble_gatt_attr_fn *cb, void *cb_arg);
功能说明:
该函数用于客户端读取指定 uuid 特征的值。
4.2.4 ble_gattc_write_no_rsp_flat¶
函数原型:
int ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle,
const void *data, uint16_t data_len);
功能说明:
该函数用于客户端写ATT数据到特征,并且不需要对端ACK。
4.2.5 ble_gattc_write_flat¶
函数原型:
int ble_gattc_write_flat(uint16_t conn_handle, uint16_t attr_handle,
const void *data, uint16_t data_len,
ble_gatt_attr_fn *cb, void *cb_arg);
功能说明:
该函数用于客户端写ATT数据到特征,并且需要对端ACK。
4.2.6 ble_gatts_notify_custom¶
函数原型:
int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
struct os_mbuf *om);
功能说明:
该函数用于服务器写Notify数据到客户端,并且不需要客户端 ACK。
4.2.7 ble_gatts_indicate_custom¶
函数原型:
int ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle,
struct os_mbuf *txom);
功能说明:
该函数用于服务器写Indicate数据到客户端,并且需要客户端 ACK。
4.2.8 ble_gatts_add_svcs¶
函数原型:
int ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs);
功能说明:
该函数用于添加一个GATT service.
4.2.9 ble_gatts_svc_set_visibility¶
函数原型:
int ble_gatts_svc_set_visibility(uint16_t handle, int visible);
功能说明:
该函数用于设置一个service是否可被发现。
4.2.10 ble_gatts_count_cfg¶
函数原型:
int ble_gatts_count_cfg(const struct ble_gatt_svc_def *defs);
功能说明:
该函数用于调整协议栈GATT service相关的计数器,在添加新service时,需要调用。
4.2.11 ble_gatts_find_svc¶
函数原型:
int ble_gatts_find_svc(const ble_uuid_t *uuid, uint16_t *out_handle);
功能说明:
该函数用于获取本地某个服务的handle信息。
4.2.12 ble_gatts_find_chr¶
函数原型:
int ble_gatts_find_chr(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid,
uint16_t *out_def_handle, uint16_t *out_val_handle);
功能说明:
该函数用于获取本地server中某个服务中的摸个特征的相关handle信息。
4.2.13 ble_gatts_find_dsc¶
函数原型:
int ble_gatts_find_dsc(const ble_uuid_t **svc_uuid, const ble_uuid_t **chr_uuid,
const ble_uuid_t **dsc_uuid, uint16_t **out_dsc_handle);
功能说明:
该函数用于获取本地server中某个服务中的摸个特征的某个描述符handle信息。
4.2.14 ble_gattc_disc_all_svcs¶
函数原型:
int ble_gattc_disc_all_svcs(uint16_t conn_handle,
ble_gatt_disc_svc_fn *cb, void *cb_arg);
功能说明:
该函数用于发现所有主服务。
4.2.15 ble_gattc_disc_svc_by_uuid¶
函数原型:
int ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid,
ble_gatt_disc_svc_fn *cb, void *cb_arg);
功能说明:
该函数用于发现特定UUID的主服务。
4.2.16 ble_gattc_find_inc_svcs¶
函数原型:
int ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
uint16_t end_handle,
ble_gatt_disc_svc_fn *cb, void *cb_arg);
功能说明:
该函数用于发现包含服务。
4.2.17 ble_gattc_disc_all_chrs¶
函数原型:
int ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
uint16_t end_handle, ble_gatt_chr_fn *cb,
void *cb_arg);
功能说明:
该函数用于发现某个服务中的所有特征。
4.2.18 ble_gattc_disc_chrs_by_uuid¶
函数原型:
int ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
uint16_t end_handle, const ble_uuid_t *uuid,
ble_gatt_chr_fn *cb, void *cb_arg);
功能说明:
该函数用于发现特定UUID的特征。
4.2.19 ble_gattc_disc_all_dscs¶
函数原型:
int ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle,
uint16_t end_handle,
ble_gatt_dsc_fn *cb, void *cb_arg);
功能说明:
该函数用于发现所有特征描述符。
4.3 SMP API¶
以下接口均可在 SDK ble_sm.h中找到,本节主要对一些常用接口 做了简要说明,具体细节用户可以到ble_sm.h中参看函数声明信息,了解函数的具体用法。
4.3.1 ble_sm_inject_io¶
函数原型:
int ble_sm_inject_io(uint16_t *conn_handle, struct ble_sm_io **pkey);
功能说明:
该函数用于在pair过程中输入 PIN Code、显示PIN Code、确认Number Compare值以及提供 OOB 信息。
4.3.2 ble_sm_set_sc_enable¶
函数原型:
void ble_sm_set_sc_enable(bool en);
功能说明:
该函数用于设置Auth_Req的 SC bit,以使能 SC pair mode。 默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.3.3 ble_sm_set_io_cap¶
函数原型:
void ble_sm_set_io_cap(uint8_t iocap);
功能说明:
该函数用于设置IO能力。默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.3.4 ble_sm_set_mitm_enable¶
函数原型:
void ble_sm_set_mitm_enable(bool en);
功能说明:
该函数用于使能MITM功能。默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.3.5 ble_sm_set_bond_enable¶
函数原型:
void ble_sm_set_bond_enable(uint8_t bond);
功能说明:
该函数用于使能bond。默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.3.6 ble_sm_set_oob_enable¶
函数原型:
void ble_sm_set_oob_enable(uint8_t oob_data_flag);
功能说明:
该函数用于使能oob。默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.3.7 ble_sm_set_our_key_dist¶
函数原型:
void ble_sm_set_our_key_dist(uint8_t key_mask);
功能说明:
该函数用于设置自己分发的key类型。默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.3.8 ble_sm_set_peer_key_dist¶
函数原型:
void ble_sm_set_peer_key_dist(uint8_t key_mask);
功能说明:
该函数用于设置对端分发的key类型。默认情况下,用户不需要手动调用这个API,可通过sdk_config.h配置。
4.4 Misc API¶
4.4.1 ble_hs_mbuf_from_flat¶
函数原型:
struct os_mbuf *ble_hs_mbuf_from_flat(const void **buf, uint16_t *len);
功能说明:
该函数用于将 buf 数组转化成 os_mbuf。
4.4.2 ble_hs_mbuf_to_flat¶
函数原型:
int ble_hs_mbuf_to_flat(const struct os_mbuf *om, void *flat, uint16_t max_len,
uint16_t *out_copy_len);
功能说明:
该函数用于从 os_mbuf 中读取数据到 数组。
5 BLE Lib 说明¶
SDK 为 pan107x
系列芯片提供了两个 lib 文件,一个带 optimize
后缀,一个不带,这两个 lib 文件可在 SDK 目录下 nimble/lib
中找到。
这两个库的区别:
带
optimize
后缀的库,是优化了 RAM 的 lib,其 RAM 消耗更少,但是功耗相对稍高不带
optimize
后缀的库,RAM 相对消耗多一些,但是功耗最优
除了上面的区别,这两个 lib 支持的功能一样, 用户可根据实际情况合理选择。