wuyage

QN902x 主动扫描及响应数据

0
阅读(2312)

在某些应用从设备希望能够广播更多的数据,由于通用的广播包里含有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软件,就可以看到:

298568432065685588.jpg


手机软件在点击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);
}

xxx.jpg


下面两张为使用sniffer配合wireshark进行抓包的结果:

xxx.jpg

YYY.jpg

代码如下:

QN902x主动扫描请求及响应.7z