蓝牙应用通过 Binder 与蓝牙进程进行通信。蓝牙进程使用 JNI 与蓝牙堆栈通信,并向开发者提供对各种蓝牙配置文件的访问权限。下图显示了蓝牙堆栈的常规结构:

处于应用框架级别的是应用代码,它使用 android.bluetooth API 与蓝牙硬件进行交互。此代码在内部通过 Binder IPC 机制调用蓝牙进程。
蓝牙系统服务(位于 packages/apps/Bluetooth 中)被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。此应用通过 JNI 调用原生蓝牙堆栈。
与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用蓝牙堆栈。
AOSP 中提供了默认蓝牙堆栈(位于 system/bt 中)。该堆栈实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义。
供应商设备使用硬件接口设计语言 (HIDL) 与蓝牙堆栈交互
HIDL 定义了蓝牙堆栈和供应商实现之间的接口。如需生成蓝牙 HIDL 文件,请将蓝牙接口文件传入 HIDL 生成工具中。接口文件位于 hardware/interfaces/bluetooth 中。
Android 蓝牙堆栈是一个完全限定的蓝牙堆栈。限定列表位于蓝牙 SIG 网站上的 QDID 169365 下。
核心蓝牙堆栈位于 [system/bt](https://android.googlesource.com/platform/system/bt/+/master) 中。开发工作在 AOSP 中进行,欢迎贡献内容。
Android蓝牙协议栈的实现在system/bt目录
以下类和接口 是为APP 提供的API,在API内部通过Binder 机制向下调用
Interfaces
| BluetoothAdapter.LeScanCallback | Callback interface used to deliver LE scan results. |
| BluetoothProfile | Public APIs for the Bluetooth Profiles. |
| BluetoothProfile.ServiceListener | An interface for notifying BluetoothProfile IPC clients when they have been connected or disconnected to the service. |
Class
| BluetoothA2dp | This class provides the public APIs to control the Bluetooth A2DP profile. |
| BluetoothAdapter | Represents the local device Bluetooth adapter. |
| BluetoothAssignedNumbers | Bluetooth Assigned Numbers. |
| ... | ... |
代码位置:/aosp/packages/apps/Bluetooth/ ,这个文件夹中的代码实现了蓝牙服务和配置文件,并且最后编译时打包成一个APP,这个APP通过JNI调用蓝牙堆栈

"Bluetooth" 应用程序调用的JNI 位于/aosp/packages/apps/Bluetooth/jni 中。

JNI 负责调用原生的蓝牙协议栈。
蓝牙堆栈代码位于/aosp/system/bt 中
这层的代码通过调用hal 层代码 来调用底层硬件

因此厂商就可以通过HIDL 接口 来对接自己的硬件设备。
hidl 接口代码位于/hardware/interfaces/bluetooth
我们就可以按照HIDL 实现自己的接口了
已经集成到aosp源码中的厂商蓝牙代码定义在/aosp/hardware中




以瑞昱(realtek)为例
对于蓝牙厂商来说必须提供一个名字为 libbt-vendor.so的库文件,这个文件的接口在
/aosp/hareware/interfaces/bluetooth/1.0/default/bt_vendor_lib.h中定义好了,aosp 并没有实现,需要厂商提供这个文件的实现方法。

bt_vendor_lib.h源码:
#ifndef BT_VENDOR_LIB_H
#define BT_VENDOR_LIB_H
#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Struct types */
/** Typedefs and defines */
/** Vendor specific operations OPCODE */
typedef enum {
/* [operation]
* Power on or off the BT Controller.
* [input param]
* A pointer to int type with content of bt_vendor_power_state_t.
* Typecasting conversion: (int *) param.
* [return]
* 0 - default, don't care.
* [callback]
* None.
*/
BT_VND_OP_POWER_CTRL,
...
} bt_vendor_opcode_t;
...
/** Define HCI channel identifier in the file descriptors array
used in BT_VND_OP_USERIAL_OPEN operation.
*/
typedef enum {
CH_CMD, // HCI Command channel
CH_EVT, // HCI Event channel
CH_ACL_OUT, // HCI ACL downstream channel
CH_ACL_IN, // HCI ACL upstream channel
CH_MAX // Total channels
} bt_vendor_hci_channels_t;
...
/*
* Bluetooth Host/Controller Vendor callback structure.
*/
/* vendor initialization/configuration callback */
typedef void (*cfg_result_cb)(bt_vendor_op_result_t result);
/* datapath buffer allocation callback (callout)
*
* Vendor lib needs to request a buffer through the alloc callout function
* from HCI lib if the buffer is for constructing a HCI Command packet which
* will be sent through xmit_cb to BT Controller.
*
* For each buffer allocation, the requested size needs to be big enough to
* accommodate the below header plus a complete HCI packet --
* typedef struct
* {
* uint16_t event;
* uint16_t len;
* uint16_t offset;
* uint16_t layer_specific;
* } HC_BT_HDR;
*
* HCI lib returns a pointer to the buffer where Vendor lib should use to
* construct a HCI command packet as below format:
*
* --------------------------------------------
* | HC_BT_HDR | HCI command |
* --------------------------------------------
* where
* HC_BT_HDR.event = 0x2000;
* HC_BT_HDR.len = Length of HCI command;
* HC_BT_HDR.offset = 0;
* HC_BT_HDR.layer_specific = 0;
*
* For example, a HCI_RESET Command will be formed as
* ------------------------
* | HC_BT_HDR |03|0c|00|
* ------------------------
* with
* HC_BT_HDR.event = 0x2000;
* HC_BT_HDR.len = 3;
* HC_BT_HDR.offset = 0;
* HC_BT_HDR.layer_specific = 0;
*/
typedef void* (*malloc_cb)(int size);
typedef void (*mdealloc_cb)(void* p_buf);
typedef void (*tINT_CMD_CBACK)(void* p_mem);
...
/*
* Bluetooth Host/Controller VENDOR Interface
*/
typedef struct {
/** Set to sizeof(bt_vndor_interface_t) */
size_t size;
/*
* Functions need to be implemented in Vendor libray (libbt-vendor.so).
*/
/**
* Caller will open the interface and pass in the callback routines
* to the implemenation of this interface.
*/
int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char* local_bdaddr);
/** Vendor specific operations */
int (*op)(bt_vendor_opcode_t opcode, void* param);
/** Closes the interface */
void (*cleanup)(void);
} bt_vendor_interface_t;

通过代码可以知道,厂商最终只需要实现
/* Entry point of DLib --
* Vendor library needs to implement the body of bt_vendor_interface_t
* structure and uses the below name as the variable name. HCI library
* will use this symbol name to get address of the object through the
* dlsym call.
*/
extern const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE;
通过这个结构体,蓝牙协议栈将厂商的实现的方法导入到协议栈内部。
bluetooth@1.0通过vendor_interface.cc 中“VendorInterface::Open ”函数加载 这个lib

运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da
我是一名决定学习Ruby和RubyonRails的ASP.NETMVC开发人员。我已经有所了解并在RoR上创建了一个网站。在ASP.NETMVC上开发,我一直使用三层架构:数据层、业务层和UI(或表示)层。尝试在RubyonRails应用程序中使用这种方法,我发现没有关于它的信息(或者也许我只是找不到它?)。也许有人可以建议我如何在RubyonRails上创建或使用三层架构?附言我使用ruby1.9.3和RubyonRails3.2.3。 最佳答案 我建议在制作RoR应用程序时遵循RubyonRails(RoR)风格。Rails
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标
网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.
一、机器人介绍 此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接
目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'
我想使用ruby-prof和JMeter分析Rails应用程序。我对分析特定Controller/操作/或模型方法的建议方法不感兴趣,我想分析完整堆栈,从上到下。所以我运行这样的东西:RAILS_ENV=productionruby-prof-fprof.outscript/server>/dev/null然后我在上面运行我的JMeter测试计划。然而,问题是使用CTRL+C或SIGKILL中断它也会在ruby-prof可以写入任何输出之前杀死它。如何在不中断ruby-prof的情况下停止mongrel服务器? 最佳答案