美文网首页
Bluetooth Send HCI CMD

Bluetooth Send HCI CMD

作者: MelanDawn | 来源:发表于2021-10-14 00:36 被阅读0次

本文基于 AOSP 的 android-11.0.0_r48 分支。

1. Overview

在 AOSP 中,蓝牙协议栈通过 HIDL 接口向 Vendor 发送 HCI CMD 主要通过两个函数:

  1. btu_hcif_send_cmd_with_cb - 自定义回调
  2. btu_hcif_send_cmd - 协议栈的默认回调

ACL、SCO、ISO 等数据包的发送也可以参考该流程,但应该有稍许不同。

2. Initialization

发送 HCI CMD 的函数主要涉及到 4 个源文件:

  1. system/bt/stack/btu/btu_hcif.cc
  2. system/bt/hci/src/hci_layer.cc
  3. system/bt/hci/src/packet_fragmenter.cc
  4. system/bt/hci/src/hci_layer_android.cc

其中有些存在依赖关系,因此先介绍初始化流程中的依赖部分。

2.1 hci_layer_get_interface() in btu_hcif.cc

system/bt/stack/btu/btu_hcif.cc

void btu_hcif_send_cmd_with_cb(const base::Location& posted_from,
                               uint16_t opcode, uint8_t* params,
                               uint8_t params_len, hci_cmd_cb cb) {
......
  hci_layer_get_interface()->transmit_command(
      p, btu_hcif_command_complete_evt_with_cb,
      btu_hcif_command_status_evt_with_cb, (void*)cb_wrapper);
}


void btu_hcif_send_cmd(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_buf) {
......
  hci_layer_get_interface()->transmit_command(
      p_buf, btu_hcif_command_complete_evt, btu_hcif_command_status_evt,
      vsc_callback);
}

由以上源代码可知,两个 HCI 发送函数最终都调用了 hci_layer_get_interface(),然后再调用发送命令的函数,那么首先确定 hci_layer_get_interface() 函数获取的内容是什么。

system/bt/hci/src/hci_layer.cc

static hci_t interface;


const hci_t* hci_layer_get_interface() {
  if (bluetooth::shim::is_gd_shim_enabled()) {                  // 1
    return bluetooth::shim::hci_layer_get_interface();
  } else {
    return bluetooth::legacy::hci_layer_get_interface();        // 2
  }
}


namespace bluetooth {
namespace shim {
const hci_t* hci_layer_get_interface();
}  // namespace shim
}  // namespace bluetooth
// 定义在这里,具体是现在 system/bt/main/shim/hci_layer.cc


const hci_t* bluetooth::legacy::hci_layer_get_interface() {    // 3
  buffer_allocator = buffer_allocator_get_interface();
  btsnoop = btsnoop_get_interface();
  packet_fragmenter = packet_fragmenter_get_interface();

  init_layer_interface();                                     // 4

  return &interface;
}


static void init_layer_interface() {                          // 5
  if (!interface_created) {
    interface.set_data_cb = set_data_cb;
    interface.transmit_command = transmit_command;            // 6
    interface.transmit_command_futured = transmit_command_futured;
    interface.transmit_downward = transmit_downward;
    interface_created = true;
  }
}
  • 由于在 Android 11 上 默认没有启用 Gabeldorsche 协议栈,因此注释 // 1 处的函数返回值是 false,即执行注释 // 2 处的:bluetooth::legacy::hci_layer_get_interface()。
  • 注释 // 2 的实现于注释 // 3 处,执行了一个重要的注释 // 4 函数。
  • 注释 // 4 的实现于注释 // 5 处,执行了一个重要的赋值操作,即注释 // 6 处。

综合以上分析可知:

  1. 若设备的 Gabeldorsche 协议栈开启,那么执行 system/bt/main/shim/hci_layer.cc 源文件中的 transmit_command() 函数;
  2. 若设备的 Gabeldorsche 协议栈没有启用,那么执行 system/bt/hci/src/hci_layer.cc 源文件中的 transmit_command() 函数。 Android 11 执行此处

2.2 system/bt/hci/src/hci_layer.cc - initialization

2.2.1 hci_layer_get_interface()

system/bt/hci/src/hci_layer.cc

const hci_t* hci_layer_get_interface() {
  if (bluetooth::shim::is_gd_shim_enabled()) {
......
  } else {
    return bluetooth::legacy::hci_layer_get_interface();
  }
}


const hci_t* bluetooth::legacy::hci_layer_get_interface() {
  buffer_allocator = buffer_allocator_get_interface();
  btsnoop = btsnoop_get_interface();
  packet_fragmenter = packet_fragmenter_get_interface();    // 1

  init_layer_interface();

  return &interface;
}


// 仅初始化一次
static void init_layer_interface() {
  if (!interface_created) {
    interface.set_data_cb = set_data_cb;
    interface.transmit_command = transmit_command;
    interface.transmit_command_futured = transmit_command_futured;
    interface.transmit_downward = transmit_downward;
    interface_created = true;
  }
}

以上代码在 2.1 中分析了一部分,不再赘述,仅分析注释 // 1 处的函数 packet_fragmenter_get_interface()

system/bt/hci/src/packet_fragmenter.cc

const packet_fragmenter_t* packet_fragmenter_get_interface() {
  controller = controller_get_interface();
  buffer_allocator = buffer_allocator_get_interface();
  return &interface;
}



static const packet_fragmenter_t interface = {init, cleanup,
                                              fragment_and_dispatch,
                                              reassemble_and_dispatch};

从以上源码可知:hci_layer.cc 获取到了 packet_fragmenter.cc 的函数入口。

2.2.2 hci_module_start_up()

system/bt/hci/src/hci_layer.cc

static future_t* hci_module_start_up(void) {

  command_credits = 1;
......
  hci_thread.StartUp();                                             // 1
  if (!hci_thread.IsRunning()) {.......}
  if (!hci_thread.EnableRealTimeScheduling()) {......}
......
  packet_fragmenter->init(&packet_fragmenter_callbacks);            // 2
......
  hci_thread.DoInThread(FROM_HERE, base::Bind(&hci_initialize));    // 3
......
}
// 1
static MessageLoopThread hci_thread("bt_hci_thread");

// 2
static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
    transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished};

// 3
extern void hci_initialize();
  1. 注释 // 1 处创建了名为 bt_hci_thread 的 HCI 工作线程;
  2. 注释 // 2 处初始化了 static const packet_fragmenter_t* packet_fragmenter,并传递了函数的数组,用于后续执行相应的代码时回调,该初始化函数 init() 将在 2.3 进行分析;
  3. 注释 // 3 处在 hci_thread 中执行了 hci_initialize() 初始化函数,该函数在 hci_layer_android.cc 中,在 2.4 分析。

2.3 system/bt/hci/src/packet_fragmenter.cc - initialization

在 2.2.2 中出现了 packet_fragmenter.cc 的初始化函数 init(),并传递了参数列表。

参数:
system/bt/hci/src/hci_layer.cc

static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
    transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished};

初始化函数:
system/bt/hci/src/packet_fragmenter.cc

static void init(const packet_fragmenter_callbacks_t* result_callbacks) {
  callbacks = result_callbacks;
}


static const packet_fragmenter_callbacks_t* callbacks;

system/bt/hci/include/packet_fragmenter.h

typedef struct {
  packet_fragmented_cb fragmented;
  packet_reassembled_cb reassembled;
  transmit_finished_cb transmit_finished;
} packet_fragmenter_callbacks_t;

那么 packet_fragmenter.cc 回调 hci_layer.cc 的函数的映射关系如下表,即在 packet_fragmenter.cc 中调用第一列的某个函数相当于调用 hci_layer.cc 中的第二列的对应函数。

system/bt/hci/src/packet_fragmenter.cc system/bt/hci/src/hci_layer.cc
fragmented transmit_fragment
reassembled dispatch_reassembled
transmit_finished fragmenter_transmit_finished

2.4 system/bt/hci/src/hci_layer_android.cc - initialization

system/bt/hci/src/hci_layer_android.cc

void hci_initialize() {

  btHci_1_1 = V1_1::IBluetoothHci::getService();

  if (btHci_1_1 != nullptr) {
    btHci = btHci_1_1;
  } else {
    btHci = V1_0::IBluetoothHci::getService();
  }

......

  {
    android::sp<V1_1::IBluetoothHciCallbacks> callbacks =
        new BluetoothHciCallbacks();
    if (btHci_1_1 != nullptr) {
      btHci_1_1->initialize_1_1(callbacks);
    } else {
      btHci->initialize(callbacks);
    }
  }
}

初始化 HCI 的 HIDL 接口、设置对应的回调函数,用于蓝牙协议栈与 Vendor 进程之间的双向通信。

3. Bluetooth send HCI CMD flow

3.1 常用的 HCI CMD 发送方法

system/bt/stack/btu/btu_hcif.cc

void btu_hcif_send_cmd_with_cb(const Location& posted_from, uint16_t opcode,
                               uint8_t* params, uint8_t params_len,
                               hci_cmd_cb cb) {
  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
  uint8_t* pp = (uint8_t*)(p + 1);

  p->len = HCIC_PREAMBLE_SIZE + params_len;
  p->offset = 0;

  UINT16_TO_STREAM(pp, opcode);
  UINT8_TO_STREAM(pp, params_len);
  if (params) {
    memcpy(pp, params, params_len);
  }

  btu_hcif_log_command_metrics(opcode, pp,
                               android::bluetooth::hci::STATUS_UNKNOWN, false);

  cmd_with_cb_data* cb_wrapper =
      (cmd_with_cb_data*)osi_malloc(sizeof(cmd_with_cb_data));

  cmd_with_cb_data_init(cb_wrapper);
  cb_wrapper->cb = std::move(cb);
  cb_wrapper->posted_from = posted_from;

  hci_layer_get_interface()->transmit_command(
      p, btu_hcif_command_complete_evt_with_cb,
      btu_hcif_command_status_evt_with_cb, (void*)cb_wrapper);
}
void btu_hcif_send_cmd(UNUSED_ATTR uint8_t 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 ||
      (opcode == HCI_BLE_RAND) || (opcode == HCI_BLE_ENCRYPT)) {
    vsc_callback = *((void**)(p_buf + 1));
  }

  // Skip parameter length before logging
  stream++;
  btu_hcif_log_command_metrics(opcode, stream,
                               android::bluetooth::hci::STATUS_UNKNOWN, false);

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

3.2 发送内容与回调内容的封装

system/bt/hci/src/hci_layer.cc

static void transmit_command(BT_HDR* command,
                             command_complete_cb complete_callback,
                             command_status_cb status_callback, void* context) {
  waiting_command_t* wait_entry = reinterpret_cast<waiting_command_t*>(
      osi_calloc(sizeof(waiting_command_t)));

  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;

  enqueue_command(wait_entry);
}

将参数封装到 waiting_command_t 结构体中,便于后续使用。

3.3 HCI CMD 立即执行与队列缓存执行

system/bt/hci/src/hci_layer.cc

static void enqueue_command(waiting_command_t* wait_entry) {

  base::Closure callback = base::Bind(&event_command_ready, wait_entry);  // 1

  std::lock_guard<std::mutex> command_credits_lock(command_credits_mutex);
  if (command_credits > 0) {
    if (!hci_thread.DoInThread(FROM_HERE, std::move(callback))) {        // 2
      // HCI Layer was shut down or not running
      buffer_allocator->free(wait_entry->command);
      osi_free(wait_entry);
      return;
    }
    command_credits--;
  } else {
    command_queue.push(std::move(callback));                             // 3
  }
}
  1. 注释 // 1 处,将函数 event_command_ready 和参数 wait_entry 构成一个 callback ,便于使用;
  2. 若 command_credits 符合条件,则立即在 hci_thread 中执行 callback;
  3. 若 command_credits 不符合条件,则将 callback 放到命令队列 command_queue 中,待后续执行。
3.3.1 队列缓存执行的路径

具体的从命令队列 command_queue 中取出并执行命令的函数如下:

system/bt/hci/src/hci_layer.cc

void process_command_credits(int credits) {
......
  command_credits = credits - get_num_waiting_commands();

  while (command_credits > 0 && !command_queue.empty()) {
    if (!hci_thread.DoInThread(FROM_HERE, std::move(command_queue.front()))) {  // 1
......
    }
    command_queue.pop();                                                        // 2
    command_credits--;
  }
}
  1. 注释 // 1 处,从命令队列 command_queue 获取头部 callback 元素进行执行;
  2. 注释 // 2 处,从命令队列 command_queue 移除成功执行的元素;
3.3.1.1 process_command_credits 的调用路径

system/bt/hci/src/hci_layer_android.cc

class BluetoothHciCallbacks : public V1_1::IBluetoothHciCallbacks {

  Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) override {
    BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, event);
    hci_event_received(FROM_HERE, packet);                        // 1
    return Void();
  }
}

system/bt/hci/src/hci_layer.cc

void hci_event_received(const base::Location& from_here, BT_HDR* packet) {
......
  if (!filter_incoming_event(packet)) {                          // 2
......
  }
}



static bool filter_incoming_event(BT_HDR* packet) {
......
  if (event_code == HCI_COMMAND_COMPLETE_EVT) {
......
    process_command_credits(credits);                          // 3.1
......
  } else if (event_code == HCI_COMMAND_STATUS_EVT) {
......
    process_command_credits(credits);                          // 3.2
......
  } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) {
......
  }
  return false;

intercepted:
......
  return true;
}

从以上注释 // 1、// 2 、// 3.1 、 // 3.2 可知,一个同步 HCI CMD 完成后或者异步 HCI CMD 的状态回复后,会检测是否执行队列中的下一条命令。

3.3.2 立即执行与缓存执行的总结
  1. 立即执行 event_command_ready;
  2. 在上一条 HCI CMD 执行完毕后或命令的状态回复之后,有机会执行下一条命令,即执行 event_command_ready。

3.4 hci_thread 中执行 HCI CMD 的发送

system/bt/hci/src/hci_layer.cc

static void event_command_ready(waiting_command_t* wait_entry) {
  {
    /// Move it to the list of commands awaiting response
    std::lock_guard<std::recursive_timed_mutex> lock(
        commands_pending_response_mutex);
    wait_entry->timestamp = std::chrono::steady_clock::now();
    list_append(commands_pending_response, wait_entry);
  }
  packet_fragmenter->fragment_and_dispatch(wait_entry->command);

  update_command_response_timer();
}

3.5 HCI CMD 的分包

system/bt/hci/src/packet_fragmenter.cc

static void fragment_and_dispatch(BT_HDR* packet) {
  CHECK(packet != NULL);

  uint16_t event = packet->event & MSG_EVT_MASK;

  if (event == MSG_STACK_TO_HC_HCI_ACL) {
    fragment_and_dispatch_acl(packet);
  } else if (event == MSG_STACK_TO_HC_HCI_ISO) {
    fragment_and_dispatch_iso(packet);
  } else {
    // 根据 system/bt/hci/src/hci_layer.cc # transmit_command() 的 MSG_STACK_TO_HC_HCI_CMD 可知:
    // HCI CMD 在此处执行,即命令不需要分包。
    callbacks->fragmented(packet, true);
  }
}
  1. ACL 和 ISO 数据需要执行分包;
  2. CMD 不需要分包;
  3. Host 向 Controller 发送的数据,在 Host 端不存在 event 类型。

根据 2.3 的回调函数映射表可知:callbacks->fragmented(packet, true) 执行的函数是
system/bt/hci/src/hci_layer.cc - transmit_fragment(...)

static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) {
......
  hci_transmit(packet);
......
}

3.6 调用 HIDL 接口发送 HCI CMD

system/bt/hci/src/hci_layer_android.cc

void hci_transmit(BT_HDR* packet) {
  HciPacket data;
  data.setToExternal(packet->data + packet->offset, packet->len);

  uint16_t event = packet->event & MSG_EVT_MASK;
  switch (event & MSG_EVT_MASK) {
    case MSG_STACK_TO_HC_HCI_CMD:
      btHci->sendHciCommand(data);
      break;
    case MSG_STACK_TO_HC_HCI_ACL:
      btHci->sendAclData(data);
      break;
    case MSG_STACK_TO_HC_HCI_SCO:
      btHci->sendScoData(data);
      break;
    case MSG_STACK_TO_HC_HCI_ISO:
      if (btHci_1_1 != nullptr) {
        btHci_1_1->sendIsoData(data);
      } else {
......
      }
      break;
    default:
......
      break;
  }
}

直接调用了 HIDL 接口,发送 HCI 的命令和不同类型的数据。

4. HCI CMD Callback flow

HCI CMD 发送后,Controller 会回复该命令状态的 Event,某些命令是异步处理,还会发送命令执行完成的Event。

接收来自 Controller 的 Event 由 hci_event_received() 函数进行分发,存在 filter_incoming_event() 函数,HCI CMD 发送时设置的回调函数,在该函数中分发。

system/bt/hci/src/hci_layer.cc

void hci_event_received(const base::Location& from_here, BT_HDR* packet) {
  btsnoop->capture(packet, true);

  if (!filter_incoming_event(packet)) {                                                  // 1
    send_data_upwards.Run(from_here, packet);                                            // 2
  }
}



static bool filter_incoming_event(BT_HDR* packet) {                                     // 3
  waiting_command_t* wait_entry = NULL;
......
  if (event_code == HCI_COMMAND_COMPLETE_EVT) {                                         // 4
......
    wait_entry = get_waiting_command(opcode);

    process_command_credits(credits);

    if (!wait_entry) {
......
    } else {
      update_command_response_timer();
      if (wait_entry->complete_callback) {
        wait_entry->complete_callback(packet, wait_entry->context);                     // 5
      } else if (wait_entry->complete_future) {
......
      }
    }

    goto intercepted;
  } else if (event_code == HCI_COMMAND_STATUS_EVT) {                                    // 6
......
    wait_entry = get_waiting_command(opcode);

    process_command_credits(credits);

    if (!wait_entry) {
......
    } else {
      update_command_response_timer();
      if (wait_entry->status_callback)
        wait_entry->status_callback(status, wait_entry->command, wait_entry->context);  // 7
    }

    goto intercepted;
  } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) {
......
  }

  return false;

intercepted:
......
  return true;
}
  1. hci_event_received() 是处理来自 Controller 的 EVENT 的必经之路,在此函数中根据不同的条件执行两个分支;
  2. 分支一: filter_incoming_event(),注释 // 1、// 3 处即为调用和实现;
    2.1. 注释 // 4 和 // 5 对应了 Host 收到来自之前 Host 发给 Controller 的命令执行完毕时,执行该回调;(4.1 介绍)
    2.2. 注释 // 6 和 // 7 对应了 Host 收到来自之前 Host 发给 Controller 的命令的执行状态的回复时,执行该回调;(4.2 介绍)
  3. 分支二:send_data_upwards.Run(from_here, packet),注释 // 2 处。(4.3 介绍)

4.1 btu_hcif_send_cmd_with_cb 的回调流程

发送命令时,自定义回调函数。

system/bt/stack/btu/btu_hcif.cc

void btu_hcif_send_cmd_with_cb(const base::Location& posted_from,
                               uint16_t opcode, uint8_t* params,
                               uint8_t params_len, hci_cmd_cb cb) {
......
  cb_wrapper->cb = std::move(cb);
......
  hci_layer_get_interface()->transmit_command(
      p, btu_hcif_command_complete_evt_with_cb,
      btu_hcif_command_status_evt_with_cb, (void*)cb_wrapper);
}

由发送命令可知,用户设置的回调函数是 hci_cmd_cb cb,即为 cb_wrapper->cb。

4.1.1 btu_hcif_command_complete_evt_with_cb

system/bt/stack/btu/btu_hcif.cc

static void btu_hcif_command_complete_evt_with_cb(BT_HDR* response,
                                                  void* context) {
  do_in_main_thread(FROM_HERE,
                    base::Bind(btu_hcif_command_complete_evt_with_cb_on_task,
                               response, context));
}



static void btu_hcif_command_complete_evt_with_cb_on_task(BT_HDR* event,
                                                          void* context) {
......
  cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)context;
......
  uint16_t param_len = static_cast<uint16_t>(event->len - 5);
  std::move(cb_wrapper->cb).Run(stream, param_len);                         // 1
......
}
  • 注释 // 1 处的代码执行了 cb_wrapper->cb,即执行了用户设置的回调函数。
4.1.2 btu_hcif_command_status_evt_with_cb

system/bt/stack/btu/btu_hcif.cc

static void btu_hcif_command_status_evt_with_cb(uint8_t status, BT_HDR* command,
                                                void* context) {
  do_in_main_thread(
      FROM_HERE, base::Bind(btu_hcif_command_status_evt_with_cb_on_task, status,
                            command, context));
}



static void btu_hcif_command_status_evt_with_cb_on_task(uint8_t status,
                                                        BT_HDR* event,
                                                        void* context) {
......
  cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)context;
  std::move(cb_wrapper->cb).Run(&status, sizeof(uint16_t));                   // 1
......
}
  • 注释 // 1 处的代码执行了 cb_wrapper->cb,即执行了用户设置的回调函数。

4.2 btu_hcif_send_cmd 的回调流程

发送命令时,不设置自定义的回调,则采用蓝牙协议栈的默认回调。
默认回调一般用于处理既定的流程。

4.2.1 btu_hcif_command_complete_evt

system/bt/stack/btu/btu_hcif.cc

static void btu_hcif_command_complete_evt(BT_HDR* response, void* context) {
  do_in_main_thread(FROM_HERE, base::Bind(btu_hcif_command_complete_evt_on_task,
                                          response, context));
}



static void btu_hcif_command_complete_evt_on_task(BT_HDR* event,
                                                  void* context) {
......
  uint16_t param_len = static_cast<uint16_t>(event->len - 5);
  btu_hcif_hdl_command_complete(opcode, stream, param_len, context);
......
}



static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p,
                                          uint16_t evt_len,
                                          void* p_cplt_cback) {
...... // 根据不同的事件,走不同的流程,不详述。
}
4.2.2 btu_hcif_command_status_evt

system/bt/stack/btu/btu_hcif.cc

static void btu_hcif_command_status_evt(uint8_t status, BT_HDR* command,
                                        void* context) {
  do_in_main_thread(FROM_HERE, base::Bind(btu_hcif_command_status_evt_on_task,
                                          status, command, context));
}



static void btu_hcif_command_status_evt_on_task(uint8_t status, BT_HDR* event,
                                                void* context) {
......
  btu_hcif_hdl_command_status(opcode, status, stream, context);
......
}



static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
                                        uint8_t* p_cmd,
                                        void* p_vsc_status_cback) {
...... // 根据不同的事件,走不同的流程,不详述。
}

4.3 send_data_upwards.Run(from_here, packet)

4.3.1 send_data_upwards - initialization

system/bt/main/bte_main.cc

void bte_main_boot_entry(void) {
......
  hci = hci_layer_get_interface();
......
  hci->set_data_cb(base::Bind(&post_to_main_message_loop));
......
}

system/bt/hci/src/hci_layer.cc

static void set_data_cb(
    base::Callback<void(const base::Location&, BT_HDR*)> send_data_cb) {
  send_data_upwards = std::move(send_data_cb);
}



static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards;

根据以上代码流程可知,执行 send_data_upwards 即为执行 post_to_main_message_loop。

4.3.2 post_to_main_message_loop 执行

system/bt/main/bte_main.cc

void post_to_main_message_loop(const base::Location& from_here, BT_HDR* p_msg) {
  if (do_in_main_thread(from_here, base::Bind(&btu_hci_msg_process, p_msg)) !=
      BT_STATUS_SUCCESS) {
......
  }
}

执行 post_to_main_message_loop() 相当于在 main 线程中执行 btu_hci_msg_process() 函数,如下。

system/bt/stack/btu/btu_task.cc

void btu_hci_msg_process(BT_HDR* p_msg) {
  /* Determine the input message type. */
  switch (p_msg->event & BT_EVT_MASK) {
    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:
      btm_route_sco_data(p_msg);
      break;

    case BT_EVT_TO_BTU_HCI_EVT:
      btu_hcif_process_event((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
      osi_free(p_msg);
      break;

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

    case BT_EVT_TO_BTU_HCI_ISO:
      // TODO: implement handler
      osi_free(p_msg);
      break;

    default:
      osi_free(p_msg);
      break;
  }
}

至此,蓝牙的 HCI CMD 发送流程和命令执行状态的回调流程结束。

相关文章

网友评论

      本文标题:Bluetooth Send HCI CMD

      本文链接:https://www.haomeiwen.com/subject/nyyeoltx.html