作者: 俞伟
蓝牙 概述
Blu et o o th 即 我们通 常说 的蓝牙。 蓝牙的 构想源 于 P AN – P ers o n al A rea N e two r k , 个人区 域 网,目的 是在小 范围的区 域网络 内 实现蓝 牙设备之 间的通信 。这个 蓝牙设备 一般是指 带蓝 牙功能的 手机或 蓝牙 手持 设备,蓝 牙设备 之间的通 信距离在 5 -1 5 米 之间, 完全免费 。 常 见的蓝牙 应用包 括: 蓝牙 耳麦,文 件传输 ,数据通 信等等。
Bla ckBe rr y 平台 对蓝牙的 支持 包括 J SR 0 8 2 和 Bla ck Berry 平 台自身 提供的 Blu et o o thS erial P o rt
( 蓝牙串 口协议 ) 。其中 J S R0 8 2 是比 较流行 ,使用 比较广泛 的蓝牙 接口标准 ,由 J 2 M E 延续 而来。本 文主要 说明 J SR0 8 2 蓝 牙接口 的使用 。
JS R08 2 规定 的内容包括:
1 . D ata Tran s m issions On ly - 仅数据传 输
2 . 通讯协议 :
· L2 CA P ( 长连接 )
· RFCOM M
· SDP
· Object Exc h ang e P r o t o c o l
3 . 功能简表 :
· Generic Ac cess P r o fil e ( GA P )
· Service D is co v er y App li cati o n P r o fil e ( SDA P )
· Seri al P o rt P r o fil e (SP P )
· Generic Object Exchang e P ro fil e (GOE P )
JS R 0 8 2 A PI 支持以下功能:
1 . Register se r v ices – 注册服 务
2 . D isc o v er d e v ices and se r v ic es – 发现蓝 牙设备 和设备 上的服务
3 . Estab li sh RFC OM M , L 2 CA P an d OBEX co nn e ctio n s – 建 立 RFCO MM , L 2 CA P , OBE X 连接
4 . Co ndu ct th ese a cti v ities in a se cur e fashi o n – 以 一种 安全的方 式来执 行以上操 作
表 1 列出了蓝牙协议 和协议层
蓝牙协议组 |
协议堆栈 |
蓝牙核心 协议 |
Baseband , L in k M an ag e r P r o t o co l , L 2 CA P , SD P |
有线连接 取代协 议 |
RFCOM M |
电话通讯 控制协 议 |
TCS Bin ary |
已经采用 的协议 |
P P P , UD P / TCP / I P , OB EX , W AP |
表 1
图 1 展现了各协议和 协议层的结构
图 1
H CI -H o st C o n tr o l In te rfa ce 以下为蓝 牙传输 底层协议 , H CI 之上为上 层协议, H CI 为上层协
议与底层 协议的 通信提供 了接口。 L2 CA P 是 长连接 协议,作 为其他 高级协议 的基础, 数据 传输以 b y te 流 为基础 。 R FCOMM 为连接 线取代协 议,模拟 RS -2 3 2 控 制, 数据传输 通过 Baseband 。 RFCO M M 协议 是其他使 用串口 通讯协议 的基础。 TCS Bin ary 定义 了通话控 制信 号,为蓝 牙设备 接收语音 数据提供 了通道 。 OBE X 协议为对 象级别 的传输提 供服务, 比如 文本文件 ,音频 文件,视 频文件 , 联系人 文件等各 种文件。
什么是蓝 牙简表 ( P r o fil es ) ?蓝牙简 表是指 对于某一 类 蓝牙功 能所需 协议的概 括,它 是 一个 标准,为 该类蓝 牙功能挑 选适合的 蓝牙通 讯协议 。
图 2 展示了常用的蓝 牙功能简表
图 2
如图 2 所示 , SP P 简表 支持电话 网络, 传真,耳 麦,网络 访问。 G OEP 简 表支持文 件传输 ,
对象推送 ,数据 同步。 TC S 简表支持无 线电话 等。
客户端与服务端模式 蓝牙服务 是指应 用服务程 序通过蓝 牙为客 户端提供 数据交互 。 比如 打印服务 就是一个 蓝牙
应用服务 ,该应 用服务程 序运行在 与打印 机相连的 服务器上 ,一旦 客户端通 过蓝牙给 服务 器发送打 印请求 ,该 应用 服务会执 行打印 操作。作 为蓝牙服 务端, 它的服务 需要定义 一个 Service Re co rd ( 服务 记录 ) 并添加该 记录到 S erv ic e D isco v er y D a tabase ( SD D B) 。
服务记录 注册后 ,服务应 用等待客 户端发 起的访问 。如果服 务端应 用与客户 端匹配, 双方 会建立蓝 牙通讯 连接。客 户端向发 服务端 发送请求 ,服务端 响应请 求。
蓝牙 客户 端
蓝牙应用 客户端 与蓝牙服 务端实现 交互的 步骤 :
1 . 搜索蓝牙 设备 – D ev i ce D is co v ery
2 . 搜索服务 – Se rvic e Sear ch
3 . 获取连接 URL – Ob tain Blu et o o th URL
4 . 建立连接 (RFCOM M , L 2 CA P , OB EX ) – E stabl ish C o nn e ctio n
5 . 数据交互 – D ata T ran s m iss io n
搜索蓝牙设备
启动设备 搜索之 前,首先 要获取本 地蓝牙 设备 M A C ID , 搜索代 理,和 最大 服务搜索 数。
public class BlueEngine implements Runnable, DiscoveryListener {
private DiscoveryAgent agent = null ;
private StreamConnection streamConnection = null ;
private DataInputStream dis = null ;
private DataOutputStream dos = null ;
private Thread thread = null ;
private int maxServiceSearches = 0;
private int serviceSearchCount ; private ServiceRecord record = null ; private Vector deviceList ;
public String command = null ; public String url = null ; public String macId = null ;
private Object bluelock = new Object();
public BlueEngine() {}
public void initBluetooth() throws Exception {
// 获取本地 设备
LocalDevice local = LocalDevice. getLocalDevice ();
// 获取本地 蓝牙设 备 MA C I D
macId = local.getBluetoothAddress();
// 获取蓝牙 设备搜 索代理
agent = local.getDiscoveryAgent();
try { // 获取最大 服务搜 索数
maxServiceSearches = Integer.parseInt (LocalDevice. getProperty ( "bluetooth.sd.trans.max" ));
} catch (NumberFormatException e) {}
deviceList = new Vector(); // 蓝牙设备 队列
}
类 Blu eEng in e 需要 实现 D i sco v er yL ist ener 接 口来执 行和完成 蓝牙设 备搜索 。 调用搜索 代理 ag ent.startInqu iry( D isc o v er y Ag ent.GI AC , thi s) 启动蓝 牙搜索。 参数 GIA C 指明 搜索所有 能够发 现的蓝牙 设备。 参数 thi s 是 D isc o v er yL ist ener ,当 搜索完成 后系统 调用 D isc o v ery L isten er 的 接口回调 处理。 搜完成后 如果蓝牙 设备队 列不为空 ,启动服 务搜索 。
public void getBluetoothUrl() throws Exception {
record = findService();
url = record .getConnectionURL(ServiceRecord. NOAUTHENTICATE_NOENCRYPT ,
false );
}
public ServiceRecord findService() {
try {
// 启动搜索 代理发 现设备 并与 DiscoveryListener 注册回调
agent .startInquiry(DiscoveryAgent. GIAC , this );
// 设备搜索 过程是 异步的 ,这里需 要同步 搜索过 程
// 设备搜索 完毕会 通知主 线程继续 运行
synchronized ( bluelock ) {
try {
bluelock .wait();
} catch (Exception e) {}
}
} catch (BluetoothStateException e) {
System. out .println( "Unable to find devices to search" );
}
// 蓝牙设备 队列不为 空,启动 服务搜 索
if ( deviceList .size() > 0) {
if (searchServices( deviceList )) {
return record ;
}
}
return null ;
}
D isc o v ery L isten er 的两个 回调接口 。接口 d ev ic eD is co v ered( Re m o te D e v ice, D e v iceClas s) 收入 被发现的 蓝牙设 备。接 口 inqu iryCo m p let ed(in t) 通知程序 设备搜 索完毕, 通知主线 程继续 。
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
// 当发现蓝 牙设备 时,如 果该设备 蓝牙模 块的 id 以 0 00 27 开头
// 则收入该 设备
if (btDevice.getBluetoothAddress().startsWith( "00027" )) {
deviceList .addElement(btDevice);
}
}
public void inquiryCompleted( int discType) {
// 蓝牙搜索 执行完 毕,通 知主线程 继续
synchronized ( bluelock ) {
try {
bluelock .notify();
} catch (Exception e) {
}
}
}
BlackBerry SDK下载
相关链接:
BlackBerry 蓝牙编程(一)
BlackBerry 蓝牙编程(二)
BlackBerry 蓝牙编程(三)