【蓝牙开发】Android Bluedroid 源码学习之对外接口设计

本文中进行的Bluedroid 源码学习是基于Android P(9) 进行.
对于bluedroid(system/bt)最终是以一个动态库(libbluetooth)的方式对外提供, 在Bluetooth APK中使用的时候是以动态的方式进行加载的

对外接口定义

在include/hardware/bluetooth.h中声明了bt_interface_t这种包含函数指针类型的结构体.

/** Represents the standard Bluetooth DM interface. */
typedef struct {
  /** set to sizeof(bt_interface_t) */
  size_t size;
  /**
   * Opens the interface and provides the callback routines
   * to the implemenation of this interface.
   */
  int (*init)(bt_callbacks_t* callbacks);
  }bt_interface_t;
  
  #define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"

在下面的代码中定义bt_interface_t类型的bluetoothInterface 并对其成员进行赋值.
btif/src/bluetooth.cc

/*****************************************************************************
 *
 *   BLUETOOTH HAL INTERFACE FUNCTIONS
 *
 ****************************************************************************/

static int init(bt_callbacks_t* callbacks) {
  LOG_INFO(LOG_TAG, "%s", __func__);

  if (interface_ready()) return BT_STATUS_DONE;

#ifdef BLUEDROID_DEBUG
  allocation_tracker_init();
#endif

  bt_hal_cbacks = callbacks;
  stack_manager_get_interface()->init_stack();
  btif_debug_init();
  return BT_STATUS_SUCCESS;
}

EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
    sizeof(bluetoothInterface),
    init,
   };

这里只是摘取了init这一接口的实现,
从这里可以看出以下两点:

  1. init 是外部需要调用的接口,但这里修饰为了static. 这里通过bluetoothInterface 这一结构体封装了对外的接口init
  2. 通过结构体函数指针的方式,一定的面向对象的思维,封装性

补充说明: “EXPORT_SYMBOL=attribute((visibility(“default”)))”

如何使用Bluedorid(system/bt)中对外的接口

上面的内容讲了接口的定义,那外部该怎么调用该接口呢?
在在 bt_core/src/hal_util.cc 中

int hal_util_load_bt_library(const bt_interface_t** interface) {
  const char* sym = BLUETOOTH_INTERFACE_STRING;
  bt_interface_t* itf = nullptr;

  // Always try to load the default Bluetooth stack on GN builds.
  void* handle = dlopen(BLUETOOTH_LIBRARY_NAME, RTLD_NOW);
  if (!handle) {
    const char* err_str = dlerror();
    LOG(ERROR) << __func__ << ": failed to load bluetooth library, error="
               << (err_str ? err_str : "error unknown");
    goto error;
  }

  // Get the address of the bt_interface_t.
  itf = (bt_interface_t*)dlsym(handle, sym);
  if (!itf) {
    LOG(ERROR) << __func__ << ": failed to load symbol from Bluetooth library "
               << sym;
    goto error;
  }

  // Success.
  LOG(INFO) << __func__ << " loaded HAL path=" << BLUETOOTH_LIBRARY_NAME
            << " btinterface=" << itf << " handle=" << handle;

  *interface = itf;
  return 0;

error:
  *interface = NULL;
  if (handle) dlclose(handle);

  return -EINVAL;
}

在上述代码中,通过dlopen和dlsym 将bluetoothInterface 这一结构体的地址载入内存,然后进行init等接口的调用.

在btcore/include/hal_util.h中,

#pragma once

#include <hardware/bluetooth.h>

// Loads the Bluetooth library. This function looks explicitly for
// libbluetooth.so and loads it.
int hal_util_load_bt_library(const bt_interface_t** interface);

补充说明: 这里需要注意的是: hal_util_load_bt_library 在Bluetooth APK中重新定义了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值