对微软winsock PC端开发蓝牙疑问

来源:互联网 发布:阿里云地域选择 湖北 编辑:程序博客网 时间:2022/05/27 14:59

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

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

再进一步查找,这才知道在 Windows XP SP1 之前,微软是不支持蓝牙的。直到 SP2,native stack 也仅仅支持少数的几种设备。可以想象蓝牙刚刚问世的时候,微软的反应是:“谁知道这项技术会不会最终成功,俺先等等看吧”。于是后来 IVT 和 Widcomm先后开发了自己的协议栈和管理应用程序,来配合蓝牙外设在 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 的优势会越来越明显?

评论

你好,我是一名学生,我现在也在进行蓝牙的开发,开发环境选择

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

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

应该是第一次插入支持的蓝牙设备的时候,xp

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

你好,我今天又重新查了下,微软的xp上开发蓝牙通信还是用c

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

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

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

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

那谢谢了!! ^_^

那谢谢了!!

^_^

你好,看了你的博客

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

我们现在正在做的是在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

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

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

我目前也在做有关蓝

我目前也在做有关蓝牙软件的开发,涉及了两个协议栈:微软和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请求。
想问问你有无类似的测试和经验分享分享。

我想问下,我用的是iv

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

MSDN

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

ivt 网站上可下载 SDK

那我还想问下,我现

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

如果你只是在 PPC

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

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

从你描述的情况在,

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

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

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

微软提供的基于winsock

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

用微软的WSALookupServiceB

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

找到了更好的办法Bluet

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

原创粉丝点击