QN902x 主动扫描及响应数据
0赞
发表于 12/25/2016 10:33:42 PM
阅读(2495)
在某些应用从设备希望能够广播更多的数据,由于通用的广播包里含有BLE Name 等数据域,留下自定义的数据长度很有限,我们可以使用把需要广播的更多数据放到扫面响应这个广播包中。
从设备以QPPS为例,更改非常简单,只需要修改原来工程中调用广播发送的位置接口:
将
app_gap_adv_start_req(GAP_GEN_DISCOVERABLE|GAP_UND_CONNECTABLE, app_env.adv_data, app_set_adv_data(GAP_GEN_DISCOVERABLE), app_env.scanrsp_data, app_set_scan_rsp_data(app_get_local_service_flag()), GAP_ADV_FAST_INTV1, GAP_ADV_FAST_INTV2);
改为:
app_gap_adv_start_req(GAP_GEN_DISCOVERABLE|GAP_UND_CONNECTABLE, app_env.adv_data, app_set_adv_data(GAP_GEN_DISCOVERABLE), scan_data, sizeof(scan_data), GAP_ADV_FAST_INTV1, GAP_ADV_FAST_INTV2);
定义扫描响应的数组为:
uint8_t scan_data[9]={0x08,0xFF,0x31,0x32,0x33,0x34,0x35,0x36,0x37};
0x08 表示长度,0xFF表示出厂自定义数据,后面的七字节数据为自定义的广播数据
这时我们如果使用手机的Nordic nFRMaster软件,就可以看到:
手机软件在点击SCAN的时候,当扫描到某一设备时会发送扫描请求,然后就会获得广播设备发回的扫描响应。
对于QN902x做Master的话,有两点需要解决:
1) 如何发出扫描请求?
2) 如何获取扫描响应?
我们在client例程上进行修改,原工程中的app_gap_dev_inq_req函数经过测试发现并没有发出扫描请求的功能,我们应该调用app_gap_set_scan_mode_req() 函数去完成主动扫描,该函数的原型如下:
/* **************************************************************************************** * @brief Set scan mode request from the remote device. *//** * * @param[in] scan_type * - 0 = passive * - 1 = active * @param[in] scan_intv scan interval * @param[in] scan_window scan window * @response GAP_SET_MODE_REQ_CMP_EVT * @description * * This function is used to set scan mode. * **************************************************************************************** void app_gap_set_scan_mode_req(uint8_t scan_type, uint16_t scan_intv, uint16_t scan_window)
调用此函数后主设备就会一直不断的扫描,并发出扫描请求。
同时需要修改app_gap_dev_scan_result_handler()函数,在这里我们需要判断广播包的类型,因为ADV_IND,SCAN_RSP类型消息都会进到这里,需要人为去判断,这样才能获取对应的数据
/* **************************************************************************************** * @brief Handles inquiry result from the GAP. *//** * * @param[in] msgid GAP_ADV_REPORT_EVT * @param[in] param Pointer to struct gap_adv_report_evt * @param[in] dest_id TASK_APP * @param[in] src_id TASK_GAP * * @return If the message was consumed or not. * @description * * This handler is used to indicate that a BLE device has responded so far during inquiry process. **************************************************************************************** */ //#if (BLE_OBSERVER) int app_gap_dev_scan_result_handler(ke_msg_id_t const msgid, struct gap_adv_report_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // wenxue struct app_adv_data adv_data; QPRINTF("evt_type:%02X\r\n", param->evt.adv_rep[0].evt_type ); // wenxue SCAN_RSP-0x04 QPRINTF("%d. %c %02X%02X%02X%02X%02X%02X", app_env.inq_idx, param->evt.adv_rep[0].adv_addr_type ? 'R' : 'P', param->evt.adv_rep[0].adv_addr.addr[5], param->evt.adv_rep[0].adv_addr.addr[4], param->evt.adv_rep[0].adv_addr.addr[3], param->evt.adv_rep[0].adv_addr.addr[2], param->evt.adv_rep[0].adv_addr.addr[1], param->evt.adv_rep[0].adv_addr.addr[0]); // app_parser_adv_data((uint8_t *)param->evt.adv_rep[0].data, param->evt.adv_rep[0].data_len, &adv_data); // if (adv_data.flag & AD_TYPE_NAME_BIT) // { // QPRINTF(" %s", adv_data.name); // } // QPRINTF("\r\n"); // app_env.inq_idx++; // wenxue if(param->evt.adv_rep[0].evt_type==0x04)// SCAN_RSP-0x04 wenxue { QPRINTF(" %s", param->evt.adv_rep[0].data); QPRINTF("\r\n"); } else { app_parser_adv_data((uint8_t *)param->evt.adv_rep[0].data, param->evt.adv_rep[0].data_len, &adv_data); if (adv_data.flag & AD_TYPE_NAME_BIT) { QPRINTF(" %s", adv_data.name); } QPRINTF("\r\n"); } return(KE_MSG_CONSUMED); }
下面两张为使用sniffer配合wireshark进行抓包的结果:
代码如下: