Firefly开源社区

标题: FireBlue QN9021 QN902x Proximity Reportor profile(防丢器) 之源码分析 (三)广播 [打印本页]

作者: dezhi    时间: 2015-4-3 11:38
标题: FireBlue QN9021 QN902x Proximity Reportor profile(防丢器) 之源码分析 (三)广播
本帖最后由 dezhi 于 2015-4-3 14:41 编辑

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

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

     回想一下FireBlue 开发板 烧录防丢器方案程序 上电后,需要向上拨动 joystick 才会开始广播,我们就从这里入手,找到按键处理函数,得到关键代码如下:
  1. app_gap_adv_start_req(GAP_GEN_DISCOVERABLE|GAP_UND_CONNECTABLE,
  2.                                 app_env.adv_data, app_set_adv_data(GAP_GEN_DISCOVERABLE),
  3.                                 app_env.scanrsp_data,
  4.                                 app_set_scan_rsp_data(app_get_local_service_flag()),
  5.                                 GAP_ADV_FAST_INTV1, GAP_ADV_FAST_INTV2);
复制代码


     F12 得到函数原型与参数注释如下
  1. ****************************************************************************************
  2. * @brief Start the device to advertising process.        *//**
  3. *
  4. * @param[in] mode Device mode to set, possible values are:
  5. * - GAP_NON_DISCOVERABLE   
  6. * - GAP_GEN_DISCOVERABLE   
  7. * - GAP_LIM_DISCOVERABLE   
  8. * - GAP_NON_CONNECTABLE     
  9. * - GAP_UND_CONNECTABLE     
  10. * - GAP_DIR_CONNECTABLE     
  11. * @param[in] adv_data Pointer to advertising data used in the advertising packets
  12. * @param[in] adv_data_len The length of advertising data
  13. * @param[in] scan_rsp_data Pointer to Scan Response data used in the advertising packets
  14. * @param[in] scan_rsp_data_len The length of Scan Response data
  15. * @param[in] adv_intv_min Minimum interval for advertising
  16. * @param[in] adv_intv_max Maximum interval for advertising
  17. * @response  GAP_SET_MODE_REQ_CMP_EVT
  18. * @description
  19. *
  20. * This function is used to set the device to advertising.
  21. *
  22. * @note
  23. * The stack will keep advertising with new parameters if calling this function in advertising state.
  24. * The adv_intv_min and adv_intv_max shall not be set to less than 0x00A0(100 ms) if the mode
  25. * is GAP_NON_DISCOVERABLE.
  26. ****************************************************************************************
  27. */
  28. void app_gap_adv_start_req(uint16_t mode, uint8_t *adv_data, uint8_t adv_data_len,
  29.                            uint8_t *scan_rsp_data, uint8_t scan_rsp_data_len,
  30.                            uint16_t adv_intv_min, uint16_t adv_intv_max);
复制代码


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

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

  2.                                                 gap_set_mode_req);
复制代码


    应用层与协议栈的交互是通过消息投递系统实现的,当TASK_GAP层完成设置广播参数的设定后会向TASK_APP,发送GAP_SET_MODE_REQ_CMP_EVT 消息,该消息的处理函数为:
  1. {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。
     

欢迎关注小弟博客http://blog.csdn.net/q562359345



作者: BiscuitET    时间: 2015-10-12 10:30
你好,最近想再RK3288上学习蓝牙通信。请问该如何开始呢?能不能在RK3288上直接学习使用蓝牙4.0?
希望能指导指导。谢谢~




欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1