蓝牙历史:
蓝牙(Bluetooth),或称为蓝芽,是一种无线个人局域网(Wireless PAN),最初由爱立信创制,后来由蓝牙技术联盟订定技术标准。据说因为此技术尚在萌芽的阶段,故将Bluetooth以“蓝芽”的中文译名在台湾进行商 业的注册,不过在2006年,该组织已将全球中文统一为“蓝牙”。
1999年5月20日,索尼爱立信、IBM、英特尔、诺基亚及东芝等业界龙头创立蓝牙特别兴趣组(SIG,Special Interest Group),制订蓝牙技术标准。
“蓝牙”(Bluetooth)这名称来自10世纪的丹麦国王哈拉尔德(Harald Gormsson)的外号。出身海盗家庭的哈拉尔德统一了北欧四分五裂的国家,成为维京王国的国王。由于他喜欢吃蓝莓,牙齿常常被染成蓝色,而获得“蓝 牙”的绰号,当时蓝莓因为颜色怪异的缘故被认为是不适合食用的东西,因此这位爱尝新的国王也成为创新与勇于尝试的象征。1998年,爱立信公司希望无线通 信技术能统一标准而取名“蓝芽”。
1998年时Bluetooth推出0.7版,支援 Baseband 与 LMP(Link Manager Protocol)通讯协定两部份。1999年推出0.8版,0.9版、1.0
Draft版,1.0a版、1.0B版。1.0 Draft版,完成SDP(Service Discovery Protocol)协定、TCS(Telephony Control Specification)协定。
2001年的1.1版正式列入IEEE标准,Bluetooth 1.1即为IEEE 802.15.1。
Bluetooth 2.0将传输率提升至2Mbps、3Mbps,远大于1.x版的1Mbps(实际约723.2kbps)。
蓝牙的标准是IEEE 802.15.1,蓝牙协议工作在无需许可的ISM(Industrial Scientific Medical)频段的2.45GHz。最高速度可达723.1kb/s。为了避免干扰可能使用2.45GHz的其它协议, 蓝牙协议将该频段划分成79频道,(频宽为1MHZ)每秒的频道转换可达1600次。
1.2版本
这个版本向下兼容1.1版,其主要改进包括:
(1)匿名方式:屏蔽设备的硬件地址(BD_ADDR),保护用户免受身分嗅探攻击和跟踪。从1.1版开始已经可以实现硬件匿名,但未被实施,因此对普通 消费者来说还是没有此功能。
(2)自适应频率跳跃(AFH,Adaptive Frequency Hopping):通过避免使用跳跃序列中的拥挤频率,从而改善对无线电干涉的抵抗。
(3)更高的实际传输速度,实际测试约为 24KB/S(192Kbps) 左右。
(4)L2CAP层引入了流量控制和错误纠正机制
2.0版本
2.0版的内容还没有什么明确的信息,但爱立信的研究者公布了一些内容:
(1)加入了“非跳跃窄频通道”(Non-hopping narrowband channel )。
(1.1)因为不需要与每个设备交换应答信号,这种通道可以用来将各种器件的蓝牙服务概要同时广播到巨量的蓝牙器件。应答信号交换过程当前需要大约一秒。
(1.2)实时公共交通时刻表、基本的交通畅通性信息和高级交通指向指示等未加密信息可以以高速度发送给设备。
(2)更高的连接速度 (实际测试速度为72KB/s)
(3)支持多个速度水平
--------------------------------------------------------------------------------------------------------------------------
蓝牙访问技术的概述:
就像其他许多通信技术,蓝牙的模块层次构成了堆栈。其结构如下:
蓝牙堆栈:
蓝牙主机控制器模块Bluetooth Host Controller作为蓝牙的底层,是典型的硬件实现,应用程序(或在蓝牙上添加的服务)不能直接控制。蓝牙主机模块允许应用程序通过蓝牙连接发送/接 受数据,或者配置连接参数:
· RFCOMM允许应用程序将蓝牙连接模拟为串口进行操作。这样可以支持传统的协议。
· 逻辑连接控制和适配协议The Logical Link Control And Adaptation Protocol (L2CAP) 允许连接的finer-grained(?)控制。它用来控制多用户的连接,处理报文的分割和组合。这是应用程序的常用选择
· 服务发现协议The Service Discovery Protocol (SDP)用来定位和描述蓝牙设备提供或者可用的服务。应用程序主要在设置和另外的蓝牙设备通信时使用它
· 主机控制接口The Host Controller Interface (HCI)驱动包装了和硬件通信的高层模块
下面提到的API将为应用程序提供对RFCOMM, L2CAP, SDP,和部分的HCI操作支持。
描述
使用下面的API提供了蓝牙的相应功能:
蓝牙套接字——蓝牙套接字通过一个类似TCP/IP套接字的接口封装了对L2CAP和RFCOMM的操作。
蓝牙服务发现数据库——服务发现数据库封装了SDP的一侧:本地服务用它来记录服务的参数,以便让远程服务发现,并判断是否适合使用。
蓝牙服务发现代理——服务发现代理封装了SDP的另外一侧:它用来发现远程设备的服务和相应的服务的参数
蓝牙安全管理器——安全管理器提供了对于接入连接设直所需要的安全配置
--------------------------------------------------------------------------------------------------------------------------
蓝牙套接字概述:
目的发现其他蓝牙设备,并通过蓝牙读写数据。
在通过蓝牙建立通信频道中有两个角色:发起方和接受方。接受方进行配置后等待发起方建立连 接。一旦连接建立,两方是对等的,都可以发送或接受数据。这个API可以在两方进行编程。
结构关系
蓝牙套接字API支持在L2CAP和RFCOMM层上的通信。API基于客户端套接字 API,客户端套接字API是允许客户端和远程设备连接或者让远程设备连接自身,并在断开前发送和接收数据标准API。蓝牙套接字API中还为蓝牙的应用 加入了适当的类型和常量
描述
API有五个关键的概念:套接字地址,远程设备询问,RFCOMM命令和选项,L2CAP命 令和HCI命令
套接字地址
每个蓝牙设备都有一个唯一的48位地址,封装在TBTDevAddr。
套接字API通过TSockAddr封装了一个泛化的通信终点,而蓝牙则提供了一个专门的版 本TBTSockAddr,里面添加了蓝牙设备地址。
远程设备质询
客户端能通过RHostResolver询问远程设备是否可用。一个 TinquirySockAddr类型的参数用来提供这样地询问:主要是用来限制对设备细节类的发现。
命令和选项
我们能够通过调用RSocket::Ioctl()发送命令到一个RFCOMM套接字。套接 字的选项则能够分别通过Rsocket::GetOpt()和Rsocket::SetOpt()来设置。通过Rsocket::Ioctl(),我们能 发送命令到L2CAP套接字和HCI层。
-------------------------------------------------------------------------------------------------------------------------
Bluetooth link:
http://msdn.microsoft.com/en-us/library/ms898944.aspx
这个连接会有以下内容:
Bluetooth OS Design Development
Bluetooth Application Development
Bluetooth Registry Settings
Bluetooth Security
Bluetooth Performance Best Practices
Bluetooth Migration
Bluetooth Reference
这个连接详细讲了蓝牙 Winsock Interface Sample
http://msdn.microsoft.com/en-us/library/ms886497.aspx
Bluetooth Application Development Samples
http://msdn.microsoft.com/en-us/library/ms880961.aspx
Bluetooth Samples
http://msdn.microsoft.com/en-us/library/ms880972.aspx
-------------------------------------------------------------------------------------------------------------------------
网上找的BlueTooth Socket的例子:
WORD wVersionRequested = 0x202;
WSADATA m_data;
SOCKET s, s1;
if( 0 == ::WSAStartup( wVersionRequested, &m_data ) ) {
s = socket( AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM );
if ( s == INVALID_SOCKET ) {
return;
}
SOCKADDR_BTH address;
memset( &address, 0x00, sizeof(address) );
address.addressFamily = AF_BTH;
address.btAddr = (BTH_ADDR)0x000123456789;
address.serviceClassId = SerialPortServiceClass_UUID;
address.port = 17; // channel value gets from Mobile Phone.
s1 = connect( s, (sockaddr*)&address, sizeof(address) );
// S1 == 0
if( s1 == SOCKET_ERROR || s1 != 0 ) {
closesocket( s );
WSACleanup();
return;
}
char buf[512];
memset( buf, 0x00, sizeof(buf) );
int ret = recv( s1, (char*)buf, sizeof( buf ), 0 );
// ret == SOCKET_ERROR
// WSAGetLastError() == 0
}