一、蓝牙基础知识
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 | 蓝牙设备client,类似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上层代码流程表