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