android 蓝牙的配对 安卓蓝牙hid

您所在的位置:网站首页 蓝牙配对密钥在哪修改 android 蓝牙的配对 安卓蓝牙hid

android 蓝牙的配对 安卓蓝牙hid

2023-06-28 12:22| 来源: 网络整理| 查看: 265

本文仅介绍扼要的流程,没有系统化介绍。

首先从system\bt\hci\src\hci_layer_android.cc文件的函数void hci_initialize() 开始初始化:

void hci_initialize() { LOG_INFO(LOG_TAG, "%s", __func__); btHci = IBluetoothHci::getService(); // If android.hardware.bluetooth* is not found, Bluetooth can not continue. CHECK(btHci != nullptr); auto death_link = btHci->linkToDeath(bluetoothHciDeathRecipient, 0); if (!death_link.isOk()) { LOG_ERROR(LOG_TAG, "%s: Unable to set the death recipient for the Bluetooth HAL", __func__); abort(); } LOG_INFO(LOG_TAG, "%s: IBluetoothHci::getService() returned %p (%s)", __func__, btHci.get(), (btHci->isRemote() ? "remote" : "local")); // Block allows allocation of a variable that might be bypassed by goto. { android::sp callbacks = new BluetoothHciCallbacks(); btHci->initialize(callbacks); } }

  从第4行的btHci = IBluetoothHci::getService();可以看到,先从HIDL层获取BluetoothHci的实际服务的接口。IBluetoothHci::getService()的实际实现在生成的文件android\hardware\bluetooth\1.0\BluetoothHciAll.cpp中。具体位置根据不同生成时的配置不用,可以在安卓编译的out目录中查找到该文件。该文件是由hidl-gen将hidl描述文件生成的中间编译c++文件,在编译时生成该文件。接下来看该函数的实现:

1 // static 2 ::android::sp IBluetoothHci::getService(const std::string &serviceName, const bool getStub) { 3 return ::android::hardware::details::getServiceInternal(serviceName, true, getStub); 4 }

 细心的朋友可能会问,前面hci_layer_android.cc中hci_initialize调用的明明没有参数,而这里的具体函数实现需要2个参数。这是因为该IBluetoothHci::getService的声明中提供了2个默认参数,分别是字符串“default”和布尔变量false。可以发现该实现中,调用了一个模板函数。具体模板函数的实现下面会作介绍。我们先关注BpHwBluetoothHci模板参数,该参数是哪里来的呢?该模板参数同样是由hidl-gen生成的中间c++代码文件android\hardware\bluetooth\1.0\BpHwBluetoothHci.h中定义的。具体实如下内容(需要提醒注意的是,这些代码是由hidl-gen工具生成的):

struct BpHwBluetoothHci : public ::android::hardware::BpInterface, public ::android::hardware::details::HidlInstrumentor { explicit BpHwBluetoothHci(const ::android::sp &_hidl_impl); typedef IBluetoothHci Pure; typedef android::hardware::details::bphw_tag _hidl_tag; virtual bool isRemote() const override { return true; } // Methods from ::android::hardware::bluetooth::V1_0::IBluetoothHci follow. static ::android::hardware::Return _hidl_initialize(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::sp& callback); static ::android::hardware::Return _hidl_sendHciCommand(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_vec& command); static ::android::hardware::Return _hidl_sendAclData(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_vec& data); static ::android::hardware::Return _hidl_sendScoData(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_vec& data); static ::android::hardware::Return _hidl_close(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor); // Methods from ::android::hardware::bluetooth::V1_0::IBluetoothHci follow. ::android::hardware::Return initialize(const ::android::sp& callback) override; ::android::hardware::Return sendHciCommand(const ::android::hardware::hidl_vec& command) override; ::android::hardware::Return sendAclData(const ::android::hardware::hidl_vec& data) override; ::android::hardware::Return sendScoData(const ::android::hardware::hidl_vec& data) override; ::android::hardware::Return close() override; // Methods from ::android::hidl::base::V1_0::IBase follow. ::android::hardware::Return interfaceChain(interfaceChain_cb _hidl_cb) override; ::android::hardware::Return debug(const ::android::hardware::hidl_handle& fd, const ::android::hardware::hidl_vec& options) override; ::android::hardware::Return interfaceDescriptor(interfaceDescriptor_cb _hidl_cb) override; ::android::hardware::Return getHashChain(getHashChain_cb _hidl_cb) override; ::android::hardware::Return setHALInstrumentation() override; ::android::hardware::Return linkToDeath(const ::android::sp& recipient, uint64_t cookie) override; ::android::hardware::Return ping() override; ::android::hardware::Return getDebugInfo(getDebugInfo_cb _hidl_cb) override; ::android::hardware::Return notifySyspropsChanged() override; ::android::hardware::Return unlinkToDeath(const ::android::sp& recipient) override; private: std::mutex _hidl_mMutex; std::vector _hidl_mDeathRecipients; };

  可以看到该实现类似于一个代理,它负责与实际的蓝牙芯片交互,并且对蓝牙协议栈提供服务,蓝牙协议栈与蓝牙芯片之间的收发数据皆经过它。

接下来调用的函数::android::hardware::details::getServiceInternal(serviceName, true, getStub)其实就在安卓源代码中的lib hidl部分了,在文件system\libhidl\transport\include\hidl\HidlTransportSupport.h中:

template sp getServiceInternal(const std::string& instance, bool retry, bool getStub) { using ::android::hidl::base::V1_0::IBase; sp base = getRawServiceInternal(IType::descriptor, instance, retry, getStub); if (base == nullptr) { return nullptr; } if (base->isRemote()) { // getRawServiceInternal guarantees we get the proper class return sp(new BpType(getOrCreateCachedBinder(base.get()))); } return IType::castFrom(base); }

  由以上的描述,可以看到这里调用时,第一个参数instance的值为“default”,第二个参数retry的值为true,第三个参数getStub的值为false。

这里需要分析sp base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);的调用。该调用直接决定了HIDL具体的实现的位置。IType::descriptor实际上是等同于IBluetoothHci::descriptor,这点比较明显,从上述代码定义就可以看到。具体取值来自 中间文件android\hardware\bluetooth\1.0\BluetoothHciAll.cpp中的const char* IBluetoothHci::descriptor("[email protected]::IBluetoothHci");getRawServiceInternal函数决定了是通过绑定式还是通过直通式与直接的蓝牙芯片进行交互。该函数实现较长,在文件system\libhidl\transport\ServiceManagement.cpp中。不过可以一步一步地分析:sp getRawServiceInternal(const std::string& descriptor, const std::string& instance, bool retry, bool getStub) { using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport; using ::android::hidl::manager::V1_0::IServiceManager; sp waiter; sp sm; Transport transport = Transport::EMPTY; //表示最终使用绑定式还是直通式HIDL。经过下面的判断,最终的值可能是HWBINDER,也可能是PASSTHROUGH。 if (kIsRecovery) { transport = Transport::PASSTHROUGH; } else { sm = defaultServiceManager1_1(); if (sm == nullptr) { ALOGE("getService: defaultServiceManager() is null"); return nullptr; } Return transportRet = sm->getTransport(descriptor, instance); if (!transportRet.isOk()) { ALOGE("getService: defaultServiceManager()->getTransport returns %s", transportRet.description().c_str()); return nullptr; } transport = transportRet; } const bool vintfHwbinder = (transport == Transport::HWBINDER); const bool vintfPassthru = (transport == Transport::PASSTHROUGH); #ifdef ENFORCE_VINTF_MANIFEST #ifdef LIBHIDL_TARGET_DEBUGGABLE const char* env = std::getenv("TREBLE_TESTING_OVERRIDE"); const bool trebleTestingOverride = env && !strcmp(env, "true"); const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride; #else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE const bool trebleTestingOverride = false; const bool vintfLegacy = false; #endif // LIBHIDL_TARGET_DEBUGGABLE #else // not ENFORCE_VINTF_MANIFEST const char* env = std::getenv("TREBLE_TESTING_OVERRIDE"); const bool trebleTestingOverride = env && !strcmp(env, "true"); const bool vintfLegacy = (transport == Transport::EMPTY); #endif // ENFORCE_VINTF_MANIFEST for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) { if (waiter == nullptr && tries > 0) { waiter = new Waiter(descriptor, instance, sm); } if (waiter != nullptr) { waiter->reset(); // don't reorder this -- see comments on reset() } Return ret = sm->get(descriptor, instance); if (!ret.isOk()) { ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.", ret.description().c_str(), descriptor.c_str(), instance.c_str()); break; } sp base = ret; if (base != nullptr) { Return canCastRet = details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */); if (canCastRet.isOk() && canCastRet) { if (waiter != nullptr) { waiter->done(); } return base; // still needs to be wrapped by Bp class. } if (!handleCastError(canCastRet, descriptor, instance)) break; } // In case of legacy or we were not asked to retry, don't. if (vintfLegacy || !retry) break; if (waiter != nullptr) { ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str()); waiter->wait(true /* timeout */); } } if (waiter != nullptr) { waiter->done(); } if (getStub || vintfPassthru || vintfLegacy) { const sp pm = getPassthroughServiceManager();//该行仅拿到了一个ServiceManager的接口,不太重要。 if (pm != nullptr) { sp base = pm->get(descriptor, instance).withDefault(nullptr);//这里需要注意了因为sp是实际的蓝牙HIDL实现接口,需要研究如果通过pm->get拿到的。 if (!getStub || trebleTestingOverride) { base = wrapPassthrough(base); } return base;//返回直通式接口。我的安卓上面配置了直通式接口,因此接下来介绍直通式的流程。其实绑定式和直通式对安卓蓝牙协议栈来讲是一样的,不同之处已经由ServiceManagement.cpp帮忙屏蔽并且处理掉了。 } } return nullptr; }

  接下来分析sp base = pm->get(descriptor, instance).withDefault(nullptr);pm->get(...)调用的函数代码(文件system\libhidl\transport\ServiceManagement.cpp)为:

Return get(const hidl_string& fqName,//该值为“[email protected]::IBluetoothHci” const hidl_string& name) override { sp ret = nullptr; openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) { IBase* (*generator)(const char* name); *(void **)(&generator) = dlsym(handle, sym.c_str());//查找该so中的sym所代表的函数 if(!generator) { const char* error = dlerror(); LOG(ERROR)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3