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

本帖最后由 dezhi 于 2015-4-3 14:41 编辑

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

 从机的广播关键有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。

欢迎关注小弟博客别把现在当未来-CSDN博客

你好,最近想再RK3288上学习蓝牙通信。请问该如何开始呢?能不能在RK3288上直接学习使用蓝牙4.0?
希望能指导指导。谢谢~