在蓝牙使能后enable 过程中 调用 hal_open函数(system\bt\hci\src\hci_hal_mct.c)
event_stream = hci_reader_new(uart_fds[CH_EVT], HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX,
thread, event_event_stream_has_bytes);
if (!event_stream) {
LOG_ERROR("%s unable to create hci reader for the event uart serial port.", __func__);
goto error;
}
acl_stream = hci_reader_new(uart_fds[CH_ACL_IN], HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX,
thread, event_acl_stream_has_bytes);
if (!acl_stream) {
LOG_ERROR("%s unable to create hci reader for the acl-in uart serial port.", __func__);
goto error;
}
当SCO链路层有数据event_event_stream_has_bytes函数会被执行:
static void event_event_stream_has_bytes(void *context) {
int bytes_read;
hci_reader_t *reader = (hci_reader_t *) context;
bytes_read = read(reader->inbound_fd, reader->data_buffer+reader->wr_ptr,
reader->buffer_size - reader->wr_ptr);
if (bytes_read <= 0) {
LOG_ERROR("%s could not read HCI message type", __func__);
return;
}
reader->wr_ptr += bytes_read;
callbacks->data_ready(DATA_TYPE_EVENT);
}
当ACL链路层有数据 event_acl_stream_has_bytes函数会被调用;
static void event_acl_stream_has_bytes(void *context) {
// No real concept of incoming SCO typed data, just ACL
int bytes_read;
hci_reader_t *reader = (hci_reader_t *) context;
bytes_read = read(reader->inbound_fd, reader->data_buffer+reader->wr_ptr,
reader->buffer_size - reader->wr_ptr);
if (bytes_read <= 0) {
LOG_ERROR("%s could not read HCI message type", __func__);
return;
}
reader->wr_ptr += bytes_read;
callbacks->data_ready(DATA_TYPE_ACL);
}
static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
assert(upper_callbacks != NULL);
assert(upper_thread != NULL);
/* hal->init(&hal_callbacks, thread);callbacks = hal_callbacks = hal_says_data_ready*/
callbacks = upper_callbacks; // callbacks 等于 hal_says_data_ready
/*
upper_thread 为 hci_layer.c 调用start_up函数创建 thread= thread_new("hci_thread");
hal->init(&hal_callbacks, thread);
*/
thread = upper_thread;
return true;
}
callbacks回调在hal_init的时候已经初始化, callbacks->data_ready 函数对应hal_says_data_ready函数;
hal_says_data_ready函数定义在 system\bt\hci\src\hci_layer.c文件中
// Event/packet receiving functions
// This function is not required to read all of a packet in one go, so
// be wary of reentry. But this function must return after finishing a packet.
static void hal_says_data_ready(serial_data_type_t type) {
packet_receive_data_t *incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type)];
uint8_t reset;
uint8_t byte;
while (hal->read_data(type, &byte, 1) != 0) {
if (soc_type == BT_SOC_SMD) {
reset = hal->dev_in_reset();
if (reset) {
incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)];
if(!create_hw_reset_evt_packet(incoming))
break;
else {
//Reset SOC status to trigger hciattach service
if(property_set("bluetooth.status", "off") < 0) {
LOG_ERROR(LOG_TAG, "SSR: Error resetting SOC status\n ");
} else {
ALOGE("SSR: SOC Status is reset\n ");
}
}
}
}
switch (incoming->state) {
case BRAND_NEW:
// Initialize and prepare to jump to the preamble reading state
incoming->bytes_remaining = preamble_sizes[PACKET_TYPE_TO_INDEX(type)];
memset(incoming->preamble, 0, PREAMBLE_BUFFER_SIZE);
incoming->index = 0;
incoming->state = PREAMBLE;
// INTENTIONAL FALLTHROUGH
case PREAMBLE:
incoming->preamble[incoming->index] = byte;
incoming->index++;
incoming->bytes_remaining--;
if (incoming->bytes_remaining == 0) {
// For event and sco preambles, the last byte we read is the length
incoming->bytes_remaining = (type == DATA_TYPE_ACL) ? RETRIEVE_ACL_LENGTH(incoming->preamble) : byte;
size_t buffer_size = BT_HDR_SIZE + incoming->index + incoming->bytes_remaining;
if (buffer_size > MCA_USER_RX_BUF_SIZE) {
LOG_ERROR(LOG_TAG, "%s buffer_size(%zu) exceeded allowed packet size, allocation not possible", __func__, buffer_size);
incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)];
if(create_hw_reset_evt_packet(incoming))
break;
else
return;
}
incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size);
if (!incoming->buffer) {
LOG_ERROR(LOG_TAG, "%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size);
// Can't read any more of this current packet, so jump out
incoming->state = incoming->bytes_remaining == 0 ? BRAND_NEW : IGNORE;
break;
}
// Initialize the buffer
incoming->buffer->offset = 0;
incoming->buffer->layer_specific = 0;
incoming->buffer->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
memcpy(incoming->buffer->data, incoming->preamble, incoming->index);
incoming->state = incoming->bytes_remaining > 0 ? BODY : FINISHED;
}
break;
case BODY:
incoming->buffer->data[incoming->index] = byte;
incoming->index++;
incoming->bytes_remaining--;
size_t bytes_read = hal->read_data(type, (incoming->buffer->data + incoming->index), incoming->bytes_remaining);
incoming->index += bytes_read;
incoming->bytes_remaining -= bytes_read;
incoming->state = incoming->bytes_remaining == 0 ? FINISHED : incoming->state;
break;
case IGNORE:
incoming->bytes_remaining--;
if (incoming->bytes_remaining == 0) {
incoming->state = BRAND_NEW;
// Don't forget to let the hal know we finished the packet we were ignoring.
// Otherwise we'll get out of sync with hals that embed extra information
// in the uart stream (like H4). #badnewsbears
hal->packet_finished(type);
return;
}
break;
case FINISHED:
LOG_ERROR(LOG_TAG, "%s the state machine should not have been left in the finished state.", __func__);
break;
}
if (incoming->state == FINISHED) {
incoming->buffer->len = incoming->index;
btsnoop->capture(incoming->buffer, true);
if (type != DATA_TYPE_EVENT) {
if(hci_state == HCI_READY) {
packet_fragmenter->reassemble_and_dispatch(incoming->buffer);
} else {
LOG_WARN("%s, Ignoring the ACL pkt received", __func__);
buffer_allocator->free(incoming->buffer);
}
} else if (!filter_incoming_event(incoming->buffer)) {
if (hci_state == HCI_READY) {
// Dispatch the event by event code
uint8_t *stream = incoming->buffer->data;
uint8_t event_code;
STREAM_TO_UINT8(event_code, stream);
data_dispatcher_dispatch(
interface.event_dispatcher,
event_code,
incoming->buffer
);
} else {
LOG_WARN("%s, Ignoring the event pkt received", __func__);
buffer_allocator->free(incoming->buffer);
}
}
// We don't control the buffer anymore
incoming->buffer = NULL;
incoming->state = BRAND_NEW;
hal->packet_finished(type);
// We return after a packet is finished for two reasons:
// 1. The type of the next packet could be different.
// 2. We don't want to hog cpu time.
return;
}
}
}
hal->read_data(type, &byte, 1) ; 对应hci_hal_mct.c文件的read_data函数
static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) {
#if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
if (type == DATA_TYPE_ACL) {
return hci_reader_read(acl_stream, buffer, max_size);
} else if (type == DATA_TYPE_EVENT) {
return hci_reader_read(event_stream, buffer, max_size);
}
#else
if (type == DATA_TYPE_ACL) {
return eager_reader_read(acl_stream, buffer, max_size);
} else if (type == DATA_TYPE_EVENT) {
return eager_reader_read(event_stream, buffer, max_size);
}
#endif
LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
return 0;
}
size_t hci_reader_read(hci_reader_t *reader, uint8_t *buffer, size_t req_size) {
int bytes_read = 0;
assert(reader != NULL);
assert(buffer != NULL);
// If the caller wants nonblocking behavior, poll to see if we have
// any bytes available before reading.
if (reader->rd_ptr < reader->wr_ptr) {
bytes_read = reader->wr_ptr - reader->rd_ptr;
if ((size_t) bytes_read > req_size)
bytes_read = req_size;
memcpy(buffer, reader->data_buffer+reader->rd_ptr, bytes_read);
reader->rd_ptr += bytes_read;
} else {
bytes_read = read(reader->inbound_fd, buffer, req_size);
if(bytes_read == -1)
bytes_read = 0;
}
return bytes_read;
}
hal_says_data_ready函数中,处理读到的数据 存入incoming->buffer , 调用函数reassemble_and_dispatch进行数据组装;
typedef struct {
receive_state_t state;
uint16_t bytes_remaining;
uint8_t preamble[PREAMBLE_BUFFER_SIZE];
uint16_t index;
BT_HDR *buffer;
} packet_receive_data_t;
packet_receive_data_t *incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type)];
incoming->buffer 对应的结构体为BT_HDR
packet_fragmenter->reassemble_and_dispatch(incoming->buffer);
static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
/*
判断packet->event事件类型 如果是MSG_HC_TO_STACK_HCI_ACL执行以下, 如果不是执行
callbacks->reassembled(packet);
*/
if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {
uint8_t *stream = packet->data;
uint16_t handle;
uint16_t l2cap_length;
uint16_t acl_length;
STREAM_TO_UINT16(handle, stream);
STREAM_TO_UINT16(acl_length, stream);
STREAM_TO_UINT16(l2cap_length, stream);
assert(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);
uint8_t boundary_flag = GET_BOUNDARY_FLAG(handle);
handle = handle & HANDLE_MASK;
BT_HDR *partial_packet = (BT_HDR *)hash_map_get(partial_packets, (void *)(uintptr_t)handle);
if (boundary_flag == START_PACKET_BOUNDARY) {
if (partial_packet) {
LOG_WARN(LOG_TAG, "%s found unfinished packet for handle with start packet. Dropping old.", __func__);
hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
buffer_allocator->free(partial_packet);
}
if (acl_length < L2CAP_HEADER_SIZE) {
LOG_WARN(LOG_TAG, "%s L2CAP packet too small (%d < %d). Dropping it.", __func__, packet->len, L2CAP_HEADER_SIZE);
buffer_allocator->free(packet);
return;
}
uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
// Check for buffer overflow and that the full packet size + BT_HDR size is less than
// the max buffer size
if (check_uint16_overflow(l2cap_length, (L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE)) ||
((full_length + sizeof(BT_HDR)) > BT_DEFAULT_BUFFER_SIZE)) {
LOG_ERROR(LOG_TAG, "%s L2CAP packet has invalid length (%d). Dropping it.", __func__, l2cap_length);
buffer_allocator->free(packet);
return;
}
if (full_length <= packet->len) {
if (full_length < packet->len)
LOG_WARN(LOG_TAG, "%s found l2cap full length %d less than the hci length %d.", __func__, l2cap_length, packet->len);
callbacks->reassembled(packet);
return;
}
partial_packet = (BT_HDR *)buffer_allocator->alloc(full_length + sizeof(BT_HDR));
partial_packet->event = packet->event;
partial_packet->len = full_length;
partial_packet->offset = packet->len;
memcpy(partial_packet->data, packet->data, packet->len);
// Update the ACL data size to indicate the full expected length
stream = partial_packet->data;
STREAM_SKIP_UINT16(stream); // skip the handle
UINT16_TO_STREAM(stream, full_length - HCI_ACL_PREAMBLE_SIZE);
hash_map_set(partial_packets, (void *)(uintptr_t)handle, partial_packet);
// Free the old packet buffer, since we don't need it anymore
buffer_allocator->free(packet);
} else {
if (!partial_packet) {
LOG_WARN(LOG_TAG, "%s got continuation for unknown packet. Dropping it.", __func__);
buffer_allocator->free(packet);
return;
}
packet->offset = HCI_ACL_PREAMBLE_SIZE;
uint16_t projected_offset = partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE);
if (projected_offset > partial_packet->len) { // len stores the expected length
LOG_WARN(LOG_TAG, "%s got packet which would exceed expected length of %d. Truncating.", __func__, partial_packet->len);
packet->len = partial_packet->len - partial_packet->offset;
projected_offset = partial_packet->len;
}
memcpy(
partial_packet->data + partial_packet->offset,
packet->data + packet->offset,
packet->len - packet->offset
);
// Free the old packet buffer, since we don't need it anymore
buffer_allocator->free(packet);
partial_packet->offset = projected_offset;
if (partial_packet->offset == partial_packet->len) {
hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
partial_packet->offset = 0;
callbacks->reassembled(partial_packet);
}
}
} else {
callbacks->reassembled(packet);
}
}
函数中的callbacks在init的时候赋值为 packet_fragmenter_callbacks
static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
transmit_fragment,
dispatch_reassembled,
fragmenter_transmit_finished
};
dispatch_reassembled函数中通过发送消息给upwards_data_queue队列处理,
// Callback for the fragmenter to dispatch up a completely reassembled packet
static void dispatch_reassembled(BT_HDR *packet) {
// Events should already have been dispatched before this point
assert((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
assert(upwards_data_queue != NULL);
if (upwards_data_queue) {
fixed_queue_enqueue(upwards_data_queue, packet);
} else {
LOG_ERROR(LOG_TAG, "%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__);
buffer_allocator->free(packet);
}
}
static void set_data_queue(fixed_queue_t *queue) {
upwards_data_queue = queue;
}
upwards_data_queue 在函数 set_data_queue 进行赋值
set_data_queue 函数在bte_main_boot_entry被调用 upwards_data_queue 赋值为
btu_hci_msg_queue。 btu_hci_msg_queue为初期HCI发送回来的消息队列,所有消息在btu_hci_msg_ready函数中处理
btu_hci_msg_ready定义如下:
system\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);
#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
/* If the host receives events which it doesn't responsd to, */
/* it should start an idle timer to enter sleep mode. */
btu_check_bt_sleep ();
#endif
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);
osi_free(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:
osi_free(p_msg);
break;
}
}