nRF 主机扫描过滤器

纵然是瞬间 提交于 2020-01-14 19:37:52

SDK15.3

不同于 HOLYIOT 项目的做法,这次使用的是 nordic 官方的扫描过滤器

 

 

首先扫描初始化(如若有多个过滤条件则需修改参数 NRF_BLE_SCAN_UUID_CNT、NRF_BLE_SCAN_NAME_CNT、NRF_BLE_SCAN_SHORT_NAME_CNT、NRF_BLE_SCAN_ADDRESS_CNT、NRF_BLE_SCAN_APPEARANCE_CNT):

static char const m_target_periph_name[] = "Nordic_UART"; /**< Name of the device to try to connect to. This name is searched for in the scanning report data. */

/**@brief NUS UUID. */
static ble_uuid_t const m_nus_uuid =
{
    .uuid = BLE_UUID_NUS_SERVICE,
    .type = NUS_SERVICE_UUID_TYPE
};

static uint8_t m_target_periph_addr[6] = {0x60, 0xFD, 0x35, 0xB0, 0x4A, 0xD4};
static uint8_t m_target_periph_addr_1[6] = {0xB0, 0x3C, 0x16, 0xDE, 0x19, 0xF9};


//static ble_gap_addr_t const m_target_periph_addr =
//{
//    /* Possible values for addr_type:
//    BLE_GAP_ADDR_TYPE_PUBLIC,
//    BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
//    BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
//    BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
//    .addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
//    .addr = {0x60, 0xFD, 0x35, 0xB0, 0x4A, 0xD4}
//};


/**@brief Function for handling Scanning Module events.
 */
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
    ret_code_t err_code;
//    NRF_LOG_INFO("scan_evt_id: %2d.", p_scan_evt->scan_evt_id);
    switch(p_scan_evt->scan_evt_id)
    {
        case NRF_BLE_SCAN_EVT_FILTER_MATCH:
        {
            NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
                        p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[0],
                        p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[1],
                        p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[2],
                        p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[3],
                        p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[4],
                        p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr[5]);
        } break;

        case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
        {
            err_code = p_scan_evt->params.connecting_err.err_code;
            APP_ERROR_CHECK(err_code);
        } break;

        case NRF_BLE_SCAN_EVT_CONNECTED:
        {

            ble_gap_evt_connected_t const * p_connected = p_scan_evt->params.connected.p_connected;

            // Scan is automatically stopped by the connection.

            NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
                        p_connected->peer_addr.addr[0],
                        p_connected->peer_addr.addr[1],
                        p_connected->peer_addr.addr[2],
                        p_connected->peer_addr.addr[3],
                        p_connected->peer_addr.addr[4],
                        p_connected->peer_addr.addr[5]);
        } break;

        case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
        {
            NRF_LOG_INFO("Scan timed out.");
            scan_start();
        } break;

//    case NRF_BLE_SCAN_EVT_NOT_FOUND:
//    {
//        NRF_LOG_INFO("Scan not found.");
//    } break;

        default:
            break;

    }

}


/**@brief Function for initializing the scanning and setting the filters.
 */
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.connect_if_match = true;
    init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;

    err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
    APP_ERROR_CHECK(err_code);

//    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, m_target_periph_name);
//    APP_ERROR_CHECK(err_code);

//    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid);
//    APP_ERROR_CHECK(err_code);

//    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, &m_target_periph_addr.addr);
//    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, m_target_periph_addr);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, m_target_periph_addr_1);
    APP_ERROR_CHECK(err_code);

//    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ALL_FILTER, true);
//    APP_ERROR_CHECK(err_code);

//    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false);
//    APP_ERROR_CHECK(err_code);

//    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false);
//    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
    APP_ERROR_CHECK(err_code);
}

 

 

另:若需解析扫描到的广播数据,可遵从官方的解析方法;(不同与HOLYIOT --> 多度项目,参考 XZL --> 1_disease_control)

在扫描回调事件 scan_evt_handler --> NRF_BLE_SCAN_EVT_FILTER_MATCH 中解析,如下:

uint16_t data_offset = 0;
uint8_t const * user_parsed_manuf_data = 0;
uint16_t user_parsed_manuf_data_len = 0;

user_parsed_manuf_data_len = ble_advdata_search(p_scan_evt->params.filter_match.p_adv_report->data.p_data, \ p_scan_evt->params.filter_match.p_adv_report->data.len, \ &data_offset, \ BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA);

user_parsed_manuf_data = &(p_scan_evt->params.filter_match.p_adv_report->data.p_data)[data_offset];

 

然后因为仅作扫描不连接,所以屏蔽所有调用 nrf_ble_scan_connect_with_target 的地方,以防满足过滤器条件时连接上从设备。

 

注:使用 NRF_BLE_SCAN_ALL_FILTER 有问题,仍需解决

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!