【android bluetooth 框架分析 02】【Module详解 3】【HciHal 模块介绍】

发布于:2025-04-17 ⋅ 阅读:(29) ⋅ 点赞:(0)

1. 背景

我们在 gd_shim_module 介绍章节中,看到 我们将 HciHal 模块加入到了 modules 中。

modules.add<hal::HciHal>();

在 ModuleRegistry::Start 函数中我们对 加入的所有 module 挨个初始化。
而在该函数中启动一个 module 都要执行那下面几步:

  1. 创建module 实体

    • Module* instance = module->ctor_();
  2. 将 当前 module 实体和 gd_stack_thread 线程绑定

    • set_registry_and_handler(instance, thread);
  3. 启动当前模块所依赖的所有子模块。

    • instance->ListDependencies(&instance->dependencies_);
    • Start(&instance->dependencies_, thread);
  4. 最后调用自己的 Start() 函数

    • instance->Start();
  5. 将module 实体加入到 started_modules_

    • started_modules_[module] = instance;

本篇文章就拿 hal::HciHal 模块来具体分析一下 他的启动。

2. modules.add

我们先来看一下 在调用 modules.add 时, 到底做了那些事情。

modules.add<hal::HciHal>();
class ModuleList {
 friend Module;
 friend ModuleRegistry;

public:
 template <class T>
 void add() {
   list_.push_back(&T::Factory); // add 时 添加的是 hal::HciHal::Factory
 }

 private:
  std::vector<const ModuleFactory*> list_;
};
  • 从代码中不难发现, 我们是将 hal::HciHal::Factory 加入到 list_ 中的。
// system/gd/hal/hci_hal_android_hidl.cc
const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHidl(); }); // 这里在创建 ModuleFactory 对象时, 传入了一个 函数, 这个函数 去 new HciHalHidl 对象
  • 这里在创建 ModuleFactory 对象时, 传入了一个 函数,但是并没有去调用这个函数。
    • 这个函数的目的是 去 new HciHalHidl 对象
class ModuleFactory {
 friend ModuleRegistry;
 friend FuzzTestModuleRegistry;

public:
 ModuleFactory(std::function<Module*()> ctor);

private:
 std::function<Module*()> ctor_;
};

//  system/gd/module.cc
ModuleFactory::ModuleFactory(std::function<Module*()> ctor) : ctor_(ctor) {
}
  • 在创建 ModuleFactory 对象时, 也仅仅是将 如下的函数赋值给了 ModuleFactory::ctor_ 函数指针。
[]() { 
	return new HciHalHidl(); 

}

3. 模块具体启动流程

1. 创建module 实体

  1. 创建module 实体
    • Module* instance = module->ctor_();
[]() { 
	return new HciHalHidl(); 

}


  • 这里就会去实际触发 该函数,去创建 HciHalHidl 对象。
  • 也就是说, modules.addhal::HciHal() 模块对应的 实体其实是 HciHalHidl对象。

class HciHalHidl : public HciHal {

}
  • HciHalHidl 继承 HciHal
class HciHal : public ::bluetooth::Module {

}
  • HciHal 又继承 Module

2. 将 当前 module 实体和 gd_stack_thread 线程绑定

  1. 将 当前 module 实体和 gd_stack_thread 线程绑定
    • set_registry_and_handler(instance, thread);
void ModuleRegistry::set_registry_and_handler(Module* instance, Thread* thread) const {
  instance->registry_ = this;
  instance->handler_ = new Handler(thread);
}
  • 将我们的 gd_stack_thread 对应的 handle 直接保存在 Module->handler_ 中。
Handler* Module::GetHandler() const {
  ASSERT_LOG(handler_ != nullptr, "Can't get handler when it's not started");
  return handler_;
}
  • 通过 Module::GetHandler() 来获取当前 handler_

3.启动当前模块所依赖的所有子模块

  1. 启动当前模块所依赖的所有子模块。
    • instance->ListDependencies(&instance->dependencies_);
    • Start(&instance->dependencies_, thread);
// system/gd/hal/hci_hal_android_hidl.cc
  void ListDependencies(ModuleList* list) const {
    list->add<SnoopLogger>();
    if (common::init_flags::btaa_hci_is_enabled()) {
      list->add<activity_attribution::ActivityAttribution>();
    }
  }
  • 这里调用了 HciHalHidl对象的ListDependencies , 这里会将 SnoopLogger 加入依赖, 通过log 发现, 这里也会去加载 activity_attribution::ActivityAttribution 模块
  • Btaa Module 就是 activity_attribution::ActivityAttribution 模块
01-10 01:47:11.567689  2008  2619 I BtGdModule: packages/modules/Bluetooth/system/gd/module.cc:86 Start: Starting of HciHalHidl
01-10 01:47:11.567995  2008  2619 I BtGdModule: packages/modules/Bluetooth/system/gd/module.cc:86 Start: Starting of SnoopLogger
01-10 01:47:11.568200  2008  2619 I BtGdModule: packages/modules/Bluetooth/system/gd/module.cc:86 Start: Starting of Btaa Module
01-10 01:47:11.569195  2008  2619 I BtGdModule: packages/modules/Bluetooth/system/gd/module.cc:105 Start: Started Btaa Module
01-10 01:47:11.570827  2008  2619 I bluetooth: packages/modules/Bluetooth/system/gd/hal/hci_hal_android_hidl.cc:229 Start: GetService start.
01-10 01:47:12.857871  2008  2619 I BtGdModule: packages/modules/Bluetooth/system/gd/module.cc:86 Start: Starting of Hci Layer

Start(&instance->dependencies_, thread);

  • 这里会先去启动 SnoopLogger 模块
  • 在去加载 Btaa Module

4. 最后调用自己的 Start() 函数

  1. 最后调用自己的 Start() 函数
    • instance->Start();
  // system/gd/hal/hci_hal_android_hidl.cc
  
  void Start() override {
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_ = GetDependency<activity_attribution::ActivityAttribution>();
    }
    btsnoop_logger_ = GetDependency<SnoopLogger>();
    LOG_INFO("GetService start.");

    // 这里 创建一个定时器, 此时将 gd_stack_thread 对应的 handle 传递给 了定时器
    auto get_service_alarm = new os::Alarm(GetHandler());

    // 定时器定时 1s, 如果超时,将跑在 gd_stack_thread 线程中
    get_service_alarm->Schedule(
        BindOnce([] {
          LOG_ALWAYS_FATAL("Unable to get a Bluetooth service after 500ms, start the HAL before starting Bluetooth");
        }),
        std::chrono::milliseconds(1000));


   // 向 SM 获取 IBluetoothHci_1_0 服务。
    std::string instance = GetHciInstance();

    bt_hci_1_1_ = IBluetoothHci::getService(instance);

    if (bt_hci_1_1_ != nullptr) {
      bt_hci_ = bt_hci_1_1_;
    } else {
      bt_hci_ = IBluetoothHci_1_0::getService(instance);
    }

    // 如果成功 向 SM获取hidl 服务, 就取消 之前的定时器,否则,1s超时后,报错,无法访问到 hidl 服务。
    get_service_alarm->Cancel();
    delete get_service_alarm;

    LOG_INFO("GetService Done.");


    // 向 蓝牙 hal 进程注册死亡回调
    ASSERT(bt_hci_ != nullptr);
    auto death_link = bt_hci_->linkToDeath(hci_death_recipient_, 0);
    ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
    callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会掉我们的 接口

    if (bt_hci_1_1_ != nullptr) {
      bt_hci_1_1_->initialize_1_1(callbacks_);
    } else {
      // 掉hal 接口, 触发 hal 初始化,将回调接口告知 hal进程。
      bt_hci_->initialize(callbacks_);
    }

    // Don't timeout here, time out at a higher layer
    callbacks_->GetInitPromise()->get_future().wait();
  }
  • callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会掉我们的 接口

1. InternalHciCallbacks

我们来看一下, 我们向 hal 进程, 注册的回调 长啥样子。

class InternalHciCallbacks : public IBluetoothHciCallbacks {


}
  • InternalHciCallbacks 继承 IBluetoothHciCallbacks 接口。
class InternalHciCallbacks : public IBluetoothHciCallbacks {
 public:
  InternalHciCallbacks(activity_attribution::ActivityAttribution* btaa_logger_, SnoopLogger* btsnoop_logger)
      : btaa_logger_(btaa_logger_), btsnoop_logger_(btsnoop_logger) {
    init_promise_ = new std::promise<void>();
  }

  void SetCallback(HciHalCallbacks* callback) {
    ASSERT(callback_ == nullptr && callback != nullptr);
    callback_ = callback;
  }

  void ResetCallback() {
    callback_ = nullptr;
  }

  std::promise<void>* GetInitPromise() {
    return init_promise_;
  }

  // 当 hal 初始化完后,会调用它,通知我们
  Return<void> initializationComplete(HidlStatus status) {
    common::StopWatch stop_watch(__func__);
    ASSERT(status == HidlStatus::SUCCESS);
    init_promise_->set_value();
    return Void();
  }


  // 当 收到 hci event 后, 会回调我们
  Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) override {
    common::StopWatch stop_watch(GetTimerText(__func__, event));
    std::vector<uint8_t> received_hci_packet(event.begin(), event.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::EVT);
    }
    if (callback_ != nullptr) {
      callback_->hciEventReceived(std::move(received_hci_packet));
    }
    return Void();
  }


 // 当收到  acl 数据后,会回调我们
  Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) override {
    common::StopWatch stop_watch(GetTimerText(__func__, data));
    std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::ACL);
    }
    if (callback_ != nullptr) {
      callback_->aclDataReceived(std::move(received_hci_packet));
    }
    return Void();
  }


  // 当收到 sco 语音数据,会回调给我们
  Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) override {
    common::StopWatch stop_watch(GetTimerText(__func__, data));
    std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::SCO);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::SCO);
    }
    if (callback_ != nullptr) {
      callback_->scoDataReceived(std::move(received_hci_packet));
    }
    return Void();
  }


  // 当收到 leaudio 数据 会回调我们
  Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) override {
    common::StopWatch stop_watch(GetTimerText(__func__, data));
    std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ISO);
    if (callback_ != nullptr) {
      callback_->isoDataReceived(std::move(received_hci_packet));
    }
    return Void();
  }

 private:
  std::promise<void>* init_promise_ = nullptr;
  HciHalCallbacks* callback_ = nullptr;
  activity_attribution::ActivityAttribution* btaa_logger_ = nullptr;
  SnoopLogger* btsnoop_logger_ = nullptr;
};

5.将module 实体加入到 started_modules_

  1. 将module 实体加入到 started_modules_
    • started_modules_[module] = instance;

4. HciHalHidl 模块其他接口介绍


// system/gd/hal/hci_hal_android_hidl.cc
class HciHalHidl : public HciHal {


public:
  void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
    callbacks_->SetCallback(callback);
  }

  void unregisterIncomingPacketCallback() override {
    callbacks_->ResetCallback();
  }

  void sendHciCommand(HciPacket command) override {
    btsnoop_logger_->Capture(command, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(command, SnoopLogger::PacketType::CMD);
    }
    bt_hci_->sendHciCommand(command);
  }

  void sendAclData(HciPacket packet) override {
    btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(packet, SnoopLogger::PacketType::ACL);
    }
    bt_hci_->sendAclData(packet);
  }

  void sendScoData(HciPacket packet) override {
    btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(packet, SnoopLogger::PacketType::SCO);
    }
    bt_hci_->sendScoData(packet);
  }

  void sendIsoData(HciPacket packet) override {
    if (bt_hci_1_1_ == nullptr) {
      LOG_ERROR("ISO is not supported in HAL v1.0");
      return;
    }

    btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ISO);
    bt_hci_1_1_->sendIsoData(packet);
  }
}

1.registerIncomingPacketCallback

  void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
    callbacks_->SetCallback(callback);
  }
  • 在之前分析 instance->Start(); 调用时有如下代码
    • callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会掉我们的 接口
    • bt_hci_->initialize(callbacks_); 将 InternalHciCallbacks 注册进 hal 进程

当 hal 进程中有 hci event 上报时, 先调用到 InternalHciCallbacks 的hciEventReceived, 从而触发 callback_->hciEventReceived(std::move(received_hci_packet));
而这里的 callback_ 就是通过 registerIncomingPacketCallback 调用 callbacks_->SetCallback(callback); 注册进来的。

  // system/gd/hal/hci_hal_android_hidl.cc
  void SetCallback(HciHalCallbacks* callback) {
    ASSERT(callback_ == nullptr && callback != nullptr);
    callback_ = callback;
  }
  // 当 收到 hci event 后, 会回调我们
  Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) override {
    common::StopWatch stop_watch(GetTimerText(__func__, event));
    std::vector<uint8_t> received_hci_packet(event.begin(), event.end());
    btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::EVT);
    }
    if (callback_ != nullptr) {
      callback_->hciEventReceived(std::move(received_hci_packet)); // 继续调用 hciEventReceived
    }
    return Void();
  }

那是谁调用的 registerIncomingPacketCallback

// system/gd/hci/hci_layer.cc
void HciLayer::Start() {

	hal_callbacks_ = new hal_callbacks(*this);

	hal->registerIncomingPacketCallback(hal_callbacks_);

}
  • 是在初始化 HciLayer 模块的 Start 函数中调用的。本机只分析 HciHal模块, HciLayer 模块在其他文章中分析。 这里不再展开分析。 只做记录。
// system/gd/hci/hci_layer.cc
struct HciLayer::hal_callbacks : public hal::HciHalCallbacks {
  hal_callbacks(HciLayer& module) : module_(module) {}

  void hciEventReceived(hal::HciPacket event_bytes) override {
    auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(event_bytes));
    EventView event = EventView::Create(packet);


	// 这里之前, 都是在Binder 线程池中执行的, 应为涉及到 跨进程间通信
	// 调用 module_.CallOn 将从 Binder线程, 的任务抛给 模块的线程处理, 这里就是  gd_stack_thread 线程
    module_.CallOn(module_.impl_, &impl::on_hci_event, move(event));
  }
};
// system/gd/module.h
  void CallOn(T* obj, Functor&& functor, Args&&... args) {
    GetHandler()->CallOn(obj, std::forward<Functor>(functor), std::forward<Args>(args)...);
  }


  • GetHandler() 返回的就是 gd_stack_thread 线程 对应的 handler

所以 最终 hal进程的回调, 先调用到 HciHal 模块的 callback , 最终在调用到 HciLayer::hal_callbacks。 这样逐级向上调用。

2. sendHciCommand

// system/gd/hci/hci_layer.cc
void send_next_command() {
	hal_->sendHciCommand(*bytes);
}


// system/gd/hal/hci_hal_android_hidl.cc
void sendHciCommand(HciPacket command) override {
    btsnoop_logger_->Capture(command, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
    if (common::init_flags::btaa_hci_is_enabled()) {
      btaa_logger_->Capture(command, SnoopLogger::PacketType::CMD);
    }
    bt_hci_->sendHciCommand(command);
  }
  • HciLayer::send_next_command 调用 HciHalHidl::sendHciCommand 通过 hal 接口 发送命令给 hal 进程。

3. sendAclData

  // HciLayer
  // system/gd/hci/hci_layer.cc
  void on_outbound_acl_ready() {
    auto packet = acl_queue_.GetDownEnd()->TryDequeue();
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendAclData(bytes); // 调用 HciHalHidl 层
  }

4. sendScoData

  // HciLayer
  // system/gd/hci/hci_layer.cc
  void on_outbound_sco_ready() {
    auto packet = sco_queue_.GetDownEnd()->TryDequeue();
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendScoData(bytes); // 调用 HciHalHidl 层
  }

5. sendIsoData

// HciLayer
// system/gd/hci/hci_layer.cc
void on_outbound_iso_ready() {
    auto packet = iso_queue_.GetDownEnd()->TryDequeue();
    std::vector<uint8_t> bytes;
    BitInserter bi(bytes);
    packet->Serialize(bi);
    hal_->sendIsoData(bytes); // 调用 HciHalHidl 层
  }

网站公告

今日签到

点亮在社区的每一天
去签到