android 蓝牙学习小记
- Android 蓝牙学习小记
- FTP与OPP协议
- 传统蓝牙服务端中常见协议列表
- BluetoothAdapter的getProfileProxy()
- 工作频段
- 蓝牙设备间的socket通信
- 两个层次的蓝牙协议
- 关于Bluetooth core profiles中的LMP协议
Android 蓝牙学习小记
这里面记录了一些开始学蓝牙是学到的一些小知识点,很零碎, 有的是自己总结,有的是从别的文章中摘抄的。
FTP与OPP协议
两个协议都是传文件的,但是两个协议传的文件有所不同。
- OPP协议传输特定格式的文件,在协议里定义了可以该协议可以接受哪些格式的文件,如下所示, 这些类型的文件接受到了后将按照文件的格式进行对应的解析。
/*** The MIME type(s) of we could accept from other device.* This is in essence a "white list" of acceptable types.* Today, restricted to images, audio, video and certain text types.*/public static final String[] ACCEPTABLE_SHARE_INBOUND_TYPES = new String[] {"image/*","video/*","audio/*","text/x-vcard","text/plain","text/html","text/xml","text/comma-separated-values","text/calendar","application/ogg","application/zip","application/vnd.ms-excel","application/msword","application/vnd.ms-powerpoint","application/pdf","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/x-hwp","application/vnd.android.package-archive",};
- 其它类型的文件就由FTP协议进程传输,标准的文件传送,如果你用FTP协议传 "text/x-vcard"类型的文件,接受端只认为传送过来的是一个文件,并将这个文件保存。
而不会将其解成一个名片。
传统蓝牙服务端中常见协议列表
A2DP: Advanced Audio Distribution Profile
AVRCP: A/V Remote Control Profile
FTP: File Transfer Profile
HDP: Health Device Profile
HFP: Hands-Free Profile
HID : Human Interface Device Profile
HSP :Headset Profile
MAP: Message Access Profile
OPP: Object Push Profile
PAN: Personal Area Networking Profile
PBAP: Phone Book Access Profile
SAP: SIM Access Profile
SPP: Serial Port Profile
详细内容请见蓝牙官网: https://www.bluetooth.com/specifications/profiles-overview
BluetoothAdapter的getProfileProxy()
- 使用getProfileProxy()方法来建立一个与配置相匹配的配置代理对象的连接。
- 创建一个BluetoothProfile.ServiceListener监听器,该监听器会在它们连接到服务器或中断与服务器的连接时,通知BluetoothProfile的IPC客户端。
- 在onServiceConnected()事件中,获得对配置代理对象的处理权;
- 一旦获得配置代理对象,就可以用它来监视连接的状态,并执行与配置有关的其他操作。
下面的getProfileProxy()的源码, 可以看到APP端通过该方法实例化了某个协议的代理,客户端通过listener可以得到这个代理对象,然后通过代理对象与协议通信。
这便是蓝牙里用到的中介与代理模式。
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,int profile) {if (context == null || listener == null) return false;if (profile == BluetoothProfile.HEADSET) {BluetoothHeadset headset = new BluetoothHeadset(context, listener);return true;} else if (profile == BluetoothProfile.A2DP) {BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);return true;} else if (profile == BluetoothProfile.A2DP_SINK) {BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener);return true;} else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);return true;} else if (profile == BluetoothProfile.INPUT_DEVICE) {BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);return true;} else if (profile == BluetoothProfile.PAN) {BluetoothPan pan = new BluetoothPan(context, listener);return true;} else if (profile == BluetoothProfile.DUN) {BluetoothDun dun = new BluetoothDun(context, listener);return true;} else if (profile == BluetoothProfile.HEALTH) {BluetoothHealth health = new BluetoothHealth(context, listener);return true;} else if (profile == BluetoothProfile.MAP) {BluetoothMap map = new BluetoothMap(context, listener);return true;} else if (profile == BluetoothProfile.HEADSET_CLIENT) {BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener);return true;} else if (profile == BluetoothProfile.SAP) {BluetoothSap sap = new BluetoothSap(context, listener);return true;} else if (profile == BluetoothProfile.PBAP_CLIENT) {BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener);return true;} else {return false;}}
工作频段
- 蓝牙电波使用2.4 ~ 2.48GHz的RF频段,进行语音和数据通信。
- 微波炉工作在2.4GHz频点,因为微波炉总有微波泄露,因此在微波炉旁使用蓝牙设备,将会阻挡蓝牙数据传输,或者消减蓝牙2/3以上的信息量。
- 2.4 — 2.48GHz(ISM 工业、科学、医疗),这一频段属工业和医疗频段,
- 无需申请无线电波使用许可证,方便在全世界推广使用.
Q
:由于很多设备都在这一频段里,会很拥挤,设备会互相干扰,会出现设备在线等待,降低数据传输速度?
A
:采用扩展频率调频技术。使用一个频率发送或接收了一个频率后,立即跳到了另一个频率,并不长期在一个频率上工作。蓝牙数据为了更为简便的传输,通常把它们折成很小的数据串,这一小串数据称为一个“分组”。蓝牙设备选择调频在信道上传送,发送器和接收器应当按相同的次序一起跳频,
蓝牙调频信道就是具有这一功能的无线信道,该功能依靠跳频序列和频率在序列中的位置来实现。而跳频序列有主单元的本地时钟来决定,主单元只要在发送数据同时,把自己的本地时钟传送给从单元,从单元就能与主单元一起同步跳频。
蓝牙设备间的socket通信
绑定后的蓝牙设备之间是可以建立Socket通信的,这种Socket类似于TCP Socket,但略有不同,该Socket只能通过调用Android API来获取并连接,但通信操作是与TCP相同的,可以获取InputStream以及OutputStream来实现数据的交互。在蓝牙规范中,有个SPP(全称Serial Port Profile) Profile,定义了如何在两台蓝牙设备之间建立虚拟串口并进行连接,顾名思义,就是来支持蓝牙设备之间的Socket通信。该Profile在蓝牙设备绑定之后便会连接,所以我们只需在蓝牙绑定成功后,通过调用相应的API,即可获取BluetoothSocket对象,在该对象中提供了”getInputStream”、”getOutputStream”来获取输入输出流,然后即可通过IO流来传输数据,实现设备通讯。
一般的,我们通过连接该Socket来实现手机控制智能设备的功能,但是Socket也仅仅只能用来数据通讯,要想实现免提电话、听音乐、外接键盘等功能,还是需要去连接对应的Profile。
两个层次的蓝牙协议
上图描述了蓝牙系统的组成, 我们需要注意如下特点:
-
图中所描述的蓝牙系统的组成部分,如Bluetooth Core和Bluetooth Application,如Host和Controller,都是指“逻辑实体”。所谓的“逻辑实体”,需要和日常生活中的“物理实体”区隔开。如在做电路设计时,一个蓝牙芯片、一个主控CPU,就是指物理实体。而蓝牙协议所描述的这些“逻辑实体”,不一定会和物理实体一一对应,如在实际应用中,Host和Bluetooth Application可能会位于同一个物理实体中(主控CPU),而Controller单独位于另一个物理实体中(蓝牙芯片)。
-
蓝牙协议规定了两个层次的协议,分别为蓝牙核心协议(Bluetooth Core)和蓝牙应用层协议(Bluetooth Application)。蓝牙核心协议关注对蓝牙核心技术的描述和规范,它只提供基础的机制,并不关心如何使用这些机制;蓝牙应用层协议,是在蓝牙核心协议的基础上,根据具体的应用需求,百花齐放,定义出各种各样的策略,如FTP、文件传输、局域网等等。
-
Bluetooth Core由两部分组成,Host和Controller。这两部分在不同的蓝牙技术中(BR/EDR、AMP、LE),承担角色略有不同,但大致的功能是相同的。Controller负责定义RF、Baseband等偏硬件的规范,并在这之上抽象出用于通信的逻辑链路(Logical Link);Host负责在逻辑链路的基础上,进行更为友好的封装,这样就可以屏蔽掉蓝牙技术的细节,让Bluetooth Application更为方便的使用。
-
在一个系统中,Host只有一个,但Controller可以一个,也可以有多个。如:单独的LE Controller;单独的BR/EDR Controller;单独的LE+BR/EDR Controller;在单独的BR/EDR Controller或LE+BR/EDR Controller基础上,增加一个或多个额外的AMP Controller。
注
摘自http://www.wowotech.net/bluetooth/bt_overview.html(谢谢这位作者,写得非常精辟且容易理解)
关于Bluetooth core profiles中的LMP协议
建立连接的两个设备分为Master和slave(发起方为Master,接收方为Slave)在一个physical channel, master和slave之间用时分的方式复用同一个physical channel,看起来像独自占用一个通道,这被称为Physical Link。
在Physical Link之上抽象出Logical Link,用来传输不同类型的数据,如同步数据,异步数据,多播数据,广播数据等,Logical Link通过占用不同时隙的方式复用Physical Link。
而LMP(Link management protocol)协议用来管理这些抽象出的Logical Link。
LMP之上又提供L2CAP层,从应用的角度复用Logical Link。L2CAP协议负责不同数据的封包和解包。
未完待续… …