当蓝牙SIG(特别兴趣组,由爱立信等厂商组成)成立的时候,其发起者曾经指出,当蓝牙能够被集成入单芯片之中、成本下降到5美元的时候,将得到极大地普及。而今,小小的一个五号电池大小的几十块人民币的东西就可以提供这个功能了,蓝牙也真的进入了我们的生活。利用蓝牙在手机之间传送图片不是什么新鲜事,现在做的是要连接Linux主机和蓝牙手机。
15.2.1 蓝牙技术概述
蓝牙最早由瑞典的爱立信公司提出,其名称源于古代瑞典的一位国王,因为总吃某种果品,把牙齿染成蓝色的,被称作蓝牙(bluetooth)。那时的瑞典统治整个北欧,盛极一时,同样有野心的爱立信于是使用这个名字来命名这个被他们寄予厚望的短距离互联技术。
Bluetooth用于连接个人周边的外围设备,比如无线耳机、打印机、扫描仪、手机、计算机等等,在这些设备之间交换文件和数据,替代低速串行线的工作,常用用途如下。
l 文件共享、传输。
l 语音传输。
l 远程打印。
l RS-232串行口线替代。
因为Bluetooth的功能十分实用,有了它既不需要麻烦的手机数据线了,也不需要像红外数据传输一样需要将两个设备对准,因此一经提出,立刻有一种一呼百应的感觉,随着成本的下降,蓝牙的用途也越来越广(当然了,这个过程也并非一帆风顺,成本的下降用了很多年才完成),大量的中低端手机也开始装备上了这项技术,以其更丰富、完善的协议栈,略高的传输速率,以及相对于红外线来说摆脱了必须毫无障碍的束缚,几乎完全取代了原来商务手机上普遍装备的红外接口。
蓝牙来到中国之初,在台湾地区注册商标的时候把“牙”替换成了更有东方美感的“芽”字,不过后来已经统一为了“牙”。蓝牙实际上并不是一种简单的协议,它的协议很复杂。
l 从网络结构和组网方式讲,蓝牙在10米区域内形成一个网络,其中可以有1个主设备,7个从设备,一共8个激活的设备,当然休眠的设备还可以有很多。对于更多的设备,可以使用adhoc的方式互联,本书不对此话题做更深入的介绍。
l 从应用来看,蓝牙支持语音通信和串行线模拟,并且通过Profile来支持各种周边智能设备的应用,比如耳机、打印机等等,并且定义了一套服务发现和调用机制。
蓝牙最有意思的莫过于第2层互联和应用层的Profile了,至于底层的跳频新意不大。另外,虽然蓝牙使用的频率和微波炉烹饪的频率毫无二致,但发射功率还是很小的,与手机相比,这个功率微不足道。
15.2.2 Linux下的蓝牙协议栈
Linux下有若干个蓝牙协议栈的实现,目前生存状况比较健康的是bluez和affix,后者是Nokia支持的,前者则是目前蓝牙的Linux官方版本,集成在Linux内核之中,也就是说,如果用户有一个比较新的2.6内核,那么,多半已经支持蓝牙了,而如果还不支持的话,重新编译一下或直接使用官方内核也就可以了。
不要误认为Linux的协议栈比不上Windows里面的,bluez协议栈支持的硬件设备远远多于Windows系统支持的。如果和作者一样只用Linux,那么,买了蓝牙适配器之后就可以使用蓝牙了。
内核的协议栈支持主要包含以下几个部分。
l HCI。这个是最底层的了,称为Host Control Interface(主机控制接口)。之所以称为HCI是源于蓝牙的应用模式的。蓝牙是连接智能外设的无线接口,接口的一侧是设备,另一侧就是主机(Host)了,采用类似记法的还有USB、IEEE1394,所以,从设计初衷来看,这几个产品都是针对差不多的市场的,只是各有所长。一个蓝牙适配器是否能被驱动起来,就看HCI的支持性了。最常见的蓝牙适配器就是作者持有的这类USB接口的了,对于大部分标准的蓝牙设备,它的驱动模块是hci-usb,对于2.6内核,插入这个适配器,该模块就被自动加载了。
l 在HCI之上是L2CAP(Logical Link Control and Adaptation Protocal,逻辑链路控制与适配层),这一层的功能承上启下,向上层提供异步数据传输的链路控制功能,所谓异步,就是不存在一个主时钟来同步所有传输的一种传输方式,通常用于数据的传输;与之相反,同步传输是完全与时钟同步的,通常用在诸如语音或是多媒体通话之中。此外,在蓝牙中,语音同步传输也是被支持的,bluez协议栈中的SCO就是支持同步模式的。
l L2CAP之上有两个协议被较广泛地使用:RFCOMM和BNEP。前者用于取代传统的串行口,包括串行口上的各种应用,比如,传真和拨号上网、打印机、文件图片等数据传输;后者则可以提供一个以太网接口,被用于计算机组网。对于手机和计算机之间,RFCOMM更常被用到,另一方面,计算机之间的组网则更常用更高速的无线局域网而不是蓝牙。
截止到这里就是内核提供的几乎所有蓝牙协议栈了,不过,仅有这些,蓝牙还不足以为用户所用,只有有了用户态的协议栈和工具相配合才能使用蓝牙。
15.2.3 用户空间中的蓝牙协议栈与相关工具
下面介绍用户空间的实现部分。
l 在最上层,蓝牙定义了很多的Profile,每个Profile对应着一种应用,比如打印、耳机(Headset)、文件传输、Fax/Modem拨号功能等。其中,文件交换对应着OBEX协议,这是一个基于蓝牙、红外(IrDA)、串口等介质的文件(对象)交换协议,这几种介质被列到一起一点也不会让人感到意外,毕竟前两个都是用来在某种意义上取代串口的。当然,有些Profile,比如一些人机交互设备(键盘鼠标之类的)的Profile是在内核中实现的。
l SDP为服务发现协议,这个协议可以认为和RFCOMM处于同一层次,因为它并不承载于RFCOMM之上,不过,这个协议却十分特殊而重要,通过它,才能识别出某一蓝牙设备提供了哪些服务(Profile),从而进一步使用。
协议栈已经有了,使用蓝牙是非常简单的事情。
l 找到蓝牙设备,这是HCI层负责的,使用bluez-utils包提供的hcitool来找到蓝牙设备。
l 找到服务,RFCOMM是通过不同的频道(channel)来提供不同的Profile的,所以需要找到要用的服务在设备上的哪个频道上,这是通过同一个软件包里的sdptool来完成的,就是SDP,服务发现协议。
l 连接恰当的服务并使用。
蓝牙的特点就是如上所述的那些了,而用户态的工具所要完成的任务就是发现服务和使用服务了。
1.启动HCI设备
首先,用户需要启动hcid,让HCI层的通信可以进行。对于Debian用户来说,需要安装bluez-utils包,并启动hcid。如果已经运行了bluetooth服务,插入USB适配器后,hcid就已经在运行了,看看相关信息,见清单15.2。
清单15.2 HCI接口信息
1 inspiration :/ etc/ bluetooth # hciconfig -a
hci 0: Type : USB
3 BD Address : 11:11:11:11:11:11 ACL MTU: 678:8 SCO MTU: 48:10
UP RUNNING PSCAN ISCAN
5 RX bytes :413 acl :0 sco :0 events :19 errors :0
TX bytes :323 acl :0 sco :0 commands :19 errors :0
7 Features : 0xbf 0xfe 0x8d 0x78 0x08 0x18 0x00 0x00
Packet type : DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
9 Link policy : RSWITCHHOLDSNIFFPARK
Link mode : MASTER
11 Name : 'inspiration -0'
Class : 0x3e 0100
13 Service Classes : Networking , Rendering , Capturing , Object Transfer , Audio
Device Class : Computer , Uncategorized
15 HCI Ver : 1.2 (0x2) HCI Rev : 0x1fe LMP Ver : 1.2 (0x2) LMP Subver : 0x1fe
Manufacturer : Integrated System Solution Corp . (57)
这个过程是自动的,当然也可以用hciconfig(8)来手工控制。hcid的配置文件位于/etc/bluetooth/hcid.conf,通常使用软件包附带的版本就可以了,如果希望不用每次连接都在计算机这里确认一次PIN码的话,可以设置其中的security字段为auto,这样,每次连接就会使用passkey设置的PIN码了。
2.寻找蓝牙设备
HCI已经启动了,现在就可以用它来寻找蓝牙设备了,当然,一定要先开启蓝牙设备的蓝牙功能,这个不是废话,手机的蓝牙是默认关闭的,只有在手动控制之下才会发送信号,允许被扫描到,不过设备的个体差异性太大,这里没法介绍,作者假设读者已经自己摸索或参照说明书打开了设备的蓝牙电源。寻找蓝牙设备如清单15.3所示。
清单15.3 寻找蓝牙设备
inspiration :/ home / gnawux # hcitool scan
18 Scanning ...
00:17:00:7 B :18: B8 Motorola SLVR
之后蓝牙设备就会被顺利地找到,当然,前提是不要忘了打开手机的蓝牙开关,并允许被找,这个功能平时最好不要打开,以防在公共场合遇到安全问题。
3.查看设备提供的服务
利用SDP协议,用户还可以查看每个设备都有功能,能提供什么服务,每种基于RFCOMM的服务都使用某种协议,占据一个“频道(channel)”,这是使用蓝牙服务时的一个重要参数。
下面是例子,先看看本机,见清单15.4。
清单15.4 本机提供的蓝牙服务
20 gnawux@inspiration :~$ sdptool browse local
Browsing FF:FF:FF :00:00:00 ...
22 Service Name : OBEX Object Push
Service RecHandle : 0x10000
24 Service Class ID List :
" OBEX Object Push " (0x1105)
26 Protocol Descriptor List :
"L2CAP" (0x0100)
28 "RFCOMM " (0x0003)
Channel : 9
30 " OBEX " (0x0008)
Profile Descriptor List :
32 " OBEX Object Push " (0x1105)
Version : 0x0100
然后可以看看关心的设备提供的服务,手机提供的服务种类比较多,首先是SDP服务器,也就是服务发现服务器,有了这个服务,就可以接下来发现其他服务功能了,见清单15.5。
清单15.5 手机提供的SDP功能
34 gnawux@inspiration :~$ sdptool browse 00:17:00:7 B :18: B8
Browsing 00:17:00:7 B :18: B8 ...
36 Service RecHandle : 0x0
Service Class ID List :
38 "SDP Server " (0x 1000)
Protocol Descriptor List :
40 "L2CAP" (0x 0100)
"SDP" (0x 0001)
42 Profile Descriptor List :
"SDP Server " (0x 1000)
44 Version : 0x 0100
手机的最基本功能就是用于(电话或网络)拨号,这里列出的第一项服务也是“拨号网络网关”,标识服务具体类型的字段是“Service Class ID”,它所在的频道是RFCOMM的频道1,如清单15.6所示。
清单15.6 手机提供的拨号网络功能
Service Name : Dialup Networking Gateway
46 Service Description : Dialup Networking Gateway
Service Provider : Motorola
48 Service RecHandle : 0x 10001
Service Class ID List :
50 " Dialup Networking " (0x 1103)
Protocol Descriptor List :
52 "L2CAP" (0x 0100)
" RFCOMM " (0x 0003)
54 Channel : 1
Language Base Attr List :
56 code _ ISO 639: 0x 656e
0x6a
58 base _ offset : 0x 100
code _ ISO 639: 0x7a68
60 encoding : 0x6a
base _ offset : 0xc 800
62 Profile Descriptor List :
" Dialup Networking " (0x 1103)
64 Version : 0x 0100
除了拨号网络服务的频道位置相对固定之外,其他服务在不同手机上的频道通常是不同的,手机一般支持的其他服务包括音频/耳机服务、车载免提服务、OBEX对象推送服务、OBEX文件传输服务以及图片推送服务等,利用这些服务,可以利用手机拨号上网或是与手机交换图片、音乐等文件。
15.2.4 使用蓝牙
首先介绍如何利用蓝牙取代手机数据线,以便进行拨号等工作。之后介绍利用蓝牙传送文件的几个用法,都是借助于前面提到的OBEX协议。
1.用蓝牙代替串口
大家知道,蓝牙的一个基本功能就是模仿串口,而串口的重要作用之一(可能是最重要的了)就是拨号,传统的DTE也就是Modem。实际上,通过RFCOMM,蓝牙连接可以反映在/dev/rfcomm0这样的字符设备上,像串口一样操作。当然,最好先定义/etc/bluetooth/ rfcomm.conf,里面根据手机的设备号和频道号写上相应设置,见清单15.7。
清单15.7 rfcomm设置
rfcomm 0 {
66 # Automatically bind the device at startup
bind yes ;
68
# Bluetooth address of the device
70 device 00:17:00:7 B :18: B8;
72 # RFCOMM channel for the connection
channel 1;
74
# Description of the connection
76 comment " Motorola SLVR L7";
}
这样,在启动bluetooth服务的时候,就已经自动连接上了,而不需要使用rfcomm(1)命令自己费力气了。现在,可以使用任意一个喜欢的串口程序(minicom、gtkterm等等)来对/dev/rfcomm0进行操作了,当然也可以使用pppd建立拨号网络。
2.利用OBEX推送文件
这是使用手机或计算机提供的“OBEX Object Push”(0x1105)服务,由另一方向其推送如文件。使用的工具是openobex-apps包里的obex test工具。首先是利用手机的Push服务向手机推送,对于本例中的手机,这是通过清单15.5所使用的sdptool命令得到的结果的一部分,清单15.8所示。
清单15.8 手机提供的对象推送功能
78 Service Name : OBEX Object Push
Service Description : OBEX Object Push
80 Service Provider : Motorola
Service RecHandle : 0x 10008
82 Service Class ID List :
" OBEX Object Push " (0x 1105)
84 Protocol Descriptor List :
"L2CAP" (0x 0100)
86 " RFCOMM " (0x 0003)
Channel : 8
88 " OBEX " (0x 0008)
可以看到,推送服务位于频道8,现在,在obex_test的命令行里指定设备和频道,如清单15.9所示。
清单15.9 向手机推送文件
gnawux@inspiration :~$ obex _ test -b 00:17:00:7 B :18: B8 8
90 Using Bluetooth RFCOMM transport
OBEX Interactive test client / server .
92 > c
Connect OK!
94 Version : 0x10. Flags : 0x00
> p wangxu . jpg me. jpg
96 PUT file (local , remote )> name = wangxu .jpg , size =34177
Going to send 34177 bytes
98 Made some progress ...
Made some progress ...
100 Made some progress ...
Made some progress ...
102 Made some progress ...
PUT successful !
104 > q
执行完obex-test之后,进入一个交互状态,首先建立连接,然后传送文件(本地文件名是wangxu.jpg,存在手机上叫me.jpg(这个是随意取的),最后退出。这个过程需要看着手机屏幕,可能要确认是否连接,文件存放在哪里,这个和手机有关。
现在也可以看看手机向计算机推送,首先应该让计算机进入接收状态,如果本地没有启动Object PUSH服务,可以利用sdptool把它加上,如清单15.10所示。
清单15.10 给计算机加上Object Push服务
gnawux@inspiration :~$ sdptool add OPUSH
106 OBEX Object Push service registered
现在进入接收状态,注意要使用计算机(local)的地址和频道号,这些信息可以通过清单15.4所示方法得到,见清单15.11。
清单15.11 接收手机推送的文件
gnawux@inspiration :~$ obex _ test -b FF:FF:FF :00:00:00 9
108 Using Bluetooth RFCOMM transport
OBEX Interactive test client / server .
110 > s
现在,计算机进入了接收模式,在手机侧发送文件到计算机就可以了。
3.使用obexftp上传下载
使用“OBEX File Transfer”(0x1106)服务的obexftp是一个方便的工具,利用它可以查看手机上的内容,并进行上传下载,对于本例,对应的频道是9。先来查看一下有哪些目录,见清单15.12。
清单15.12 obexftp列目录清单
gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -l
112 Browsing 00:17:00:7 B :18: B8 ...
Channel : 9
114 Connecting ... done
Receiving "( null )"...| <? xml version ="1.0" ?>
116 <! DOCTYPE folder - listing SYSTEM "obex - folder - listing . dtd">
<folder - listing >
118 <parent - folder />
<folder name =" audio " size ="0" type =" folder " modified ="20060805 T 144844 Z" user
- perm =" RW" />
<!--[if !supportLists]-->120 <!--[endif]--><folder name =" video " size ="0" type =" folder " modified ="20060805 T 144844 Z"
user - perm =" RW" />
<folder name =" picture " size ="0" type =" folder " modified ="20060805 T 144844 Z"
user - perm =" RW" />
<!--[if !supportLists]-->121 <!--[endif]--><folder name =" MMC( Removable )" size ="0" type =" folder " modified ="19700101 T
000000 Z" user - perm =" RW"
124 </folder - listing >done
Disconnecting ... done
可以看到,有4个有读写(RW)权限的目录,再看看audio里面有什么,见清单15.13。
清单15.13 obexftp查看audio目录
126 gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -l audio
Browsing 00:17:00:7 B :18: B8 ...
128 Channel : 9
Connecting ... done
130 Receiving " audio "...| <? xml version ="1.0" ?>
<! DOCTYPE folder - listing SYSTEM "obex - folder - listing . dtd">
132 <folder - listing >
<parent - folder />
<!--[if !supportLists]-->134 <!--[endif]--><file name ="a.mp 3" size ="977920" type =" audio /mp 3" modified ="20060805 T 145050
Z" user - perm =" RW"
136 </folder - listing >done
Disconnecting ... done
可以看到,这里有一个MP3文件,把它取下来,如清单15.14所示。
清单15.14 obexftp下载
138 gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -c audio -g a.mp3
Browsing 00:17:00:7 B :18: B8 ...
140 Channel : 9
Connecting ... done
142 Sending " audio "... done
Receiving "a.mp3"... - done
144 Disconnecting ... done
经过一段漫长的等待,传送终于完成了。再把wangxu.jpg放到picture目录去,如清单15.15所示。
清单15.15 obexftp下载
gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -c picture -p wangxu .jpg
146 Browsing 00:17:00:7 B :18: B8 ...
Channel : 9
148 Connecting ... done
Sending " picture "... done
150 Sending " wangxu .jpg "...\ done
Disconnecting ... done
这些就是obexftp的基本用法,更复杂的用法可以参考它的手册页obexftp(1)。此外,还有obexserver、qobex(基于QT的图形化界面工具)等工具,此处不一一介绍。