http://www.w2bc.com/article/126068
一、蓝牙基础知识
1.蓝牙( Bluetooth )是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换。蓝牙基于设备低成本的收发器芯片,传输距离近、低功耗。
2.微波频段:使用2.402GGHz到2.480GHz(包括防护频带)的ISM波段的UHF无线电波
3.蓝牙使用跳频技术,将传输的数据分割成数据包,通过79个指定的蓝牙频道分别传输数据包。每个频道的频宽为1MHz。
4.蓝牙是基于数据包、有着主从架构的协议。一个主设备至多可和同一微微网中的七个从设备通讯。所有设备共享主设备的时钟。
5.蓝牙机器作为主设备的时候最多可与七个从设备连接。从设备一般只与一个主设备连接。设备之间可以通过协议转换角色。
6. 功率射程
类别 | 最大功率容量 | 射程范围 (m) | |
(mW) | (dBm) | ||
1 | 100 | 20 | ~100 |
2 | 2.5 | 4 | ~10 |
3 | 1 | 0 | ~1 |
7.数据吞吐量
版本 | 数据率 | 最大应用吞吐量 |
1.2 | 1Mbit/s | >80 kbit/s |
2.0 + EDR | 3 Mbit/s | >80 kbit/s |
3.0 + HS | 24 Mbit/s | 请参考3.0 + HS |
4.0 | 24 Mbit/s | 请参考4.0 LE |
7.关于射程:多数蓝牙应用是为室内环境而设计的,由于墙的衰减和信号反射造成的信号衰落会使得射程远小于蓝牙产品规定的射程范围。两个敏感度和发射功率都较高的1类设备相连接,射程可远高于一般水平的100m,取决于应用所需要的吞吐量。有些设备在开放的环境中的射程能够高达1km甚至更高。
8.最新版本:蓝牙4.2,发布于2014年12月2日(截止2016年3月22日)
9.每个设备都有一个唯一的48-位的地址。然而这些地址并不会显示于连接请求中。但是用户可自行为他的蓝牙设备命名(蓝牙设备名称),这一名称即可显示在其他设备的扫描结果和配对设备列表中。
10.蓝牙框架
11.蓝牙核心系统包括主机和控制器两部分,其中控制器包括主控制器和次控制器。
12.蓝牙基本规范
在蓝牙作用有四种基本规范(Profile),这些规范会被其它的规范使用。它们是:
(1)GAP Profile: Generic Access Profile,该Profile保证不同的Bluetooth产品可以互相发现对方并建立连接。
(2)SDAP Profile: Service Discovery Application Profile,通过该Profile,一个Bluetooth设备可以找到其它Bluetooth设备提供的服务,以及查询相关的信息。
(3)SPP Profile: Serial Port Profile,模拟串口通讯
(4)GOEP Profile: Generic Object Exchange Profile,通用对象交换。这个Profile的名字有些费解,它定义的是数据的传输,包括同步,文件传输,或者推送其它的数据。可以理解为内容无关的传输层协议,可以被任何应用用来传输自己定义的数据对象。
13.蓝牙应用规范
BR/EDR profile(Android支持)
(1)A2DP(Advanced Audio Distribution Profile)
高级音频、立体声规范,包括A2DP Sink和A2DP Source;
(2)AVRCP(Audio/Video Remote Control Profile)
音视频远程控制规范,音乐播放、暂停等;
(3)HFP(Hands-Free Profile)
免提规范,用于蓝牙通话;
(4)HSP(Headset Profile)
耳机规范,用于蓝牙耳机;
(5)HID(Human Interface Device Profile)
人体接口设备规范,分为HID Host和HID Device;
(6)OPP(Object Push Profile)
对象推送规范,用于传输文件;
(7)PAN(Personal Area Networking Profile)
个人局域网规范,蓝牙网络共享;
(8)PBAP(Phone Book Access Profile)
电话号码簿访问规范;
(9)MAP(Message Access Profile)
信息访问规范;
(10)HDP(Health Device Profile)
健康设备规范,和一些健康设备进行通信;
(11)BLP(Blood Pressure Profile)
血压规范;
(12)FMP(Find Me Profile)
找我规范;
(13)HRP(Heart Rate Profile)
心率规范;
(14)HOGP(HID Over GATT Profile)
基于GATT的HID规范;
(15)TIP(Time Profile)
时间规范。
二、硬件部分知识
1.基础处理器
(1)AP:ApplicationProcessor应用处理器
采用ARM架构的CPU,通常负责运行OS和一些特定设置和载入开机预设。比如一个没有电话功能的平板电脑,只跑android或者win8的系统,只要AP就可以。
(2)BP:BasebandProcessor 基带处理器
架构相对于AP简单,处理电话、信息之类的功能。
(3)CP:coprocessor Processor 协处理器
基带芯片加协处理器(CP,通常是多媒体加速器), 用来通过处理主cpu的一些工作负荷来使操作提速的辅助处理器。
(4)RF:Radio Frequency射频部分
无线信号的发射部分,如电话、蓝牙、WIFI信号发射、接收。
2.简单平板电脑结构框图
AP芯片+外设+Android系统
3.蓝牙硬件接口框图(以UART接口芯片为例)
(1)UART部分:串口,主要负责数据传输;
(2)PCM 部分:语音接口,用于通话时语音数据传输;
(3)Power部分:电源控制。
三、软件部分知识
1.Android Bluetooth Architecture蓝牙代码架构
1.1 串口驱动
Linux的内核的蓝牙驱动程、Linux的内核的蓝牙协议的层
1.2BlueZ的适配器
(1)内核代码:由驱动程序和BlueZ核心协议组成
驱动程序:实现在内核源代码kernel/driver/bluetooth中(包含Linuxkernel对各种接口的)包括:USBdriver、USB driver and Otherdriver。
Bluetooth协议:实现在内核源代码 kernel/net/bluetooth中。包括:hci、l2cap、hid、rfcomm、sco、SDP、BNEP等协议的实现。
(2)用户态程序及工具集:
包括应用程序接口和BlueZ工具集。BlueZ提供函数库以及应用程序接口,便于程序员开发bluetooth应用程序。BlueZ utils是主要工具集,实现对bluetooth设备的初始化和控制。
1.3 蓝牙相关的应用程序接口
Android.buletooth包中的各个Class(蓝牙在框架层的内容)
类名 | 作用 |
BluetoothAdapter | 本地蓝牙设备的适配类,所有的蓝牙操作都要通过该类完成 |
BluetoothClass | 用于描述远端设备的类型,特点等信息 |
BluetoothDevice | 蓝牙设备类,代表了蓝牙通讯过程中的远端设备 |
BluetoothServerSocket | 蓝牙设备服务端,类似ServerSocket |
BluetoothSocket | 蓝牙设备客户端,类似Socket |
BluetoothClass.Device | 蓝牙关于设备信息 |
BluetoothClass.Device.Major | 蓝牙设备管理 |
BluetoothClass.Service | 蓝牙相关服务 |
附:Google官方提供的蓝牙代码框架图
2.Hciattach:建立串口和蓝牙协议层的数据连接通道
3.数据传输流程
(1) uart口取得蓝牙模块的数据;
(2) uart口通过ldisc传给hci_uart;
(3) hci_uart传给在其上的h4;
(4) h4传给hci层;
(5) hci层传给l2cap层;
(6) l2cap层再传给rfcomm。
4.BluetoothAdapter:蓝牙适配器
直到我们建立bluetoothSocket连接之前,都要不断操作它。
BluetoothAdapter中的动作常量
ACTION_DISCOVERY_FINISHED | 已完成蓝牙搜索 |
ACTION_DISCOVERY_STARTED | 已经开始搜索蓝牙设备 |
ACTION_LOCAL_NAME_CHANGED | 更改蓝牙的名字 |
ACTION_REQUEST_DISCOVERABLE | 请求能够被搜索 |
ACTION_REQUEST_ENABLE | 请求启动蓝牙 |
ACTION_SCAN_MODE_CHANGED | 扫描模式已经改变 |
ACTION_STATE_CHANGED | 状态已改变 |
ACTION_CONNECTION_STATE_CHANGED |
|
5.常量介绍
(1)开关状态值
蓝牙关闭 : int STATE_OFF , 值为10, 蓝牙模块处于关闭状态;
蓝牙打开中 : int STATE_TURNING_ON , 值为11, 蓝牙模块正在打开;
蓝牙开启 : int STATE_ON , 值为12, 蓝牙模块处于开启状态;
蓝牙开启中 : int STATE_TURNING_OFF , 值为13, 蓝牙模块正在关闭;
蓝牙开关状态顺序 : STATE_OFF --> STATE_TURNING_ON --> STATE_ON -->STATE_TURNING_OFF --> STATE_OFF;
(2)扫描状态值
无功能状态 : int SCAN_MODE_NONE , 值为20, 查询扫描和页面扫描都失效, 该状态下蓝牙模块既不能扫描其它设备, 也不可见;
扫描状态 : int SCAN_MODE_CONNECTABLE , 值为21, 查询扫描失效, 页面扫描有效, 该状态下蓝牙模块可以扫描其它设备, 从可见性来说只对已配对的蓝牙设备可见, 只有配对的设备才能主动连接本设备;
可见状态 : int SCAN_MODE_CONNECTABLE_DISCOVERABLE, 值为23, 查询扫描和页面扫描都有效;
查询扫描功能 : 其它设备可以扫描到本设备 , 指的是可见性可见;
页面扫描功能 : 可以主动扫描其它设备;
(3)蓝牙操作接收的广播
开始搜索广播 : String ACTION_DISCOVERY_STARTED, 蓝牙适配器开始搜索远程设备, 值为"android.bluetooth.action.DISCOVERY_START",蓝牙适配器开始搜索之后, 会先有12秒的查询扫描(12s内可见), 查询扫描后进行页面扫描(主动搜索), 需要BLUETOOTH权限;
如果搜索到蓝牙设备, 就会收到BluetoothDevice.ACTION_FOUND广播, 可以从Intent中获取存放在其中的BluetoothDevice对象,intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
设备查找非常消耗资源, 在查找的过程中, 不能连接远程的蓝牙设备, 已经存在的连接也要限制带宽, 如果想要执行除查找外的其它操作, 之前最好调用cancelDiscovery();
搜索完成广播 : String ACTION_DISCOVERY_FINISHED,蓝牙S适配器完成搜索发出的广播,?值为"android.bluetooth.adapter.action.DISCOVERY_FINISHED", 需要BLUETOOTH权限;
蓝牙名称改变广播 : String ACTION_LOCAL_NAME_CHANGED, 本地的蓝牙适配器改变了自己的名称, 值为"android.bluetooth.adapter.action.LOCAL_NAME_CHANGED",注意改变的是本设备名称, 不是远程设备的.这个广播包含一个EXTRA_LOCAL_NAME附加域, 需要BLUETOOTH权限;
扫描模式变化广播 : String ACTION_SCAN_MODE_CHANGED, 蓝牙模块扫描模式发生了变化, 值为"android.bluetooth.adapter.action.SCAN_MODE_CHANGED",该Intent对象包含了EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE,两个附加域分别是新的和旧的扫描模式, 这里可以根据前后扫描模式的不同做出不同的操作, 需要BLUETOOTH权限;
开关模式变化广播 : String ACTION_STATE_CHANGED, 蓝牙模块被打开或者关闭, 值为"android.bluetooth.adapter.action.STATE_CHANGED",该广播的Intent中包含EXTRA_STATE和EXTRA_PREVIOUS_STATE两个附加域, 需要BLUETOOTH权限;
(4)蓝牙操作请求的广播
开启蓝牙 : String ACTION_REQUEST_ENABLE, 打开蓝牙, 值为"android.bluetooth.adapter.action.REQUEST_ENABLE",
Intentintent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,requestCode);
可以在Activity中的onActivityResult()方法中处理结果, 如果蓝牙模块打开成功, 则返回结果吗RESULT_OK; 如果蓝牙模块打开失败, 则返回结果码RESULT_CANCELED;
打开和关闭蓝牙模块, 都可以通过ACTION_STATE_CHANGED广播来监听;
蓝牙可见 : String ACTION_REQUEST_DISCOVERABLE, 使蓝牙可见, 值为"android.bluetooth.adapter.action.REQUEST_DISCOVERABLE",默认的可见时间为120s, 可以在广播中添加附加域, 设置任意的可见时间, 附加域为EXTRA_DISCOVERABLE_DURATION, 需要BLUETOOTH权限;
可以在Activity中的onActivityResult()方法中处理结果, 如果蓝牙模块设置可见成功, 则返回结果吗RESULT_OK; 如果蓝牙模块设置可见失败, 则返回结果码RESULT_CANCELED;
IntentdiscoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,0);
startActivityForResult(discoverableIntent,resultCode)
(5)附加域
附加域是放在Intent中的, 使用Intent.putExtra(附加域,附加值)方法添加附加域;
扫描模式附加域 : 这两个附加域的值是扫描模式, 可以为SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE,SCAN_MODE_CONNECTABLE_DISCOVERABLE;
String EXTRA_SCAN_MODE :值为"android.bluetooth.adapter.extra.SCAN_MODE";
String EXTRA_PREVIOUS_SCAN_MODE :值为"android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE";
开关状态附加域 : 这两个附加域的值是开关状态, 可以为STATE_OFF, STATE_ON, STATE_TURNING_OFF, STATE_TURNING_ON;
String EXTRA_STATE :值为"android.bluetooth.adapter.extra.STATE";
String EXTRA_PREVIOUS_STATE :值为"android.bluetooth.adapter.extra.PREVIOUS_STATE";
蓝牙名称附加域 : String EXTRA_LOCAL_NAME , 存放ACTION_LOCAL_NAME_CHANGED附加域的附加值 , 值为"android.bluetooth.adapter.extra.LOCAL_NAME";
可见时间附加域 : String EXTRA_DISCOVERABLE_DURATION, 存放的是ACTION_REQUEST_DISCOVERABLE广播的可见时长, 值为"android.bluetooth.adapter.extra.DISCOVERABLE_DURATION";
(6)错误码
int ERROR ,这个值用来标记错误 , 方便自己使用的 , 没有实际意义。
6.A2DP连接的建立
A2DP_CONNECT上层代码流程表