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

来源:互联网 发布:安卓程序员用mac好吗 编辑:程序博客网 时间:2024/05/25 13:34

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;
}

static void init_layer_interface() {
  if (!interface_created) {
    interface.send_low_power_command = low_power_manager->post_command;
    interface.do_postload = do_postload;

    // It's probably ok for this to live forever. It's small and
    // there's only one instance of the hci interface.
    interface.event_dispatcher = data_dispatcher_new("hci_layer");
    if (!interface.event_dispatcher) {
      LOG_ERROR("%s could not create upward dispatcher.", __func__);
      return;
    }

    interface.set_data_queue = set_data_queue;
#ifdef BLUETOOTH_RTK
    interface.transmit_int_command = transmit_int_command;
#endif
    interface.transmit_command transmit_command;
    interface.transmit_command_futured = transmit_command_futured;
    interface.transmit_downward = transmit_downward;
    interface_created = true;
  }
}

然后调用bt/hci/src/hci_layer.c中的transmit_command方法,


static void transmit_command(
    BT_HDR *command,
    command_complete_cb complete_callback,
    command_status_cb status_callback,
    void *context) {
  waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t));
  if (!wait_entry) {
    LOG_ERROR("%s couldn't allocate space for wait entry.", __func__);
    return;
  }

  uint8_t *stream = command->data + command->offset;
  STREAM_TO_UINT16(wait_entry->opcode, stream);
  wait_entry->complete_callback = complete_callback;
  wait_entry->status_callback = status_callback;
  wait_entry->command = command;
  wait_entry->context = context;

  // Store the command message type in the event field
  // in case the upper layer didn't already
  command->event = MSG_STACK_TO_HC_HCI_CMD;

  fixed_queue_enqueue(command_queuewait_entry);
}
这里会把command封装成一个wait_entry再发送到一个command_queue队列里面,

command_queue队列又是在start_up里面初始化的,

static future_t *start_up(void) {
  LOG_INFO("%s", __func__);
.........................
  command_queue = fixed_queue_new(SIZE_MAX);
  if (!command_queue) {
    LOG_ERROR("%s unable to create pending command queue.", __func__);
    goto error;
  }
.........................................

然后这个队列又与一个线程相关联起来,并使用event_command_ready来处理事件,
fixed_queue_register_dequeue(command_queue, thread_get_reactor(thread), event_command_ready, NULL);

// Command/packet transmitting functions

static void event_command_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
  if (command_credits > 0) {
    waiting_command_t *wait_entry = fixed_queue_dequeue(queue);
    command_credits--;

    // Move it to the list of commands awaiting response
    pthread_mutex_lock(&commands_pending_response_lock);
    list_append(commands_pending_response, wait_entry);
    pthread_mutex_unlock(&commands_pending_response_lock);

    // Send it off
    low_power_manager->wake_assert();
#ifdef BLUETOOTH_RTK
  if(bluetooth_rtk_h5_flag)
    hci_h5->send(wait_entry->command);
  else
    packet_fragmenter->fragment_and_dispatch(wait_entry->command);
#else
  packet_fragmenter->fragment_and_dispatch(wait_entry->command);// 调用packet_fragmenter.c里面的fragment_and_dispatch方法,
#endif
  low_power_manager->transmit_done();

#ifdef BLUETOOTH_RTK
  if(!bluetooth_rtk_h5_flag){
    non_repeating_timer_restart_if(command_response_timer, !list_is_empty(commands_pending_response));
  }
#else
  non_repeating_timer_restart_if(command_response_timer, !list_is_empty(commands_pending_response));
#endif
  }
}


packet_fragmenter这个变量的初始化也是在hci_layer.c中的hci_layer_get_interface初始化的,在发送过程中会回调之前在hci_layer.c中start_up()中packet_fragmenter->init(&packet_fragmenter_callbacks);注册的packet_fragmenter_callbacks这个结构体,这个结构体如下:

static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
  transmit_fragment,
  dispatch_reassembled,
#ifdef BLUETOOTH_RTK
  fragmenter_transmit_finished,
  filter_incoming_event
#else
  fragmenter_transmit_finished
#endif
};
在文件packet_fragmenter.c中,
static void fragment_and_dispatch(BT_HDR *packet) {
  assert(packet != NULL);

  uint16_t event = packet->event & MSG_EVT_MASK;
  uint8_t *stream = packet->data + packet->offset;

  // We only fragment ACL packets
  if (event != MSG_STACK_TO_HC_HCI_ACL) {
    callbacks->fragmented(packet, true); // 调用hci_layer.c文件中的packet_fragmenter_callbacks 结构体中的transmit_fragment
    return;
  }

  uint16_t max_data_size =
    SUB_EVENT(packet->event) == LOCAL_BR_EDR_CONTROLLER_ID ?
      controller->get_acl_data_size_classic() :
      controller->get_acl_data_size_ble();

  uint16_t max_packet_size = max_data_size + HCI_ACL_PREAMBLE_SIZE;
  uint16_t remaining_length = packet->len;

  uint16_t continuation_handle;
  STREAM_TO_UINT16(continuation_handle, stream);
  continuation_handle = APPLY_CONTINUATION_FLAG(continuation_handle);

  while (remaining_length > max_packet_size) {
    // Make sure we use the right ACL packet size
    stream = packet->data + packet->offset;
    STREAM_SKIP_UINT16(stream);
    UINT16_TO_STREAM(stream, max_data_size);

    packet->len = max_packet_size;
    callbacks->fragmented(packet, false);// 调用hci_layer.c文件中的packet_fragmenter_callbacks 结构体中的transmit_fragment

    packet->offset += max_data_size;
    remaining_length -= max_data_size;
    packet->len = remaining_length;

    // Write the ACL header for the next fragment
    stream = packet->data + packet->offset;
    UINT16_TO_STREAM(stream, continuation_handle);
    UINT16_TO_STREAM(stream, remaining_length - HCI_ACL_PREAMBLE_SIZE);

    // Apparently L2CAP can set layer_specific to a max number of segments to transmit
    if (packet->layer_specific) {
      packet->layer_specific--;

      if (packet->layer_specific == 0) {
        packet->event = MSG_HC_TO_STACK_L2C_SEG_XMIT;
        callbacks->transmit_finished(packet, false);// 调用hci_layer.c文件中的packet_fragmenter_callbacks 结构体中的fragmenter_transmit_finished
        return;
      }
    }
  }

  callbacks->fragmented(packet, true);// 调用hci_layer.c文件中的packet_fragmenter_callbacks 结构体中的transmit_fragment
}


上面的commands_pending_response的这个列表是在start_up里面创建的,然后在发送指令的时候会把相关的指令加到这个列表里面再等待响应,

  commands_pending_response = list_new(NULL);
  if (!commands_pending_response) {
    LOG_ERROR("%s unable to create list for commands pending response.", __func__);
    goto error;
  }

  command_response_timer = non_repeating_timer_new(COMMAND_PENDING_TIMEOUT, command_timed_out, NULL);
  if (!command_response_timer) {
    LOG_ERROR("%s unable to create command response timer.", __func__);
    goto error;
  }

如果响应超时的话,会回调command_timed_out重启bluetooth这个进程,static const uint32_t COMMAND_PENDING_TIMEOUT = 8000;这里会等待8S的超时,就会把自己kill掉,

static void command_timed_out(UNUSED_ATTR void *context) {
  pthread_mutex_lock(&commands_pending_response_lock);

  if (list_is_empty(commands_pending_response)) {
    LOG_ERROR("%s with no commands pending response", __func__);
  } else {
    waiting_command_t *wait_entry = list_front(commands_pending_response);
    pthread_mutex_unlock(&commands_pending_response_lock);

    // We shouldn't try to recover the stack from this command timeout.
    // If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
    LOG_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, wait_entry->opcode);
  }

  LOG_ERROR("%s restarting the bluetooth process.", __func__);
  usleep(10000);
  kill(getpid(), SIGKILL);
}

在hci_layer.c中的start_up方法里面,

thread = thread_new("hci_thread");
  if (!thread) {
    LOG_ERROR("%s unable to create thread.", __func__);
    goto error;
  }

  hal->init(&hal_callbacksthread);// 这个方法是调用hci_hal_h4.c中的方法hal_init()

static const hci_hal_callbacks_t hal_callbacks = {
  hal_says_data_ready
};

那么如上的方法就是把hal_callbacks (hci_hal_callbacks_t )的成员变量hal_says_data_ready 赋给data_ready,那么在有事件发生的时候就回调方法hal_says_data_ready 

// See what data is waiting, and notify the upper layer
static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *context) {
#ifdef BLUETOOTH_RTK
  if(!bluetooth_rtk_h5_flag) {
#endif
  if (stream_has_interpretation) {
    callbacks->data_ready(current_data_type);
  } else {
    uint8_t type_byte;
    if (eager_reader_read(reader, &type_byte, 1, true) == 0) {
      LOG_ERROR("%s could not read HCI message type", __func__);
      return;
    }
    if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
      LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
      return;
    }

    stream_has_interpretation = true;
    current_data_type = type_byte;
  }
#ifdef BLUETOOTH_RTK
  } else {
    stream_has_interpretation = true;
    current_data_type = DATA_TYPE_H5;
    callbacks->data_ready(current_data_type);
  }
#endif
}

// 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 byte;
#ifdef BLUETOOTH_RTK
  if(bluetooth_rtk_h5_flag){
    while(hal->read_data(type, &byte, 1, false) != 0) {
      hci_h5->rcv(&byte);
    }
  } else {
#endif
  while (hal->read_data(type, &byte, 1, false) != 0) {
    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;
          incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size);

          if (!incoming->buffer) {
            LOG_ERROR("%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)]; //这里会把HCI到来的event 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, false);
        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("%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);//接受报文完成后会保存到BT SNOOP里面

      if (type != DATA_TYPE_EVENT) {
        packet_fragmenter->reassemble_and_dispatch(incoming->buffer); // 如果改报文不是事件类型,就继续上传到上层
      } else if (!filter_incoming_event(incoming->buffer)) {//如果报文是事件类型,也会上传
        // 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
        );//这个方法里面的interface.event_dispatcher是在bte_main.c中入口函数bte_main_boot_entry()里面的data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue);初始化的,那么这里就会往btu_hci_msg_queue这个队列里面放相关的事件报文包
      }

      // 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;
    }
  }
#ifdef BLUETOOTH_RTK
  }
#endif
}

调用packet_fragmenter.c里面的reassemble_and_dispatch方法,

static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
  if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {//如果接受到报文消息是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("%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);
      }

      uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
      if (full_length <= packet->len) {
        if (full_length < packet->len)
          LOG_WARN("%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("%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("%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);//组装报文,调用hci_layer.c中的dispatch_reassembled()
      }
    }
  } else {
    callbacks->reassembled(packet);//组装报文,调用hci_layer.c中的dispatch_reassembled()
  }
}

在文件hci_layer.c中的dispatch_reassembled()方法
// 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
#ifdef BLUETOOTH_RTK
  if(!bluetooth_rtk_h5_flag)
    assert((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
#else
  assert((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);//判断改报文的事件类型是否是MSG_HC_TO_STACK_HCI_EVT,在这里应该是MSG_HC_TO_STACK_HCI_EVT事件类型
#endif
  assert(upwards_data_queue != NULL);
#ifdef BLUETOOTH_RTK_COEX
  if(!bluetooth_rtk_h5_flag) {
    if ((packet->event& MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {
      uint8_t *pp = ((uint8_t *)(packet + 1)) + packet->offset;
      rtk_parse_manager->rtk_parse_l2cap_data(pp,0);
    }
  }
#endif
  /*BOARD_HAVE_BLUETOOTH_RTK_COEX end*/

  if (upwards_data_queue) {
    fixed_queue_enqueue(upwards_data_queue, packet);
  } else {
    LOG_ERROR("%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__);
    buffer_allocator->free(packet);
  }
}

会把整个报文放到upwards_data_queue这个队列里面,
这个队列的定义如下:
// The hand-off point for data going to a higher layer, set by the higher layer
static fixed_queue_t *upwards_data_queue;
如上的注释,可以看出这个队列会被上层设定并使用,
它的初始化是在文件bt/main/bte_main.c中的bte_main_boot_entry方法,
******************************************************************************/
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;
    }

    data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue);
    hci->set_data_queue(btu_hci_msg_queue);
...................
}

如上的hci的接口就是hci_layer.c文件中hci_layer_get_interface()这个方法返回的,
然后在这个接口的初始化的时候会指定set_data_queue这个函数指针的成员变量,
我们可以到hci_t这个结构体中的这个函数指针的成员变量定义,
  // Set the queue to receive ACL data in
  void (*set_data_queue)(fixed_queue_t *queue);

static void init_layer_interface() {
  if (!interface_created) {
    interface.send_low_power_command = low_power_manager->post_command;
    interface.do_postload = do_postload;

    // It's probably ok for this to live forever. It's small and
    // there's only one instance of the hci interface.
    interface.event_dispatcher = data_dispatcher_new("hci_layer");
    if (!interface.event_dispatcher) {
      LOG_ERROR("%s could not create upward dispatcher.", __func__);
      return;
    }

    interface.set_data_queue = set_data_queue;
#ifdef BLUETOOTH_RTK
    interface.transmit_int_command = transmit_int_command;
#endif
    interface.transmit_command = transmit_command;
    interface.transmit_command_futured = transmit_command_futured;
    interface.transmit_downward = transmit_downward;
    interface_created = true;
  }
}

所以如上的 hci->set_data_queue(btu_hci_msg_queue);之后,那就是upwards_data_queue所指向的队列就是btu_hci_msg_queue ,那就是接受HCI的消息后通过组装分发到这队列里面来,
那么收到ACL DATA后,接下来会进一步的处理





=======================================================

以另外一个BT_EVT_TO_BTU_HCI_EVT事件为例子

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);

在文件bt/stack/btu/btu_hcif.c中,

void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
{
    UINT8   *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
    UINT8   hci_evt_code, hci_evt_len;
#if BLE_INCLUDED == TRUE
    UINT8   ble_sub_code;
#endif
    STREAM_TO_UINT8  (hci_evt_code, p);
    STREAM_TO_UINT8  (hci_evt_len, p);

    switch (hci_evt_code)
    {
        case HCI_INQUIRY_COMP_EVT:
            btu_hcif_inquiry_comp_evt (p);
            break;
        case HCI_INQUIRY_RESULT_EVT:
            btu_hcif_inquiry_result_evt (p);
            break;

.............................................

#if (BLE_LLT_INCLUDED == TRUE)
               case HCI_BLE_RC_PARAM_REQ_EVT:
                    btu_ble_rc_param_req_evt(p);
                    break;
#endif
               case HCI_BLE_DATA_LENGTH_CHANGE_EVT:
                    btu_ble_data_length_change_evt(p, hci_evt_len);
                    break;
            }
            break;
#endif /* BLE_INCLUDED */
        case HCI_VENDOR_SPECIFIC_EVT:
                btm_vendor_specific_evt (p, hci_evt_len);
#ifdef BLUETOOTH_RTK_API
                rtkbt_api_Hook(RTKBT_HOOK_RECEIVE_EVENT,(void *)p_msg,hci_evt_len);
#endif
            break;
    }
}






























static void btu_hcif_command_status_evt(uint8_t status, BT_HDR *command, void *context)
{
    BT_HDR *event = osi_calloc(sizeof(BT_HDR) + sizeof(command_status_hack_t));
    command_status_hack_t *hack = (command_status_hack_t *)&event->data[0];

    hack->callback = btu_hcif_command_status_evt_on_task;
    hack->status = status;
    hack->command = command;
    hack->context = context;

    event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;

    fixed_queue_enqueue(btu_hci_msg_queue, event);
}

0 0
原创粉丝点击