QN902x 主动扫描及响应数据
0赞
发表于 12/25/2016 10:33:42 PM
阅读(3130)
在某些应用从设备希望能够广播更多的数据,由于通用的广播包里含有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进行抓包的结果:


代码如下:
