BLE Central¶
1 功能概述¶
此项目演示蓝牙主机功能,通过扫描其他BLE设备,并通过特定的服务UUID进行识别,此处是ANS
服务0x1811
。作为对端,可以直接使用bleprph_enc
进行编译下载另外一个EVB上和主机sample完成测试。
2 环境要求¶
board:
pan108x evb
uart(option): 用来显示串口log(波特率921600,选项
8n1
)
3 编译和烧录¶
例程位置:<home>\nimble\samples\bluetooth\ble_central\keil
使用keil
进行打开项目选择需要的controller进行烧录ble_central_origin
或者ble_central_spark
进行编译烧录。
4 演示说明¶
烧录完成后,设备会一直打印收到的广播信息,连接上会显示
Connection established
,服务发现完成后输出Service discovery complete
。[10:48:46.565]LL Controller Version:bd5923c [10:48:46.603]ble_store_config_num_our_secs:0 ble_store_config_num_peer_secs:0 ble_store_config_num_cccds:0 [10:48:46.673]flags=0x06 uuids16(complete)=0xe0ff mfg_data=0x53:0x50:0x04:0x11:0x23:0x00:0x00:0x00:0x60:0x13 flags=0x06 name(complete)=QHM-C109 mfg_data=0x06:0x00:0x01:0x09:0x20:0x02:0x3f:0x6b:0x8e:0x3d:0x22:0x86:0x72:0xf0:0x67:0x3e:0x52:0x1f:0x94:0xe1:0xcd:0xc7:0x24:0x29:0x0f:0x6d:0x98:0x1a:0x55 flags=0x1a tx_pwr_lvl=12 mfg_data=0x4c:0x00:0x10:0x05:0x1c:0x18:0x03:0x6b:0xee flags=0x06 uuids16(complete)=0xe0ff mfg_data=0x53:0x50:0x04:0x11:0x23:0x00:0x00:0x00:0x60:0x13 flags=0x06 name(complete)=QHM-C109 flags=0x06 uuids16(complete)=0xe0ff mfg_data=0x53:0x50:0x04:0x11:0x23:0x00:0x00:0x00:0x60:0x13 flags=0x06 name(complete)=QHM-C109 .................................... [10:48:48.154]flags=0x06 name(complete)=QHM-C109 flags=0x06 uuids16(complete)=0xe0ff mfg_data=0x53:0x50:0x04:0x11:0x23:0x00:0x00:0x00:0x60:0x13 flags=0x06 uuids16(complete)=0x1811 name(complete)=nimble-bleprph tx_pwr_lvl=0 [10:48:48.242]Connection established handle=0 our_ota_addr_type=0 our_ota_addr=06:05:04:03:06:06 our_id_addr_type=0 our_id_addr=06:05:04:03:06:06 peer_ota_addr_type=0 peer_ota_addr=06:05:04:03:02:01 peer_id_addr_type=0 peer_id_addr=06:05:04:03:02:01 conn_itvl=32 conn_latency=0 supervision_timeout=256 encrypted=0 authenticated=0 bonded=0 [10:48:50.397]Service discovery complete; status=0 conn_handle=0 [10:48:50.515]Read complete; status=0 conn_handle=0 attr_handle=12 value=0x00 Write complete; status=270 conn_handle=0 attr_handle=22 Subscribe complete; status=0 conn_handle=0 attr_handle=20
断链时会有如下输出。
disconnect; reason=0x08 handle=0 our_ota_addr_type=0 our_ota_addr=06:05:04:03:06:06 our_id_addr_type=0 our_id_addr=06:05:04:03:06:06 peer_ota_addr_type=0 peer_ota_addr=06:05:04:03:02:01 peer_id_addr_type=0 peer_id_addr=06:05:04:03:02:01 conn_itvl=32 conn_latency=0 supervision_timeout=256 encrypted=0 authenticated=0 bonded=0
广播显示和连接过滤调整
如果广播打印太过频繁,影响查看相关log可以手动关掉:
blecent_gap_event(struct ble_gap_event *event, void *arg)
{
struct ble_gap_conn_desc desc;
struct ble_hs_adv_fields fields;
int rc;
switch (event->type) {
case BLE_GAP_EVENT_DISC:
rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
event->disc.length_data);
if (rc != 0) {
return 0;
}
/* An advertisment report was received during GAP discovery. */
print_adv_fields(&fields); /*此函数用于输出广播数据,可以屏蔽盖函数关掉*/
/* Try to connect to the advertiser if it looks interesting. */
blecent_connect_if_interesting(&event->disc); /*连接时的过滤函数*/
return 0;
连接时的过滤条件blecent_connect_if_interesting
:
/**
* Connects to the sender of the specified advertisement of it looks
* interesting. A device is "interesting" if it advertises connectability and
* support for the Alert Notification service.
*/
static void
blecent_connect_if_interesting(const struct ble_gap_disc_desc *disc)
{
uint8_t own_addr_type;
int rc;
/*Filter adv by rssi*/
if (disc->rssi < -70) /*此处可以调整RSSI进行过滤*/
{
return;
}
/* Don't do anything if we don't care about this advertiser. */
if (!blecent_should_connect(disc)) {
return;
}
/* Scanning must be stopped before a connection can be initiated. */
rc = ble_gap_disc_cancel();
if (rc != 0) {
printf("Failed to cancel scan; rc=%d\n", rc);
return;
}
/* Figure out address to use for connect (no privacy for now) */
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
printf("error determining address type; rc=%d\n", rc);
return;
}
/* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for
* timeout.
*/
rc = ble_gap_connect(own_addr_type, &disc->addr, 30000, NULL,
blecent_gap_event, NULL);
if (rc != 0) {
printf("Error: Failed to connect to device; addr_type=%d "
"addr=%s\n; rc=%d",
disc->addr.type, addr_str(disc->addr.val), rc);
return;
}
}