android bluedroid 协议栈里面的各个组件之间的消息处理机制


1.  蓝牙协议栈里面的各组件的通信是通过消息队列,例如:
btu_task 和bta直接就是通过队列bt/stack/btu/btu_task.c
// Communication queue between btu_task and bta.
extern fixed_queue_t * btu_bta_msg_queue;

这个队列的初始化在
bt/stack/btu/btu_init.c

void BTU_StartUp(void)
{
    memset (&btu_cb, 0, sizeof (tBTU_CB));
    btu_cb.trace_level = HCI_INITIAL_TRACE_LEVEL;

    btu_bta_msg_queue =  fixed_queue_new(SIZE_MAX);
    if (btu_bta_msg_queue == NULL)
        goto error_exit;

之后需要在btu初始化的时候,把这个队列和相关的线程关联起来,这样发送完消息后,就可以通知相关的线程去队列里面取消息并进行处理
在文件bt/stack/btu/btu_task.c,

void btu_task_start_up(UNUSED_ATTR void *context) {

..................
  fixed_queue_register_dequeue(btu_bta_msg_queue,
      thread_get_reactor(bt_workqueue_thread),
       btu_bta_msg_ready,
      NULL);

然后在各个profile使用的话就是通过入列的方式
在bt/bta/sys/bta_sys_main.c中,

void bta_sys_sendmsg(void *p_msg)
{
    // There is a race condition that occurs if the stack is shut down while
    // there is a procedure in progress that can schedule a task via this
    // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
    // it gets used here; hence we check for NULL before using it.
    if (btu_bta_msg_queue)
         fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
}

一般一些profile的消息通过调用如上的方法来发送消息,例如:
HH的profile里面的添加一个虚拟的HID设备的时候,
void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
                  UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
{
    tBTA_HH_MAINT_DEV    *p_buf;
    UINT16  len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;

    p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf(len);

    if (p_buf != NULL)
    {
        memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));

        p_buf->hdr.event            =  BTA_HH_API_MAINT_DEV_EVT;
        p_buf->sub_event            =  BTA_HH_ADD_DEV_EVT;
        p_buf->hdr.layer_specific   = BTA_HH_INVALID_HANDLE;

        p_buf->attr_mask            = (UINT16) attr_mask;
        p_buf->sub_class            = sub_class;
        p_buf->app_id               = app_id;
        bdcpy(p_buf->bda, bda);

        memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
        if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list)
        {
            p_buf->dscp_info.descriptor.dl_len =  dscp_info.descriptor.dl_len;
            p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
            memcpy(p_buf->dscp_info.descriptor.dsc_list, dscp_info.descriptor.dsc_list, dscp_info.descriptor.dl_len);
        }
        else
        {
            p_buf->dscp_info.descriptor.dsc_list = NULL;
            p_buf->dscp_info.descriptor.dl_len = 0;
        }

         bta_sys_sendmsg(p_buf);
    }
}

发送完消息到队列后,相关联的线程就会收到这个消息,就行处理,
在bt/stack/btu/btu_task.c中,在这个函数里面就出列,并把相关的消息就行处理,

void  btu_bta_msg_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
    BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
     bta_sys_event(p_msg);
}

在bt/bta/sys/bta_sys_main.c中,

void bta_sys_event(BT_HDR *p_msg)
{
    UINT8       id;
    BOOLEAN     freebuf = TRUE;

    APPL_TRACE_EVENT("BTA got event 0x%x", p_msg->event);

    /* get subsystem id from event */
    id = (UINT8) (p_msg->event >> 8);

    /* verify id and call subsystem event handler */
    if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))
    {
        freebuf = (* bta_sys_cb. reg[id]-> evt_hdlr)(p_msg);
    }
    else
    {
        APPL_TRACE_WARNING("BTA got unregistered event id %d", id);
    }

    if ( freebuf) // 假如调用相关的evt_hdlr成功,则free相关的buf
    {
         GKI_freebuf(p_msg);
    }

}

如上的 (* bta_sys_cb . reg [id]-> evt_hdlr )这个函数指针是在各个profile初始化的时候赋值的,

各个profile调用如下的函数来进行注册的,在bt/bta/sys/bta_sys_main.c
void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
{
    bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
    bta_sys_cb.is_reg[id] = TRUE;
}

比如HH的,在bt/bta/hh/bta_hh_api.c中,

void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
{
    tBTA_HH_API_ENABLE *p_buf;

    /* register with BTA system manager */
     bta_sys_register(BTA_ID_HH, & bta_hh_reg);

    LOG_INFO("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
    p_buf = (tBTA_HH_API_ENABLE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_ENABLE));

    if (p_buf != NULL)
    {
        memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));

        p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
        p_buf->p_cback = p_cback;
        p_buf->sec_mask = sec_mask;

        bta_sys_sendmsg(p_buf);
    }
}

它会注册一个
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值