nordic蓝牙开发中的坑系列
1、使用主机模式设置蓝牙扫描规则时发现,当希望设置两个以上的过滤规则,但是实际表现往往不符合代码逻辑。在调试过中发现sdk封装的函数有问题。
ret_code_t nrf_ble_scan_filters_enable(nrf_ble_scan_t * const p_scan_ctx,
uint8_t mode,
bool match_all)
{
VERIFY_PARAM_NOT_NULL(p_scan_ctx);
// Check if the mode is correct.
if ((!(mode & NRF_BLE_SCAN_ADDR_FILTER)) &&
(!(mode & NRF_BLE_SCAN_NAME_FILTER)) &&
(!(mode & NRF_BLE_SCAN_UUID_FILTER)) &&
(!(mode & NRF_BLE_SCAN_SHORT_NAME_FILTER)) &&
(!(mode & NRF_BLE_SCAN_APPEARANCE_FILTER)))
{
return NRF_ERROR_INVALID_PARAM;
}
ret_code_t err_code;
// Disable filters.
err_code = nrf_ble_scan_filters_disable(p_scan_ctx);
ASSERT(err_code == NRF_SUCCESS);
nrf_ble_scan_filters_t * p_filters = &p_scan_ctx->scan_filters;
// Turn on the filters of your choice.
#if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
if (mode & NRF_BLE_SCAN_ADDR_FILTER)
{
p_filters->addr_filter.addr_filter_enabled = true;
}
#endif
#if (NRF_BLE_SCAN_NAME_CNT > 0)
if (mode & NRF_BLE_SCAN_NAME_FILTER)
{
p_filters->name_filter.name_filter_enabled = true;
}
#endif
#if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
if (mode & NRF_BLE_SCAN_SHORT_NAME_FILTER)
{
p_filters->short_name_filter.short_name_filter_enabled = true;
}
#endif
#if (NRF_BLE_SCAN_UUID_CNT > 0)
if (mode & NRF_BLE_SCAN_UUID_FILTER)
{
p_filters->uuid_filter.uuid_filter_enabled = true;
}
#endif
#if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
if (mode & NRF_BLE_SCAN_APPEARANCE_FILTER)
{
p_filters->appearance_filter.appearance_filter_enabled = true;
}
#endif
// Select the filter mode.
p_filters->all_filters_mode = match_all;
return NRF_SUCCESS;
}
在设置了过滤规则后,使用此函数使能设置,之后再次设置其他过滤规则并使能。此时由于line20函数的存在,后续的使能操作会disable掉之前的规则,导致无论设置使能几个规则,表现都是只有一个规则生效。在使用中要注意这个问题。
2、第二坑还是此函数引出的,当设置多个规则并且希望所有规则全部生效时,需要把参数match_all,设置为true。当希望删除所有规则时,调用
nrf_ble_scan_filters_disable
nrf_ble_scan_all_filter_remove
两个函数。此时出现的问题是,nrf_ble_scan_filters_disable只是disbale之前设置的每一项,nrf_ble_scan_all_filter_remove是把设置规则的存储空间清零。但是之前使用的全部匹配的参数 match_all则依然是true,则会导致蓝牙主机再也无法进入扫描回调。
在不更改sdk的前提下,此问题的解决方案是先调用一次nrf_ble_scan_filters_enable函数,把match_all参数设置为false,然后再disable和remove过滤规则。