【android bluetooth 协议分析 02】【bluetooth hal 层详解 3】【高通蓝牙hal主要流程介绍-上】

1. 背景

本节主要讨论 高通 蓝牙 hal 中,的一些流程。 看看你是否都清楚如下问题:

  1. 高通芯片电如何控制?
  2. 串口是在哪里控制的?
  3. 固件如何下载?
  4. 初始化流程是怎么样的?

如果你已经对上述讨论的问题,已经很清楚了,那你无需阅读该文章,请自行忽略。当然,也可以给笨叔挑挑错。 欢迎评论,一起探讨,毕竟都是笨叔自己的理解,难免有点出入,我也想进步!!!

在阅读这篇文章之前, 可以先阅读一下两篇文章。
【android bluetooth 框架分析 02】【Module详解 3】【HciHal 模块介绍】
【android bluetooth 协议分析 02】【bluetooth hal 层详解 2】【蓝牙hal层hidl_1.0和hidl_1.1层接口的区别是什么】

我们这里按照 hidl 1.0 接口讲解。1.1 类似。

2. bt server 触发流程

我们先来回顾一下,bt.server 是如何触发 hal 之间的通信的。

在 HciHal 模块的 Start 函数中,我们会去向 SM 获取 hal_1.0 服务, 并且调用 hal 的 initialize 接口

c 复制代码
  // system/gd/hal/hci_hal_android_hidl.cc
  
  void Start() override {
   
    std::string instance = GetHciInstance();

    if (bt_hci_1_1_ != nullptr) {
    } else {
      // 1. 向 SM 获取 IBluetoothHci_1_0 服务。
      bt_hci_ = IBluetoothHci_1_0::getService(instance);
    }

    LOG_INFO("GetService Done.");

    callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会调用我们的 接口

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

    // 3. 等待 hal initialize 执行完成。
    callbacks_->GetInitPromise()->get_future().wait();
  }

可以将上面 HciHal 模块的 Start 函数 总结为三步:

  1. 向 SM 找 bt hal 1.0 服务
  2. 调用 hal initialize
  3. 等待 hal initialize 完成

我们本节讨论的 蓝牙芯片上电,打开蓝牙串口, 固件下载。 都是在 这里调用 hal initialize 到 hal initialize 完成直接 进行的。

1. 向 SM 找 bt hal 1.0 服务

c 复制代码
std::string GetHciInstance() {
  char buf[64];
  int hci_adapter = InitFlags::GetAdapterIndex();
  // 0 -> "default" (default bluetooth adapter)
  // 1 -> "hci1" (new bluetooth adapter)
  if (hci_adapter > 0) {
    snprintf(buf, sizeof(buf), "hci%d", hci_adapter);
  } else {
    snprintf(buf, sizeof(buf), "default");
  }
  return std::string(buf);
}
  • 如果是 bt0 就找寻 android.hardware.bluetooth@1.0::IBluetoothHci/default 服务, 如果是 bt1 就找寻 android.hardware.bluetooth@1.0::IBluetoothHci/hci1 服务
c 复制代码
bt_hci_ = IBluetoothHci_1_0::getService(instance);
  • 通过 IBluetoothHci_1_0::getService 就能获取到 android.hardware.bluetooth@1.0::IBluetoothHci/default 服务。

2. 调用 hal initialize

c 复制代码
callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_); // hal进程,会调用我们的 接口

bt_hci_->initialize(callbacks_);
c 复制代码
class InternalHciCallbacks : public IBluetoothHciCallbacks {

};
  • InternalHciCallbacks 继承了 IBluetoothHciCallbacks。 hal 侧的回调就是调用到这里。
  • 通过 调用 hal 的 initialize 方法将 bt.server 的回调函数注册进 hal.

调用 hal 的 initialize 方法 , 将完成很多工作。 完成的工作将在 hal 侧详细介绍。我们这里先梳理流程。

当 hal 侧处理完 initialize 后, 会通知 bt.server.继续执行。

3. 等待 hal initialize 完成

c 复制代码
callbacks_->GetInitPromise()->get_future().wait();



  std::promise<void>* GetInitPromise() {
    return init_promise_;
  }
  • 通过 init_promise_ 实现等待。

我们看一下, hal 是如何通知我们的。

c 复制代码
class InternalHciCallbacks : public IBluetoothHciCallbacks {

  Return<void> initializationComplete(HidlStatus status) {
    common::StopWatch stop_watch(__func__);
    //ASSERT(status == HidlStatus::SUCCESS);
    if (status != HidlStatus::SUCCESS) {
      ALOGE("HidlStatus is not SUCCESS");
      exit(EXIT_FAILURE);
    }
    init_promise_->set_value();
    return Void();
  }


}

在第2步,我们将 InternalHciCallbacks 注册进了 hal 进程。 hal 在处理完成 initialize 后,会通过 initializationComplete 告知 .bt.server.

此时,这里的等待就会退出, 继续执行其他操作。

3. hal 侧逻辑

1. hal服务启动和注册

android 系统中 会在对应的 rc 文件中启动当前的 蓝牙hal

shell 复制代码
service vendor.bluetooth-1-0-xxxx /vendor/bin/hw/android.hardware.bluetooth@1.0-service-xxxx
    interface android.hardware.bluetooth@1.0::IBluetoothHci default
    class hal
    user bluetooth
    group bluetooth system wakelock oem_2901 net_raw oem_2912
    capabilities BLOCK_SUSPEND NET_ADMIN
c 复制代码
// hidl_hci/1.0/default/service.cpp

int main() {
    ALOGI("BT-Transport driver main");
    (void)umask(S_IWGRP | S_IWOTH);

    struct sched_param rt_params;
    rt_params.sched_priority = BT_TX_RT_PRIORITY;

    android::hardware::ProcessState::initWithMmapSize((size_t)(256144));

    configureRpcThreadpool(1, true /*callerWillJoin*/);

    ALOGI("isVendorEnhancedFramework: %d", isVendorEnhancedFramework);
    ALOGI("Registering BT Service");

    status_t status;

    status = registerBluetoothHci(); // 注册蓝牙服务

    if (status != OK)
      ALOGI("Error while registering BT service: %d", status);

    ALOGI("BTTPI: Main, joinRpcThreadpool for HIDL");
    joinRpcThreadpool();

    return status;
}

static status_t registerBluetoothHci()
{
    status_t status;
#ifdef DUAL_BT
    const char *bt_hci_instance = "hci1";
#else
    const char *bt_hci_instance = "default";
#endif

#ifdef LAZY_SERVICE
    status = registerLazyPassthroughServiceImplementation<IBluetoothHci>(bt_hci_instance);
#else
    status = registerPassthroughServiceImplementation<IBluetoothHci>(bt_hci_instance);
#endif

    return status;
}

我们当前的 hal 支持双蓝牙, 从 DUAL_BT 可以看出来,我们通过 编译来控制 编译两个不同的 bin. 用于 bt0 和 bt1.

在 registerBluetoothHci 函数中 当 registerPassthroughServiceImplementation<>() 被调用时:

  1. 框架在 libhidltransport.so 内部调用一个动态查找函数
  2. 它尝试在你的 HAL .so 中查找函数:

extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);

  1. 如果找到了,就调用它并返回 HAL 实例
c 复制代码
// hidl_hci/1.0/default/bluetooth_hci.cpp

IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name)
{
  ALOGI("%s ,new BluetoothHci() name:%s slot:%d", __func__, name, Util::getHwSlot());
  Util::init(name);
  return new BluetoothHci(Util::getHwSlot());
}

BluetoothHci 继承 IBluetoothHci 接口

c 复制代码
class BluetoothHci : public IBluetoothHci {
 public:
  BluetoothHci();
  BluetoothHci(int slot);
  ~BluetoothHci();
  Return<void> initialize(
      const ::android::sp<IBluetoothHciCallbacks>& cb) override;
  Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
  Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
  Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
  Return<void> close() override;
  Return<void> debug(const hidl_handle& handle,
                     const hidl_vec<hidl_string>& options) override;

 private:
  void sendDataToController(HciPacketType type, const hidl_vec<uint8_t>& data);
  void startDetectBluetooth(int slot);
  void stopDetectBluetooth();
  ::android::sp<IBluetoothHciCallbacks> event_cb_;
  ::android::sp<BluetoothDeathRecipient> deathRecipient;
  int hw_slot_;
  std::thread detect_bt_thread_;
};

extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
c 复制代码
// bt0 调用

01-13 02:03:20.629763   714   714 I vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: HIDL_FETCH_IBluetoothHci ,new BluetoothHci() name:default slot:0


// bt1 调用
01-13 02:03:20.630275   715   715 I vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: HIDL_FETCH_IBluetoothHci ,new BluetoothHci() name:hci1 slot:0
c 复制代码
// 此时 bt0 的服务就已经注册成功了。 bt.server 就可以 get 当前服务了。
01-13 02:03:20.641529   714   714 I HidlServiceManagement: Registered android.hardware.bluetooth@1.0::IBluetoothHci/default

2. initialize 调用

当 bt.server 调用 bt_hci_->initialize(callbacks_); 将调用到如下代码

c 复制代码
// hidl_hci/1.0/default/bluetooth_hci.cpp

Return<void> BluetoothHci::initialize(
  const ::android::sp<IBluetoothHciCallbacks>& cb)
{
  bool rc = false;

  ALOGW("BluetoothHci::initialize(), slot%d", hw_slot_);
  if (cb == nullptr) {
    ALOGE("%s: Received NULL callback from BT client", __func__);
    return Void();
  }
  ::android::sp<IBluetoothHciCallbacks> event_cb_tmp;
  event_cb_tmp = cb; // 将我们 bt.server 传递进来的 回调保存在 event_cb_tmp 中了。

   // 1. 调用 DataHandler::Init 方法
    rc = DataHandler::Init( TYPE_BT,
      [this, event_cb_tmp](bool status) {
        if (event_cb_tmp != nullptr) {
          ALOGI("%s: Set callbacks received from BT client inorder "
                 "to provide status and data through them", __func__);
          event_cb_ = event_cb_tmp;
        }
        if (event_cb_ != nullptr) {
          auto hidl_client_status = event_cb_->initializationComplete(
            status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
          if(!hidl_client_status.isOk()) {
            ALOGE("Client dead, callback initializationComplete failed");
          }
        }
      },
      [this, event_cb_tmp](HciPacketType type, const hidl_vec<uint8_t> *packet) {
        DataHandler *data_handler = DataHandler::Get();
        if (event_cb_tmp == nullptr) {
          ALOGE("BluetoothHci: event_cb_tmp is null");
          if (data_handler)
            data_handler->SetClientStatus(false, TYPE_BT);
          return;
        }
        /* Skip calling client callback when client is dead */
        if(data_handler && (data_handler->GetClientStatus(TYPE_BT) == false)) {
          ALOGI("%s: Skip calling client callback when client is dead", __func__);
          return;
        }
        Logger::Get()->UpdateRxTimeStamp();
        switch (type) {
          case HCI_PACKET_TYPE_EVENT:
          {
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_EVT_CALL_BACK);
#endif
            auto hidl_client_status = event_cb_tmp->hciEventReceived(*packet);
            if(!hidl_client_status.isOk()) {
              ALOGE("Client dead, callback hciEventReceived failed");
              if (data_handler)
                data_handler->SetClientStatus(false, TYPE_BT);
            }
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_POST_STACK_EVT_CALL_BACK);
#endif
          }
          break;
          case HCI_PACKET_TYPE_ACL_DATA:
          {
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_ACL_CALL_BACK);
#endif
            auto hidl_client_status = event_cb_tmp->aclDataReceived(*packet);
            if(!hidl_client_status.isOk()) {
              ALOGE("Client dead, callback aclDataReceived failed");
              if (data_handler)
                data_handler->SetClientStatus(false, TYPE_BT);
            }
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_POST_STACK_ACL_CALL_BACK);
#endif
          }
          break;
          default:
            ALOGE("%s Unexpected event type %d", __func__, type);
            break;
        }
      });


  if (!rc && (cb != nullptr)) {
     ...
  } else if (rc && (cb != nullptr)) {
     ALOGI("%s: linking to deathRecipient", __func__);
     cb->linkToDeath(deathRecipient, 0);
  }

  return Void();
}
c 复制代码
// BluetoothHci::initialize 函数调用开始
01-13 02:03:26.451268   714   714 W vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: BluetoothHci::initialize(), slot0

01-13 02:03:26.451326   714   714 W vendor.RunningAndroid.bluetooth@1.0-data_handler: DataHandler:: Init()
01-13 02:03:26.451454   714   714 I vendor.RunningAndroid.bluetooth@1.0-data_handler: data_service_setup_sighandler: Entry
01-13 02:03:26.451487   714   714 D vendor.RunningAndroid.bluetooth@1.0-data_handler: isProtocolAdded:
01-13 02:03:26.451498   714   714 I vendor.RunningAndroid.bluetooth@1.0-data_handler: isProtocolAdded: status:0
01-13 02:03:26.451507   714   714 I vendor.RunningAndroid.bluetooth@1.0-data_handler: Open init_status 0 
01-13 02:03:26.451897   714   714 D vendor.RunningAndroid.bluetooth@1.0-wake_lock: Init wakelock is initiated 

// BluetoothHci::initialize 函数调用退出
01-13 02:03:26.452016   714   714 I vendor.RunningAndroid.bluetooth@1.0-bluetooth_hci: initialize: linking to deathRecipient

在 BluetoothHci::initialize 中最主要就是调用 DataHandler::Init

1. DataHandler::Init

c 复制代码
// hidl_hci/1.0/default/data_handler.cpp
bool DataHandler::Init(ProtocolType type, InitializeCallback init_cb,
                       DataReadCallback data_read_cb)
{
  // lock required incase of multiple binder threads
  ALOGW("DataHandler:: Init()");
  std::unique_lock<std::mutex> guard(init_mutex_);
  Get();
  // 将上述两个回调 传入 他的 Open 函数
  return data_handler->Open(type, init_cb, data_read_cb);
}

DataHandler::Init 有两个回调 :

  1. InitializeCallback init_cb

  2. DataReadCallback data_read_cb

1. InitializeCallback init_cb

其中 InitializeCallback init_cb 传入的内容是:

c 复制代码
[this, event_cb_tmp](bool status) {
        if (event_cb_tmp != nullptr) {
          ALOGI("%s: Set callbacks received from BT client inorder "
                 "to provide status and data through them", __func__);
          event_cb_ = event_cb_tmp;
        }
        if (event_cb_ != nullptr) {
          auto hidl_client_status = event_cb_->initializationComplete(
            status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
          if(!hidl_client_status.isOk()) {
            ALOGE("Client dead, callback initializationComplete failed");
          }
        }
      }
2. DataReadCallback data_read_cb

DataReadCallback data_read_cb 传入的内容是:

c 复制代码
 
      [this, event_cb_tmp](HciPacketType type, const hidl_vec<uint8_t> *packet) {
        DataHandler *data_handler = DataHandler::Get();
        if (event_cb_tmp == nullptr) {
          ALOGE("BluetoothHci: event_cb_tmp is null");
          if (data_handler)
            data_handler->SetClientStatus(false, TYPE_BT);
          return;
        }
        /* Skip calling client callback when client is dead */
        if(data_handler && (data_handler->GetClientStatus(TYPE_BT) == false)) {
          ALOGI("%s: Skip calling client callback when client is dead", __func__);
          return;
        }
        Logger::Get()->UpdateRxTimeStamp();
        switch (type) {
          case HCI_PACKET_TYPE_EVENT:
          {
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_EVT_CALL_BACK);
#endif
            auto hidl_client_status = event_cb_tmp->hciEventReceived(*packet);
            if(!hidl_client_status.isOk()) {
              ALOGE("Client dead, callback hciEventReceived failed");
              if (data_handler)
                data_handler->SetClientStatus(false, TYPE_BT);
            }
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_POST_STACK_EVT_CALL_BACK);
#endif
          }
          break;
          case HCI_PACKET_TYPE_ACL_DATA:
          {
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_PRE_STACK_ACL_CALL_BACK);
#endif
            auto hidl_client_status = event_cb_tmp->aclDataReceived(*packet);
            if(!hidl_client_status.isOk()) {
              ALOGE("Client dead, callback aclDataReceived failed");
              if (data_handler)
                data_handler->SetClientStatus(false, TYPE_BT);
            }
#ifdef DUMP_RINGBUF_LOG
            Logger::Get()->UpdateRxEventTag(RX_POST_STACK_ACL_CALL_BACK);
#endif
          }
          break;
          default:
            ALOGE("%s Unexpected event type %d", __func__, type);
            break;
        }
      }

将上述两个回调 传入 他的 Open 函数

2. DataHandler::Open

c 复制代码
bool DataHandler::Open(ProtocolType type, InitializeCallback init_cb,
                       DataReadCallback data_read_cb)
{
  char dst_buff[MAX_BUFF_SIZE];
  char init_buff[MAX_BUFF_SIZE];
  struct timeval tv;
  std::map<ProtocolType, ProtocolCallbacksType *>::iterator it;
  std::unique_lock<std::mutex> guard(internal_mutex_);


  ALOGI("Open init_status %d \n", init_status_);


  // update the pending Init cb and other callbacks
  it = protocol_info_.find(type);
  if (it == protocol_info_.end()) {
    ProtocolCallbacksType *cb_data  = new (ProtocolCallbacksType);
    cb_data->type = type;
    cb_data->is_pending_init_cb = true;
    cb_data->init_cb = init_cb; // 将我们回调保存在 cb_data 中
    cb_data->data_read_cb = data_read_cb;
    protocol_info_[type] = cb_data;
  }
  switch (init_status_) { // 这里默认的 状态是 0: INIT_STATUS_IDLE
    ...
    case INIT_STATUS_IDLE:
      init_status_ = INIT_STATUS_INITIALIZING;
      break;
  }


  // 在这里 创建了一个 线程
  init_thread_ = std::thread(...);

  return true;
}

也就是说 bt.server 调用 initialize 函数后,hal 侧启动了一个线程 专门干这个事情。 initialize 函数就顺利返回了。

主要 initialize 的工作全部在 该线程中处理了。

3. 转门的线程处理 initialize 工作

线程处理函数如下:

c 复制代码
[this, type]() {


    // 1. 启动定时器
    StartInitTimer();

    if (!IsSocAlwaysOnEnabled()) {
        soc_need_reload_patch = true;
    }
    ALOGI("%s: soc_need_reload_patch = %d", __func__, soc_need_reload_patch); // 这里是1 

    if (soc_type_ == BT_SOC_SMD) {
    } else {
      // 2. 创建 UartController 对象
      controller_ = static_cast<Controller *> (new UartController(soc_type_));
    }

    if (controller_) {
      int retry_count = 0;
      // 进入循环 初始化。如果初始化失败,接着尝试
      while (retry_count < INIT_MAX_RETRY_TIMES) {
        // 3. 调用 controller_->Init 函数
        status = controller_->Init([this](ProtocolType ptype, HciPacketType type,
                                          const hidl_vec<uint8_t> *hidl_data)   {
                                     OnPacketReady(ptype, type, hidl_data);
                                   });
        if (status)
          break;
        ++retry_count;
      }
      
    }

    ...

	// 4. 初始化成功后 停止定时器
    StopInitTimer();
    std::unique_lock<std::mutex> guard(internal_mutex_);
    if (status) {
      /* Stop moving further if timeout detected */
      {
        guard.unlock();
        std::unique_lock<std::mutex> lock(DataHandler::init_timer_mutex_);
        if (GetInitTimerState() == TIMER_OVERFLOW) {
          ALOGW("Initialization timeout detected cleanup is in process");
          // Init thread exited.
          is_init_thread_killed = true;
          return;
        }
        guard.lock();
        init_status_ = INIT_STATUS_SUCCESS;
        ALOGD("Firmware download succeded.");
      }
    } else {
		...
    }

    std::map<ProtocolType, ProtocolCallbacksType *>::iterator it;
    for (auto& it: protocol_info_) {
      ProtocolCallbacksType *cb_data = (ProtocolCallbacksType*)it.second;
      cb_data->is_pending_init_cb = false;
      gettimeofday(&tv, NULL);
      snprintf(dst_buff, sizeof(dst_buff), "Init callback status = %d", status);
      BtState::Get()->AddLogTag(cb_status_buf, tv, dst_buff);
      BtState::Get()->SetTsStatusOfCbSent(cb_status_buf);
      // 5. 调用回调
      cb_data->init_cb(status); 
    }

    // clear the list if the controller open call fails
    if (!status) {
	    ...
    }
    guard.unlock();
    // BT ON successful
    property_set("persist.vendor.service.bdroid.system_delay_crash_count", "0");
    // Init thread exited.
    is_init_thread_killed = true;
    ALOGD("%s: init thread exited now", __func__);
  }

这个线程 主要做如下几件事情:

  1. 启动定时器
  2. 创建 UartController 对象
  3. 调用 controller_->Init 函数
  4. 初始化成功后 停止定时器
  5. 调用回调 init_cb

1. 启动定时器

启动定时器的目的是, 为了 防止 Controller 交互时, 无响应。 这里不是重点。暂时忽略。

2.创建 UartController 对象

c 复制代码
// hidl_hci/1.0/default/uart_controller.cpp

UartController::UartController(BluetoothSocType soc_type)
  : soc_crashed(false), soc_type_(soc_type),
  hci_packetizer_([this](hidl_vec<uint8_t> *data) { OnPacketReady(data); })
{
...
}

UartController 没有啥可以讲述的,一堆变量。暂时忽略

3. 调用 controller_->Init 函数

c 复制代码
bool UartController::Init(PacketReadCallback pkt_read_cb)
{

	power_manager_.Init(soc_type_);



  // 1. 给芯片 上电
  if (soc_need_reload_patch) {
    // power off the chip first
    power_manager_.SetPower(false);

    // power on the chip using power manager
    power_manager_.SetPower(true);
  }



  // 2. 初始化 HciTransport
  hci_transport_ = static_cast<HciTransport*> (uart_transport);
  ret = uart_transport->Init(soc_type_, soc_need_reload_patch);

  // 3. 创建 固件 补丁管理器
  patch_dl_manager = new (std::nothrow)PatchDLManager(soc_type_, uart_transport, &power_manager_);

  uart_transport->ClockOperation(USERIAL_OP_CLK_ON);



  //Download the NVM/RAM patch
  if (soc_need_reload_patch) {
    logger_->PropertyGet("vendor.wc_transport.skip_patch_dload", skip_patch_download, "false");
    if (strcmp(skip_patch_download, "true") != 0) {
      // 4. 开始打补丁, 下载固件
      if (patch_dl_manager->PerformChipInit() < 0) {
      }
      temp_add_on_features = patch_dl_manager->GetAddOnFeatureList();
    } else {}
  }


  // 获取 controller 的芯片版本, 做记录使用
  chipset_ver_ = patch_dl_manager->GetChipVersion();

  init_done_ = true;

  ALOGD("Init succeded");
  return init_done_;
}

由于篇幅原因,这里将于 下一篇,中讲解 这部分内容

4. 初始化成功后 停止定时器

这里不是重点。暂时忽略。

5. 调用回调 init_cb

当芯片上完电, 已经下载完固件后, 将调用 回调。

c 复制代码
cb_data->init_cb(status); 

这里将回调到 3.2.1.1 小节中的回调。

c 复制代码
[this, event_cb_tmp](bool status) {
        if (event_cb_tmp != nullptr) {
          ALOGI("%s: Set callbacks received from BT client inorder "
                 "to provide status and data through them", __func__);
          event_cb_ = event_cb_tmp;
        }
        if (event_cb_ != nullptr) {
          auto hidl_client_status = event_cb_->initializationComplete(
            status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
          if(!hidl_client_status.isOk()) {
            ALOGE("Client dead, callback initializationComplete failed");
          }
        }
      }
  • 最终会回调到 bt.server 中的 initializationComplete 函数。告知 bt.server 初始化成功。
相关推荐
每次的天空17 分钟前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭1 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日2 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安2 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑2 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟6 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡7 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi007 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil9 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你9 小时前
Android View的绘制原理详解
android