蓝牙 蓝牙技术(Bluetooth)是一种使用电波的、近距离的无线数据通信技术,它是为有线电缆的无线化而开发的。它的传输速度为1Mbps,传输距离为10米左右。利用“蓝牙“技术能够有效地简化掌上电脑、笔记本电脑和移动电话手机等移动通信终端设备之间的通信,也能够成功地简化以上这些设备与internet之间的通信,从而使这些现代通信设备与因特网之间的数据传输变得更加迅速高效,并为无线通信拓宽道路。因此,蓝牙技术使得现代一些轻易携带的移动通信设备和电脑设备不必借助电缆就能联网,并且能够实现无线上因特网,其实际应用范围还可以拓展到各种家电产品、消费电子产品和汽车等信息家电,从而组成一个巨大的无线通信网络。蓝牙系统由以下功能单元组成:无线单元、链路控制单元、链路管理单元、相关软件。蓝牙工作在全球通用的2.4Mb/s(即工业、科学、医学)频段,其数据传输速率为1Mb/s,该技术采用时分双工传输方案来实现全双工传输。 蓝牙规范接口可以直接集成到电脑上或者通过PC 卡或者 USB 接口进行连接。可以通过蓝牙蜂窝电话连接远端网络;利用蓝牙蜂窝电话做扬声器;在蓝牙笔记本电脑、手持机和移动电话间进行商用卡交易;在蓝牙笔记本电脑、手持机和移动电话间进行时间同步等等。蓝牙是一个独立的技术规范,不依赖于任何其他的技术规范。 蓝牙技术是一种新技术,它的问世无疑给移动通信的进一步发展带来新的动力。与此同时,也会开创一些新的、目前还不知道的应用。显然,为了更具生命力,它必须在解决自身问题的过程中不断进步。但应该相信在不久的将来,几乎所有家庭和办公设备都将是无线连接的,随之而来的将是生活和工作的日益简单和高效。 2.2.2 J2ME蓝牙 2.2.2.1 J2ME 蓝牙协议栈 J2ME 蓝牙协议栈如下图所示。
图5 J2ME蓝牙协议栈图 Bluetooth Radio 、LC、LMP和Host Controller Interface Firmware组成了协议栈的底层硬件部分。HCI、L2CAP、SDP、RFCOMM、OBEX组成了协议栈的上层软件部分。协议栈各部分组成的说明如下所示。 l Bluetooth Radio:蓝牙射频,用于调制和解调收发的蓝牙信号。 l LC:基带连接控制器,控制物理连接、射频跳动及封装包。 l LMP:连接管理器,控制和配置与其它设备的连接。 l Host Controller Interface Firmware:主控制器的硬件部分。 l HCI:主机控制器接口(Host Controller Interface)。这一层顾名思义就是主机(计算机)和控制器(蓝牙设备)之间的接口。可以看到,其他所有的层都要经过 HCI。 l L2CAP:即逻辑链接控制器适配层协议(Logical Link Controller Adaptation Protocol)。为上层协议提供面向连接和无连接的数据服务,并提供多协议功能和分割重组操作,允许传输和接收{zd0}长度为64KB的L2CAP数据包。 l SDP是服务发现协议(Service Discovery Protocol)层,用于在远程蓝牙设备上寻xxx。服务器维护一张服务记录列表,每个服务记录都包含服务器上一个服务的信息,每个服务对应一个服务记录。客户端访问服务器时,首先要获得服务器的访问记录,然后通过服务记录建立连接。 l RFCOMM:基于L2CAP协议的虚拟串口协议(virtual serial port protocol),因为它允许蓝牙设备模拟串口的功能。 l OBEX:为协议栈{zg}层,可以用来传输文件或者交换对象数据,OBEX协议是基于RFCOMM实现的。 在本设计中采用RFCOMM协议来实现手机与计算机进行通信,这主要是因为RFCOMM可以进行流式数据通信。 2.2.2.2 J2ME 蓝牙开发接口 JSR82规范是专门针对蓝牙开发设计的应用程序编程接口,其中包含如下两个包。 l Javax.bluetooth:核心API。 l Javax.obex:对象交换API。 Javax.bluetooth包中的类和接口如下表所示: 类和接口
表1 Javax.bluetooth包中的类和接口表
2.2.3 WINDOWS蓝牙 2.2.3.1 windows 蓝牙协议栈 windows 蓝牙协议栈如下图所示:
在本设计中只用到windows蓝牙协议栈中的两个部分,对于其它部分这里不作介绍,这两部分分别是: l WshBth : Windows蓝牙套接字帮助组成部分。 WshBth被Windows套接字层调用,来执行套接字操作。 WshBth主要通过TDI(输驱动程序接口)接口使用RfComm协议。 WshBth(一种服务,负责调查缓存和转发数据)还调用到BthServ进行远程设备查询,BthPort(一种被USB蓝牙加载的微型驱动)进行本地无线查询。 l RfComm:实现了蓝牙串行电缆仿真协议的组件。 RfComm也使用L2CAP和SDP接口来发现BthPort 。RfComm上层展示了TDI接口,使这一部分近似为网络传输。这是WshBth从用户模式的API连接到蓝牙发送和接收数据的过程。用户模式的应用程序可以使用Windows SDK中所描述的WinSock接口访问RfComm。 2.2.3.2 windows 蓝牙设计的一般过程 创建服务端套接字 1. 提供Winsock的版本和实现细节的数据来初始化caller application。可以通过调用WSAStartup函数来获得这个数据。 WSADATA wsd; WSAStartup (MAKEWORD(2,2), &wsd); 2. 调用socket函数来创建一个蓝牙套接字。 SOCKET server_socket=socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM); socket函数的参数值将套接字设置为蓝牙服务。 3. 通过设置SOCKADDR_BTH结构体来储存服务器设备的信息。SOCKADDR_BTH sa; memset (&sa, 0, sizeof(sa)); sa.addressFamily = AF_BT; sa.port = channel & 0xff; 注意 为了避免冲突,在选择服务器通道时建议将channel设置为0,这样RFCOMM将自动使用下一个有效的通道。结构体中的信息用来将套接字绑定到服务器设备的本地地址上。 4. 调用bind函数绑定第二步中创建的server_socket,传入第三步中创建的sa的引用指定设备信息。 if (bind (server_socket, (SOCKADDR *)&sa, sizeof(sa))) { //Perform error handling closesocket (server_socket); return 0; } 5. 用listen函数来监听客户端蓝牙设备发送的连接请求。 if (listen (server_socket,5)) { //Perform error handling closesocket (server_socket); return 0; } 6. 用accept函数来接受传入的连接请求。 SOCKADDR_BTH sa2; int size = sizeof(sa2); SOCKET s2 = accept (server_socket, (SOCKADDR *)&sa2,&size); 调用accept将返回SCOKADDR_BTH类型的客户端地址。 7. 调用closecocket函数来关闭套接字。 closesocket(server_socket); 要结束对Winsock服务的使用,调用WSACleanup函数。在程序中对每个成功调用的WSAStartup都必须对应地调用WSACleanup。
创建客户端套接字 1. 提供Winsock的版本和实现细节的数据来初始化caller application。可以通过调用WSAStartup函数来获得这个数据。 WSADATA wsd; WSAStartup (MAKEWORD(2,2), &wsd); 2. 调用socket函数来创建一个蓝牙套接字。 SOCKET client_socket = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM); socket函数的参数值将套接字设置为蓝牙服务。 3. 通过设置SOCKADDR_BTH结构体来储存客户端要连接到的远程设备的信息。 a. 创建并初始化SOCKADDR_BTH变量。 SOCKADDR_BTH sa; memset (&sa, 0, sizeof(sa)); b. 将btAddr成员赋值为包含目标设备地址的BT_ADDR变量。 sa.btAddr = b; //b is a BT_ADDR variable 应用程序可以接受字符串类型的设备地址,但必须将其转换并储存为一个BT_ADDR类型变量。 c. 如果服务标识符有效,则将serviceClassId成员设置为基于RFCOMM的服务的GUID。这种情况下,客户端执行SDP查询然后使用得到的服务器通道。或者如果要使用硬编码的通道编号,将port成员变量设置为服务器通道编号。 sa.port = channel & 0xff; 4. 调用connect函数来连接到蓝牙套接字。 if (connect (client_socket, (SOCKADDR *)&sa, sizeof(sa))) { //Perform error handling. closesocket (client_socket); return 0; } 传递第3步中设置好的SOCKADDR_BTH来指定目标设备的属性。连接建立后,你可以通过发送和接收数据来和目标设备通信。 5. 要关闭与目标设备的连接调用closesocket函数关闭蓝牙套接字,并且确保使用CloseHandle函数释放套接字。 closesocket(client_socket); CloseHandle ((LPVOID)client_socket); 6. 要结束对Winsock服务的使用,调用WSACleanup函数。在程序中对每个成功调用的WSAStartup都必须对应地调用WSACleanup。 |