FireBlue QN9020 QN9021 QN902x Proximity Reportor profile(防丢器) 之源码分析 (三)广播

来源:互联网 发布:java编程题app 编辑:程序博客网 时间:2024/06/04 19:47

     每一对蓝牙设备的的通信都有一个连接的过程,而蓝牙4.0 与传统蓝牙的连接过程又有些不一样的,BLE4.0 的连接过程的先由从机(这里自然就是防丢器)先通过广播通道广播数据(advertising),主机(手机)监听广播通道,如果监听到有广播数据,则向其发送扫描请求(scan request),广播者接受到扫描请求后回复扫描响应(scan response)。流程如下图:


     从机的广播关键有3点
     1.广播的数据
     2.扫描响应的数据
     3.广播的时间间隙

     回想一下FireBlue 开发板 烧录防丢器方案程序 上电后,需要向上拨动 joystick 才会开始广播,我们就从这里入手,找到按键处理函数,得到关键代码如下:
          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);




     F12 得到函数原型与参数注释如下
***************************************************************************************** @brief Start the device to advertising process.        *//**** @param[in] mode Device mode to set, possible values are:* - GAP_NON_DISCOVERABLE    * - GAP_GEN_DISCOVERABLE    * - GAP_LIM_DISCOVERABLE    * - GAP_NON_CONNECTABLE     * - GAP_UND_CONNECTABLE     * - GAP_DIR_CONNECTABLE     * @param[in] adv_data Pointer to advertising data used in the advertising packets* @param[in] adv_data_len The length of advertising data* @param[in] scan_rsp_data Pointer to Scan Response data used in the advertising packets* @param[in] scan_rsp_data_len The length of Scan Response data* @param[in] adv_intv_min Minimum interval for advertising* @param[in] adv_intv_max Maximum interval for advertising* @response  GAP_SET_MODE_REQ_CMP_EVT* @description** This function is used to set the device to advertising.** @note* The stack will keep advertising with new parameters if calling this function in advertising state.* The adv_intv_min and adv_intv_max shall not be set to less than 0x00A0(100 ms) if the mode* is GAP_NON_DISCOVERABLE.*****************************************************************************************/void app_gap_adv_start_req(uint16_t mode, uint8_t *adv_data, uint8_t adv_data_len,                           uint8_t *scan_rsp_data, uint8_t scan_rsp_data_len,                           uint16_t adv_intv_min, uint16_t adv_intv_max);

第一个参数为广播的模式,
第二、第三为广播的数据的指针和长度。
第四、第五为扫描响应的数据指针和长度。
第六、第七为广播间隙的最小和最大值。

跟进app_gap_adv_start_req 得知,实质是TASK_APP 向 TASK_GAP 发送了一个GAP_SET_MODE_REQ 消息,消息携带了的参数为广播的内容。
struct gap_set_mode_req *msg = KE_MSG_ALLOC(GAP_SET_MODE_REQ, TASK_GAP, TASK_APP,                                                gap_set_mode_req);

应用层与协议栈的交互是通过消息投递系统实现的,当TASK_GAP层完成设置广播参数的设定后会向TASK_APP,发送GAP_SET_MODE_REQ_CMP_EVT 消息,该消息的处理函数为:
{GAP_SET_MODE_REQ_CMP_EVT,              (ke_msg_func_t) app_gap_set_mode_req_cmp_evt_handler}

跟进该函数,函数根据任务当前状态做出相应的处理。


跟进app_set_adv_data(GAP_GEN_DISCOVERABLE)
从源码解析出来的函数功能为设置app_env.adv_data 即广播数据为发现模式和名字

跟进app_set_scan_rsp_data(app_get_local_service_flag())
从源码解析出来的函数功能为设置app_env.scanrsp_data 即扫描响应数据为Profiles 的UUID

前面提到的 2个函数所组织的返回数据类型参考蓝牙标准规范v4.0,以下为从规格书截图,


所提供截图为广播、扫描响应数据格式 ,可以广播数据的内容,这里还得读者自己去查阅,理解得更为通透。


     在两个广播事件之间有一个间隔,如下图

     计算公式为:T_advEvent = advInterval + advDelay
     其中:
          advInterval 应为0.625ms 的整倍数,并且在20ms~10.24s 之间
          advDelay    是一个随机值 ,在 0~10ms 之间
     
     这里的广播间隙会影响BLE 的功耗,如果时间间隙过小,会频繁广播,加大功耗,间隙过大,被发现的过程就会增大,这里还得按照需求适当调整。

最后我们用Light Blue 探测 广播的内容,均为所设置的 内容,包括了发现模式,设备名称,Profiles UUID。
 
1 0