Android BT STACK BTU 和 HCI之间的消息传递


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

2.  这个队列的初始化在
bt/main/bte_main.c

void bte_main_boot_entry(void)
{
    module_init(get_module(GKI_MODULE));
    module_init(get_module(COUNTER_MODULE));

    hci = hci_layer_get_interface();
    if (!hci)
      LOG_ERROR("%s could not get hci layer interface.", __func__);

     btu_hci_msg_queue = fixed_queue_new(SIZE_MAX);
    if (btu_hci_msg_queue == NULL) {
      LOG_ERROR("%s unable to allocate hci message queue.", __func__);
      return;
    }

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

void btu_task_start_up(UNUSED_ATTR void *context) {

..................
  fixed_queue_register_dequeue( btu_hci_msg_queue,
      thread_get_reactor(bt_workqueue_thread),
       btu_hci_msg_ready,
      NULL);

}

发送消息的方式如下:
在文件bt/stack/btu/btu_hcif.c或btu_init.c中,
fixed_queue_enqueue( btu_hci_msg_queue, event);

发送到队列后,开始使用如下的方法进行处理:

在文件bt/stack/btu/btu_task.c中,
void  btu_hci_msg_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
    BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
     btu_hci_msg_process(p_msg);
}

static void btu_hci_msg_process(BT_HDR *p_msg) {
    /* Determine the input message type. */
    switch (p_msg->event & BT_EVT_MASK)
    {
        case BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK: // TODO(zachoverflow): remove this
            ((post_to_task_hack_t *)(&p_msg->data[0]))->callback(p_msg);
            break;
        case BT_EVT_TO_BTU_HCI_ACL:
            /* All Acl Data goes to L2CAP */
            l2c_rcv_acl_data (p_msg);
            break;

        case BT_EVT_TO_BTU_L2C_SEG_XMIT:
            /* L2CAP segment transmit complete */
            l2c_link_segments_xmitted (p_msg);
            break;

        case BT_EVT_TO_BTU_HCI_SCO:
#if BTM_SCO_INCLUDED == TRUE
            btm_route_sco_data (p_msg);
            break;
#endif

        case BT_EVT_TO_BTU_HCI_EVT:
             btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
            GKI_freebuf(p_msg);

#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
            /* If host receives events which it doesn't response to, */
            /* host should start idle timer to enter sleep mode.     */
            btu_check_bt_sleep ();
#endif
            break;

        case BT_EVT_TO_BTU_HCI_CMD:
             btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
            break;

        default:;
            int i = 0;
            uint16_t mask = (UINT16) (p_msg->event & BT_EVT_MASK);
            BOOLEAN handled = FALSE;

            for (; !handled && i < BTU_MAX_REG_EVENT; i++)
            {
                if ( btu_cb.event_reg[i]. event_cb == NULL) // btu_cb.event_reg[i].event_cb 这个callback是在哪里初始化的??
                    continue;

                if (mask == btu_cb.event_reg[i].event_range)
                {
                    if (btu_cb.event_reg[i].event_cb)
                    {
                        btu_cb.event_reg[i].event_cb(p_msg);
                        handled = TRUE;
                    }
                }
            }

            if (handled == FALSE)
                GKI_freebuf (p_msg);

            break;
    }

}

我们以一个调用 btu_hcif_send_cmd给controller发送指令为例子, 如下的一个为例:

void  btu_hcif_send_cmd (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_buf)
{
    if (!p_buf)
      return;

    uint16_t opcode;
    uint8_t *stream = p_buf->data + p_buf->offset;
    void * vsc_callback = NULL;

    STREAM_TO_UINT16(opcode, stream);

    // Eww...horrible hackery here
    /* If command was a VSC, then extract command_complete callback */
    if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC
#if BLE_INCLUDED == TRUE
        || (opcode == HCI_BLE_RAND)
        || (opcode == HCI_BLE_ENCRYPT)
#endif
       ) {
        vsc_callback = *((void **)(p_buf + 1));
    }

     hci_layer_get_interface()->transmit_command(
      p_buf,
       btu_hcif_command_complete_evt,
       btu_hcif_command_status_evt,
      vsc_callback);

#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
    btu_check_bt_sleep ();
#endif
}

hci_layer_get_interface这个方法调用 hci_layer_get_interface后 会返回一个函数指针,

const hci_t *hci_layer_get_interface() {
  buffer_allocator = buffer_allocator_get_interface();
  hal = hci_hal_get_interface();
  btsnoop = btsnoop_get_interface();
  hci_inject = hci_inject_get_interface();
  packet_fragmenter = packet_fragmenter_get_interface();
  vendor = vendor_get_interface();
  low_power_manager = low_power_manager_get_interface();

#ifdef BLUETOOTH_RTK
  hci_h5 =  hci_get_h5_interface();
#endif
#ifdef BLUETOOTH_RTK_COEX
  rtk_parse_manager = rtk_parse_manager_get_interface();
#endif
   init_layer_interface();
  return & interface;
}

stati
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值