当前位置

Win32 下的蓝牙——开发事项、外设购买

作为项目 MobileSync 的一部分,我计划增加对蓝牙通信的支持。结果经过一段时间的尝试,我发现 Win32 平台上针对蓝牙开发简直太让人郁闷了。

红外的支持看 MSDN 的文档下很容易就完成了,所以我也首先去参考 MSDN 上蓝牙相关的部分,结果在创建一个 BTH 的套接字的时候返回了 10047 错误——"Address family not supported by protocol family"。接下来从网上搜索得知这是因为我的机器上还没有安装本机协议栈(native bluetooth stack)的缘故。太奇怪了,我明明已经安装了驱动并可以传送文件啊,为什么说我不支持蓝牙?

再进一步查找,这才知道在 Windows XP SP1 之前,微软是不支持蓝牙的。直到 SP2,native stack 也仅仅支持少数的几种设备。可以想象蓝牙刚刚问世的时候,微软的反应是:“谁知道这项技术会不会最终成功,俺先等等看吧”。于是后来 IVTWidcomm先后开发了自己的协议栈和管理应用程序,来配合蓝牙外设在 Win32 平台上的使用。而我的蓝牙适配器的问题就是,它可以在 IVT 下工作,但 SP2 不支持(ISSC 芯片)。

对于蓝牙软件开发商来说,问题就很棘手。市场上有三种协议栈,最好是全都支持以适应最大可能的应用范围。我现在才明白为什么我的 Nokia 3650 的 PC 同步程序无法用蓝牙通信,这是因为它用的 mRouter 协议层只支持 Widcomm 和 Native,不支持设备附带的 IVT 驱动。

后来还找到 Jon Cellini 的一篇文章,描述如何让并没有被 MS 官方支持的设备在 native 协议栈下工作的。虽然有人报告他的 ISSC 设备可以如法炮制,但我的适配器却不能这样去工作。

为了能继续我的开发工作,我只好重新买了一个 CSR 芯片的适配器。很便宜,不过 50 元(加上快递费),芯片版本还是 BlueCore4-ROM,似乎能支持蓝牙 2.0。它很顺利就在 XP 下自动检测出来了,同时"Control Panel"里面多了一个"Bluetooth Devices"的控件。然后我就发现微软缺省的管理程序比 IVT 差太多了,很明显 Microsoft Native Stack 将是未来开发的主流,但要想得到用户的广泛应用,还差一套完善的设备管理程序。不知道未来是 Vista 去改进,还是独立的第三方厂商做开发。

故事讲完了,如果你计划购买蓝牙适配器,我建议还是选择一个 SP2 官方支持的,比如 CSR 就挺好。市场上的主流好像是 ISSC,它的确更便宜一些,但我不敢保证 SP3 或者 Vista 就一定会支持..

最后要说的是,从这个事例里面看到,微软对外设的支持也就那么回事情,Linux 的 BlueZ 栈好像在 2.4.x 时代就确定了主流地位,是不是未来对新型硬件的支持以后 Linux 的优势会越来越明显?

Topic: 

评论

我目前也在做有关蓝牙软件的开发,涉及了两个协议栈:微软和widcomm。看了下你写的文章,想和你交流一下。
不知你对蓝牙配对了解的多不多,蓝牙通信两端,server端运行wince,使用微软蓝牙栈,client端是pc机,运行winxp,使用widcomm蓝牙栈,可否让蓝牙的配对过程自动化?即不用人工输入PIN码。
我测试过,server端我可以预先为请求连接的设备设置好PIN,但client端却不能编程设置好,需要在请求连接时手工输入。伪代码如下:
server:
---------
create socket
bind
listen
accept
if (connected)
{
set authenticate able
set pin
set authenticate
}

client:
--------
start inquiry
start discovery
openclient

这里server的authenticate设置是在accept连接成功后才执行的,在执行到setauthenticate时会要求client端输入PIN,但要手工输入。查阅widcomm的sdk文档,只发现有个Bond方法的参数可指定了PIN值,但是,如果在client端运行Bond,server的accept却接收不到请求,相反是系统弹出了一个对话框要求输入PIN,我觉得可能原因是两端的accept、Bond工作在不同的协议层上,所以,server的accept会收不到client的Bond请求。
想问问你有无类似的测试和经验分享分享。

从你描述的情况在,我觉得问题在于目前 Widcomm 和 MS 提供的 API 不支持的缘故。你现在调用的 API 都是接受到另一方请求 PIN 后的缺省行为就是弹出一个对话框。

accept/Bond 应该是两种不同的通信过程(严格来说,你所说的不同的协议层的提法是错误的),都是主动请求对方响应 PIN

我最近一段时间比较忙,一直也没有去继续研究蓝牙。我现在能想到的就是询问 widcomm 关于 API 的情况;或者是不要用 native 的 Bluetoothxxxxxxx 系列 API 族,而是用 socket 去完成通信. 不知道我的猜想是不是对的...

微软提供的基于winsock的蓝牙接口是在RFCOMM协议层之上实现的,而widcomm的Bond()却不是RFCComm的C++类的成员函数,所以我猜想是由于两个函数工作在不同的层上,不知这样说法对不对。
感谢你的答复,微软提供的接口真不好用,感觉麻烦死了,我想在连接前获取本地的蓝牙地址也比较困难,好像WSALookupServiceBegin/Next/End函数族可以获取本地地址,但不知是不是调用不对,读取不到,执行这个函数也要一点耗时,不爽。

用微软的WSALookupServiceBegin/Next/End函数族已可以读到本地的蓝牙地址,微软的sdk文档有某些错误,原来的用法不对。
通过WSALookupServiceBegin的返回来判断蓝牙是否已插好,但这个函数需要一点延时等待,使用感觉不好,不知是否会有更好的办法判断蓝牙是否已插上。

找到了更好的办法BluetoothFindFirstRadio/BluetoothGetRadioInfo来判断蓝牙是否已插好,可以动手封装这两个开发包了。

我想问下,我用的是ivt的驱动,是不是不能用Msdn里面的socket建立的方法来建立socket,还有什么办法吗?是不是要从底层的驱动开始动手,如果你看到这个帖的话,加我msn好吗?大家交流下:jonason123@hotmail.com

MSDN 里面的方法肯定是不能用滴。

ivt 网站上可下载 SDK

那我还想问下,我现在想实现简单的pc和ppc之间的通信,就是pc可以给ppc发消息,类似于普通的socket,要通过蓝牙的话,又几种方法呢?(我不考虑pc端用的是什么驱动,就是说任何驱动我都可以用蓝牙实现pc和ppc之间的通习)

如果你只是在 PPC 开发,应该可以不考虑 PC 的驱动,毕竟创建物理链路、传输数据通信这部分是标准的。PPC 上的驱动应该是 MS 标准的吧..

如果是 PC 的话就必须考虑驱动了

你好,看了你的博客,现在对蓝牙了解更多了,谢谢!

我们现在正在做的是在PC端读取蓝牙发送过来的数据,我下载了Widcomm的SDK,但是编译的时候提示:
error LNK2001: unresolved external symbol _GUID_BLUETOOTH_RADIO_OUT_OF_RANGE
WidcommSdklib.lib(MSUtils.obj) : error LNK2001: unresolved external symbol _GUID_BLUETOOTH_RADIO_IN_RANGE
WidcommSdklib.lib(MSUtils.obj) : error LNK2001: unresolved external symbol _GUID_BLUETOOTH_PIN_REQUEST
WidcommSdklib.lib(MSUtils.obj) : error LNK2001: unresolved external symbol _GUID_BLUETOOTH_L2CAP_EVENT
WidcommSdklib.lib(MSUtils.obj) : error LNK2001: unresolved external symbol _GUID_BLUETOOTH_HCI_EVENT

但是这些GUID_BLUETOOTH_RADIO_IN_RANGE之类的在widcomm说明里边没有定义呢,反而在MS的SDK里可以找到蛛丝马迹,那么是不是在使用Widcomm进行开发的时候还需要安装微软的SDK呢?可否给小弟一些建议或者帮助,谢谢了!

我看了一下 widcomm SDK 的 README,好像它现在有一种 Vista Pack 模式,就是说基于 windows native stack 来封装

你可能就是属于这种情况。。。
查查文档吧,看看怎么使用兼容 5.x SDK 的模式

你好,我是一名学生,我现在也在进行蓝牙的开发,开发环境选择的是:
系统 xp sp2 , 安装了 xp sp2的platform sdk, 用的是visual studio 2005中的C++ ,选择的是MFC的程序, 蓝牙适配器选择了 世纪飞扬 的 ,我拆开看了下,芯片是ISSC的, 然后我将蓝牙适配器插入电脑的USB口, 想发现一个蓝牙模块(这个是CSR芯片的),程序中写入:WSALookupServiceBegin的时候,出现了错误,10108:此服务不存在. 不知道是什么原因, 看了你的文章, 是不是微软的sdk不支持ISSC的芯片?还是什么别的原因?

我在网上下了一个BlueSoleil的软件,就可以用来发现周围的蓝牙模块(CSR芯片的),而且配对,传输都没有问题

应该是第一次插入支持的蓝牙设备的时候,xp 才去安装相对应的蓝牙服务

你好,我今天又重新查了下,微软的xp上开发蓝牙通信还是用csr芯片的适配器最好,但是有个问题又来了,就是关于csr适配器的选型问题,我不想购买很小的(因为太小,所以我不放心),不知道楼主用的是什么型号的蓝牙适配器, 还有个问题就是 多普达手机中的蓝牙芯片是什么型号的呢?

我的适配器,也就口香糖那么宽,小拇指那么长,不知道你觉得它的大小如何

多普达手机里的蓝牙芯片?我也不知道,你是想在 WinCE 上开发吗?我觉得应该是 native stack 的吧..

那谢谢了!!

^_^

您好,我用的蓝牙适配器也是CSR芯片,用WSALookupServiceBegin函数搜索蓝牙时也是出现了错误10108,请问您之前的问题怎么解决的?求指教