ANDROID的 BLUETOOTH 实现机制

  从 ANDROID3.0 开始BLUETOOTH  API 提供了对 Bluetooth profile协议的支持。目前 ANDROID4.0 API 提供了五种蓝牙无线接口规范(Bluetooth profile )的 支持 ,用来在设备之间提供蓝牙通讯实现特定功能:包括 Headset Hands-Free profile (实现蓝牙耳机功能), A2dp profile (第二代蓝牙声音设备协议,用来在蓝牙设备之间实现高质量的声音传输),InputDevice profile(实现蓝牙输入设备功能), Bluetooth  Panprofile (实现蓝牙个人局域网功能), BluetoothHealth profile(实现蓝牙健康设备规范,用来与支持蓝牙健康设备规范的设备进行蓝牙通讯)。另外还有 Bluetooth Pbapprofile (实现蓝牙电话本功能),但接口和其它profile 实现不一致

       ANDROIDBluetooth profile API的实现主要采用了中介模式、代理模式及状态模式等。

      应用通过一个统一的类 BluetoothAdapter (蓝牙本地适配器类)与这些蓝牙设备协议对应的 BLUETOOTH  API 进行交互。

        BluetoothAdapter 也是所有蓝牙对象交互的入口。通过BluetoothAdapter 除了实现 BLUETOOTH profile API 的调用外,还提供发现其它蓝牙设备、查询配对成功的设备、使用已知的MAC 地址实例化蓝牙设备、创建一个 BluetoothServerSocket 对象来监听其它蓝牙设备以及根据地质实例化蓝牙设备等功能。因此几乎所有的蓝牙对象和所有的蓝牙服务都维护一个BluetoothAdapter 单例对象, BluetoothAdapter 单例对象通过 BluetoothAdapter 类提供的getDefaultAdapter 函数获得。 BluetoothAdapter 对象可以说是整个系统交互的中介,是中介设计模式的采用。

      而几个蓝牙设备协议的实现借助几个 ANDROID 服务来实现,并通过代理对象对外提供 BLUETOOTH  APIHeadset 对应的代理对象为 BluetoothHeadset A2dp 对应的代理对象为 BluetoothA2dp InputDevice profile对应的代理对象为 BluetoothInputDeviceBluetooth  Pan 对应的代理对象为BluetoothPanBluetooth Health 对应的代理对象为 BluetoothHealth

      通过 BluetoothAdapter 类提供的getProfileProxy 函数根据不同的 profile参数实例化对应的代理对象, getProfileProxy 函数还传给代理对象一个实现BluetoothProfile.ServiceListener 接口的监听对象。

      代理对象实例化时与代理的服务进行绑定,与服务进行绑定成功后调用对应监听对象的 onServiceConnected 回调函数,并通过回调函数把代理对象传给应用,应用通过代理对象通过 BINDER 访问蓝牙设备服务。

       Headset 对应蓝牙服务为BluetoothHeadsetServiceBluetoothHandsfree 对象, A2dp profile 对应的蓝牙服务为 BluetoothA2dpService ,而 InputDeviceprofile Bluetooth Healthprofile Bluetooth  Panprofile 都由BluetoothService 服务来实现。 Bluetooth Pbapprofile 对应的服务是 BluetoothPbapService

       BluetoothAdapter 对象相关类图如下:

      

        图中几个蓝牙服务 BluetoothHeadsetServiceBluetoothA2dpServiceBluetoothService BluetoothPbapService BluetoothDeviceProfileState BluetoothHandsfree BluetoothEventLoop对象都 维护一个 BluetoothAdapter 对象(使用 BluetoothAdapter 类提供的 getDefaultAdapter 函数获得),并通过 BluetoothAdapter 对象提供的getProfileProxy 函数根据 profile类型 获得要访问的代理对象,还通过 BluetoothAdapter 对象访问其它蓝牙对象。

       图中几个代理对象都是 BluetoothProfile 接口的实现,并都维护一个 ServiceListener 监听对象。BluetoothHeadset 对象通过 IBluetoothHeadset BluetoothHeadsetService 服务进行BINDER 调用, BluetoothA2dp 对象通过 IBluetoothA2dpBluetoothA2dpService 服务进行 BINDER 调用,而 BluetoothInputDeviceBluetoothPanBluetoothHealth 对象通过 IBluetooth 调用BluetoothService API

       代理对象本身及 BluetoothAudioGateway 对象也可以通过 BluetoothAdapter 对象访问其它蓝牙对象来获得蓝牙设备信息和状态。

        BluetoothAdapter 对象提供的接口除了getProfileProxy 外主要有以下几个:

        getRemoteDevice()  获得远端设备,返回一个BluetoothDevice 对象;

        getBondedDevices()  获得已配对设备,返回绑定(配对)到本地蓝牙的BluetoothDevice 对象集合;

        getState()    获得本地蓝牙的当前状态,包括STATE_ONSTATE_OFF STATE_TURNING_ONSTATE_TURNING_OFF 四种状态,由 BluetoothAdapterStateMachine 状态机进行维护

        isEnabled()   返回当前蓝牙是否可用状态,和getState()==STATE_ON 对应。

        enable()     打开本地蓝牙

        disable()     关闭本地蓝牙

        getUuids()  返回本地蓝牙支持的UUIDs 数组

        isDiscovering()   本地蓝牙当前正处于蓝牙设备发现过程

        cancelDiscovery()  取消当前蓝牙设备发现过程

         另外还提供创建 RfcommSocket 监听通道的 API

        BluetoothAdapter 对象通过六个API 来创建 RfcommSocket 数据连接监听通道 ( 三个使用固定端口三个使用随机端口) 及一个 SCO 监听通道(面向连接方式,主要用于话音传输)。三个创建使用固定端口的监听通道 API :一个用来创建需要认证和加密的使用固定 socket 端口的API (需要 BLUETOOTH_ADMIN 权限许可);一个用来创建不加密不认证的透明固定端口的 RFCOMMSocket API ;一个用来创建加密不认证的固定端口的 RFCOMMSocket API 。三个创建使用随机端口的监听RfcommSocket 通道 API (一个创建加密认证通道、一个创建透明通道、一个创建加密无认证通道),随机端口的产生由 BluetoothAdapter 的内部对象 RfcommChannelPicker 负责产生。

       对于蓝牙服务端,可以调用 BluetoothAdapter 对象的这些 API 来创建一个 BluetoothServerSocket 对象,初始化一个服务端 RfcommSocket 监听通道,并调用BluetoothServerSocket 对象的 accept 函数接收对方连接(实际调用刚实例化的监听 RfcommSocketaccept 函数)。当成功与对方建立连接后, BluetoothServerSocket 对象的 accept 函数返回一个新RfcommSocket 通道,用来作为设备之间的数据传输的通讯通道。

       每个 RfcommSocket 通道对应一个BluetoothSocket 对象。 BluetoothServerSocket 对象实例化时根据 BluetoothServerSocket 实例化函数传进来的通道socket 类型、是否需要认证对方设备、连接是否加密、远端 socket 端口等参数来实例化一个 BluetoothSocket 对象,socket 端口参数为空时使用产生的随机端口。实例化 BluetoothSocket 对象时使用的 socket 端口值为1 30 之间的数,但10 1112 19 四个保留端口留给其它Profile 使用。

       BluetoothSocket 对象的实例化函数中还实例化了一个 BluetoothInputStream 对象和BluetoothOutputStream 对象,用作交换数据使用。

       BluetoothSocket 对象还可以由蓝牙客户端设备来实例化,即由BluetoothDevice 对象来实例化。每个 BluetoothDevice 对象对应一个远端蓝牙设备。 BluetoothDevice 对象使用BluetoothSocket 对象向蓝牙服务端请求连接。通过 BluetoothSocket 对象还可以查询远端蓝牙设备的信息如设备名、 MAC 地址、绑定状态、蓝牙类型等。

       BluetoothDevice 对象提供了四个创建RfcommSocket 的函数(两个用于创建安全连接,两个用于创建透明连接,而两个安全连接和两个透明连接中一个通过SDP 设备发现功能产生的随机 socket 端口,一个使用固定 socket 端口)   及一个创建 SCO socket (用于话音传输)的函数 createScoSocketcreateScoSocket 及创建透明固定socket 端口的 API 的使用需要 BLUETOOTH_ADMIN 权限许可。设备发现功能的实现由SdpHelper 对象来实现。

       下图是 BluetoothService相关类图:

     

    

      BluetoothService服务采用三个 ProfileHandler对象提供相关 Profile API的服务。 BluetoothPanProfileHandler用于 Bluetooth PanProfile BluetoothInputProfileHandler 用于 Bluetooth InputDevice Profile BluetoothHealthProfileHandler 用于 Bluetooth HealthProfile

      三个 ProfileHandler对象通过父对象 BluetoothService与其它蓝牙对象交互。 三个 ProfileHandler对象本身都有一个以 BluetoothDevice 对象为keyHashMap 以维护已连接设备状态。

        BluetoothPanProfileHandl 对象还通过ConnectivityManagerINetworkManagementService BluetoothTetheringDataTracker 三个对象和接口与数据连接服务交互实现蓝牙连接共享功能。数据连接服务机制见博主的另一篇博文《第十一篇 ANDROID系统网络连接和管理机制 》。

        BluetoothHealthProfileHandler 使用BluetoothHealthAppConfiguration 对象指示一个登记用来与医疗蓝牙设备通讯和接收健康蓝牙设备发来的数据的对象,也称为sink 角色,与 sink 通讯的健康蓝牙设备称为 Source

      应用通过调用 BluetoothHealth 代理对象的 registerSinkAppConfiguration 函数在 BluetoothHealthProfileHandler 对象中登记一个BluetoothHealthAppConfiguration 对象。

      应用使用 BluetoothHealth 代理对象的connectChannelToSourceconnectChannelToSink 函数实现 sinkSource 的连接。

        BluetoothHealthProfileHandler使用 IBluetoothHealthCallback回调接口 通过 BluetoothHealth 代理对象向 应用发送事件通知。

       BluetoothService服务还包括几个状态机对象 ,采用了状态设计模式。

       一个 BluetoothAdapterStateMachine 状态机 ,处理和 维护本地蓝牙的状态 事件,包括 BluetoothOn Switching HotOffWarmUp PowerOff PerProcessState 等几个状态对象,初始状态为 PowerOff BluetoothAdapterStateMachine 状态机 通过IBluetoothStateChangeCallback 接口 BluetoothAdapter 对象通知本地蓝牙的状态。

       在 PowerOff 状态接收到 BluetoothService 服务发来的 USER_TURN_ON 消息时(由应用调用 BluetoothAdapter 对象的enable 函数触发)完成本地蓝牙模块和固件的加载,还启动一个BluetoothEventLoop 对象,通过 JNI 启动一个线程接收本地蓝牙模块bluez 产生的蓝牙信号。

        两个 BluetoothProfileState 状态机 ,其中 一个维护A2dp Profile 连接状态 的管理, 另外 一个维护 Health Profile连接 状态 的管理。

        还有 一个以蓝牙设备地址为 key BluetoothDeviceProfileState状态机 HashMap集合 为每个已配对远程设备提供一个相关的 BluetoothDeviceProfileState状态机,用来跟踪所有的蓝牙 Profile的输入输出连接。

          InputDevice profile 连接 状态的管理由 BluetoothInputProfileHandler对象提供的一个 状态机对象进行 维护。

转自“ http://www.tuicool.com/articles/Evaqmi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值