510
个编辑
更改
→实验现象
==== 实验现象 ====
主机部分,上电打印例程名称'''1.4_ble_central_scan_whitelist''',如果成功设置白名单,则打印'''Successfully set whitelist!''',然后如果附近有白名单中的设备,则会打印扫描到的白名单设备的信息。
[[文件:Nrf rtt 14.png|边框|居中|无框|656x656像素]]
从机部分相较于前两章的内容,几乎没有改动,这边不做讲解。因为白名单的限制,是由主机部分完成。
==== 工程及源码讲解 ====
===== 工程说明 =====
本实验的修改内容集中在主机的扫描初始化以及扫描的回调事件处理函数中,所以下面只有主机部分的代码讲解,而没有从机部分的。
===== 主机部分 =====
====== scan_init()函数 ======
首先我们查看一下主机扫描的初始化函数,我们可以看到filter_policy过滤扫描参数,我们配置为BLE_GAP_SCAN_FP_WHITELIST,也就是白名单扫描模式。
启用这个白名单模式,如果成功,则会在扫描回调事件处理函数中给我们返回NRF_BLE_SCAN_EVT_WHITELIST_REQUEST请求开启白名单的事件ID。<syntaxhighlight lang="c" line="1" start="54">
// 定义扫描参数
static ble_gap_scan_params_t m_scan_params =
{
.active = 1, // 1为主动扫描,可获得广播数据及扫描回调数据
.interval = NRF_BLE_SCAN_SCAN_INTERVAL, // 扫描间隔:160*0.625 = 100ms
.window = NRF_BLE_SCAN_SCAN_WINDOW, // 扫描窗口:80*0.625 = 50ms
.timeout = NRF_BLE_SCAN_SCAN_DURATION, // 扫描持续的时间:设置为0,一直扫描,直到明确的停止扫描
.filter_policy = BLE_GAP_SCAN_FP_WHITELIST, // 扫描白名单设备
.scan_phys = BLE_GAP_PHY_1MBPS, // 扫描1MBPS的PHY
};
</syntaxhighlight><syntaxhighlight lang="c" line="1" start="181">
//******************************************************************
// fn : scan_init
//
// brief : 初始化扫描(未设置扫描数据限制)
//
// param : none
//
// return : none
static void scan_init(void)
{
ret_code_t err_code;
nrf_ble_scan_init_t init_scan;
// 清空扫描结构体参数
memset(&init_scan, 0, sizeof(init_scan));
// 配置扫描的参数
init_scan.p_scan_param = &m_scan_params;
// 初始化扫描
err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
APP_ERROR_CHECK(err_code);
}
</syntaxhighlight>
====== scan_evt_handler()函数 ======
可以看到,当我们接收到NRF_BLE_SCAN_EVT_WHITELIST_REQUEST事件时,我们将去调用sd_ble_gap_whitelist_set函数设置我们的白名单设备。
我们这边首先获取了从机的MAC地址:'''0xD363BFCE5C46''',然后将其添加到白名单设备列表当中。
当我们扫描到'''0xD363BFCE5C46'''后将打印他的广播和扫描回调数据、以及型号强度。
{{Note|text=这个地方,需要大家设置为自己的从设备MAC,不然无法使用此例程|type=tips}}
<syntaxhighlight lang="c" line="1" start="99">
//******************************************************************
// fn : scan_evt_handler
//
// brief : 处理扫描回调事件
//
// param : scan_evt_t 扫描事件结构体
//
// return : none
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
uint32_t err_code;
ble_gap_addr_t peer_addr;
ble_gap_addr_t const * p_peer_addr;
switch(p_scan_evt->scan_evt_id)
{
// 白名单设置请求
case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
{
memset(&peer_addr, 0x00, sizeof(peer_addr));
peer_addr.addr_id_peer = 1;
peer_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
peer_addr.addr[5] = 0xD3;
peer_addr.addr[4] = 0x63;
peer_addr.addr[3] = 0xBF;
peer_addr.addr[2] = 0xCE;
peer_addr.addr[1] = 0x5C;
peer_addr.addr[0] = 0x46;
p_peer_addr = &peer_addr;
// 设置白名单
err_code = sd_ble_gap_whitelist_set(&p_peer_addr, 0x01);
if (err_code == NRF_SUCCESS)
{
NRF_LOG_INFO("Successfully set whitelist!");
}
APP_ERROR_CHECK(err_code);
}break;
// 扫描到的白名单设备数据
case NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT:
{
// 判断是否为扫描回调数据
if(p_scan_evt->params.p_whitelist_adv_report->type.scan_response)
{
if(p_scan_evt->params.p_whitelist_adv_report->data.len) // 存在扫描回调数据
{
NRF_LOG_INFO("scan data: %s",
Util_convertHex2Str(
p_scan_evt->params.p_whitelist_adv_report->data.p_data,
p_scan_evt->params.p_whitelist_adv_report->data.len));
}
else
{
NRF_LOG_INFO("scan data: %s","NONE");
}
NRF_LOG_INFO("rssi: %ddBm",p_scan_evt->params.p_whitelist_adv_report->rssi);
}
else // 否则为广播数据
{
// 打印扫描的设备MAC
NRF_LOG_INFO("Device MAC: %s",
Util_convertBdAddr2Str((uint8_t*)p_scan_evt->params.p_whitelist_adv_report->peer_addr.addr));
if(p_scan_evt->params.p_whitelist_adv_report->data.len) // 存在广播数据
{
NRF_LOG_INFO("adv data: %s",
Util_convertHex2Str(
p_scan_evt->params.p_whitelist_adv_report->data.p_data,
p_scan_evt->params.p_whitelist_adv_report->data.len));
}
else
{
NRF_LOG_INFO("adv data: %s","NONE");
}
}
} break;
default:
break;
}
}
</syntaxhighlight>
===== 从机部分 =====
无
==== 实验总结 ====
经过白名单实验的学习,我们需要明白以下几点:
1.我们使用白名单功能的前提是我们知道对方设备的MAC。
2.白名单功能只需要主机完成
3.了解NRF_BLE_SCAN_EVT_WHITELIST_REQUEST事件以及sd_ble_gap_whitelist_set()函数
=== 通用连接实验 ===