ANDROID的 BLUETOOTH 实现机制

来源:互联网 发布:linux 打开21端口 编辑:程序博客网 时间:2024/06/05 04:49
  从 ANDROID3.0 开始BLUETOOTH  API 提供了对Bluetooth profile协议的支持。目前 ANDROID4.0 API 提供了五种蓝牙无线接口规范(Bluetooth profile)的 支持 ,用来在设备之间提供蓝牙通讯实现特定功能:包括 HeadsetHands-Free profile(实现蓝牙耳机功能), A2dp profile(第二代蓝牙声音设备协议,用来在蓝牙设备之间实现高质量的声音传输),InputDeviceprofile(实现蓝牙输入设备功能), Bluetooth Panprofile(实现蓝牙个人局域网功能), BluetoothHealthprofile(实现蓝牙健康设备规范,用来与支持蓝牙健康设备规范的设备进行蓝牙通讯)。另外还有Bluetooth Pbapprofile(实现蓝牙电话本功能),但接口和其它profile实现不一致

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

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

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

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

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

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

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

       BluetoothAdapter 对象相关类图如下:

      

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

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

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

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

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

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

        getState()    获得本地蓝牙的当前状态,包括STATE_ONSTATE_OFFSTATE_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 端口值为130 之间的数,但10111219 四个保留端口留给其它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 PanProfileBluetoothInputProfileHandler用于 Bluetooth InputDeviceProfile BluetoothHealthProfileHandler 用于 Bluetooth HealthProfile

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

        BluetoothPanProfileHandl 对象还通过ConnectivityManagerINetworkManagementServiceBluetoothTetheringDataTracker 三个对象和接口与数据连接服务交互实现蓝牙连接共享功能。数据连接服务机制见博主的另一篇博文《第十一篇 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
原创粉丝点击