Windows Embedded Source Tools for Bluetooth

Bluetooth的应用十分广泛,基于Bluetooth的通信程序开发主要有以下几个步骤:
服务端
* 设置设备为可发现。
* 公开服务给其他Bluetooth设备访问。
* 接受其他Bluetooth设备的链接。
* 与链接上的Bluetooth设备进行通信。
客户端
* 发现周边Bluetooth设备。
* 主动与被发现的设备发起连接。
* 与链接上的Bluetooth设备进行通信。
在.NET Compact Framework下进行Bluetooth开发有几个可选解决方案
* 可以P/Invoke直接调用Bluetooth的API(btdrt.dll)
* 使用MS的Windows Embedded Source Tools for Bluetooth
* 使用32feet.NET库

这篇文章讲述基于Windows Embedded Source Tools for Bluetooth的开发,点击 链接 下载Windows Embedded Source Tools for Bluetooth,安装后在目录 C:/Program Files/Microsoft/Windows Embedded Source Tools会找到源码以及编译后的DLL。
服务端

  1. using Microsoft.WindowsMobile.SharedSource.Bluetooth;
  2. private void SetRadioMode()
  3. {
  4.     BluetoothRadio br = new BluetoothRadio();
  5.     WriteMessage("Radio Mode:" + br.BluetoothRadioMode);
  6.     if (br.BluetoothRadioMode != BluetoothRadioMode.Discoverable)
  7.     {
  8.         br.BluetoothRadioMode = BluetoothRadioMode.Discoverable;
  9.         WriteMessage("Radio Mode:" + br.BluetoothRadioMode);
  10.     }
  11. }
  12. private void StartService()
  13. {
  14.     Guid guid = StandardServices.SerialPortServiceGuid;
  15.     service = new BluetoothService(guid);
  16.     service.Start();
  17.     WriteMessage("Service started!");
  18.     System.Net.Sockets.NetworkStream ns = service.AcceptConnection(); //Warning: this is blocking code
  19.     WriteMessage("Got a request!");
  20.    
  21.     string dataToSend = "Hello from service!";
  22.     // Convert dataToSend into a byte array
  23.     byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(dataToSend);
  24.     // Output data to stream
  25.     ns.Write(dataBuffer, 0, dataBuffer.Length);
  26.     byte[] buffer = new byte[2000];
  27.     while (service.Started && !stop)
  28.     {
  29.         if (ns.DataAvailable)
  30.         {
  31.             ns.Read(buffer, 0, 50);
  32.             string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, 50);
  33.             WriteMessage("Receiving data:" + data);
  34.         }
  35.     }
  36.     // Clear and close stream
  37.     ns.Flush();
  38.     ns.Close();
  39. }
复制代码

代码1
SetRadioMode检查本端Bluetooth设备是否为可发现,如果不可发现就设置为可发现。本地Bluetooth设备的状态分成三种:On,Off,Discoverable。在Windows Embedded Source Tools for Bluetooth库里面查询和设置设备RadioMode的函数有点问题,只能用在Windows Mobile里面,如果在Wince里使用,需要对SafeNativeMethods.cs进行以下的修改:

  1. //It does not support Wince 5 since Wince 5 does not include bthutil.dll
  2. //[DllImport(BTHUTIL_DLL)]
  3. //public static extern int BthGetMode(ref BluetoothRadioMode mode);
  4. //[DllImport(BTHUTIL_DLL)]
  5. //public static extern int BthSetMode(BluetoothRadioMode mode);
  6. public static int BthGetMode(ref BluetoothRadioMode mode)
  7. {
  8.     int mask = 0;
  9.     int ret = BthReadScanEnableMask(ref mask);
  10.     switch (mask)
  11.     {
  12.         case 0x0:
  13.             mode = BluetoothRadioMode.Off;
  14.             break;
  15.         case 0x2:
  16.             mode = BluetoothRadioMode.On;
  17.             break;
  18.         case 0x3:
  19.             mode = BluetoothRadioMode.Discoverable;
  20.             break;
  21.     }
  22.     return ret;
  23. }
  24. public static int BthSetMode(BluetoothRadioMode mode)
  25. {
  26.     int mask = 0;
  27.     switch (mode)
  28.     {
  29.         case BluetoothRadioMode.Off:
  30.             mask = 0x0;
  31.             break;
  32.         case BluetoothRadioMode.On:
  33.             mask = 0x2;
  34.             break;
  35.         case BluetoothRadioMode.Discoverable:
  36.             mask = 0x3;
  37.             break;
  38.     }
  39.     return BthWriteScanEnableMask(mask);
  40. }
  41. [DllImport(BTDRT_DLL)]
  42. public static extern int BthReadScanEnableMask(ref int mask);
  43. [DllImport(BTDRT_DLL)]
  44. public static extern int BthWriteScanEnableMask(int mask);
复制代码

代码2
Wince里面没有bthutil.dll,所以不能直接使用BthGetMode和BthSetMode的APIs了。需要调用BthReadScanEnableMask和BthWriteScanEnableMask来实现。
StartService使用winsock启动一个服务的侦听,在启动服务端时候必须选择服务,例子里选择了串口服务。关于bluetooth的服务,可以参考 http://en.wikipedia.org/wiki/Bluetooth_profile。 注意当service启动后,使用service.AcceptConnection()会把线程挂起,如果在实际使用中,一般需要启动一个worker thread执行,否则程序没办法处理其他任务,例如UI的响应。传输的数据是比特串(byte[]),所以可以传输任意类型的数据,在例子中传输的数据为string。在例子中回应"Hello from service!"给客户端后开始不停的接收,实际通信顺序由具体需求决定。
客户端

  1. private void PairedDevices()
  2. {
  3.     BluetoothRadio br = new BluetoothRadio();
  4.    
  5.     BluetoothDeviceCollection devices = br.PairedDevices;
  6.     foreach (BluetoothDevice device in devices)
  7.     {
  8.         WriteMessage("ID:" + device.Address[5].ToString("X2") + "-"
  9.             + device.Address[4].ToString("X2") + "-"
  10.             + device.Address[3].ToString("X2") + "-"
  11.             + device.Address[2].ToString("X2") + "-"
  12.             + device.Address[1].ToString("X2") + "-"
  13.             + device.Address[0].ToString("X2") + ", Name:" + device.Name);
  14.     }
  15.     ConnectService(devices[0] as BluetoothDevice);
  16. }
  17. private void ConnectService(BluetoothDevice device)
  18. {
  19.     Guid guid = StandardServices.SerialPortServiceGuid;
  20.     // Create network stream object
  21.     // Connect to the device service (via the GUID)
  22.     System.Net.Sockets.NetworkStream ns = device.Connect(guid);
  23.     // Create storage for receiving data
  24.     byte[] buffer = new byte[2000];
  25.     // Read Data
  26.     ns.Read(buffer, 0, 50);
  27.     // Convert Data to String
  28.     string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, 50);
  29.     WriteMessage("Receiving data: " + data);
  30.     int i = 0;
  31.     while (!stop)
  32.     {
  33.         WriteMessage("Writing: " + i.ToString());
  34.         byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(i.ToString());
  35.         ns.Write(dataBuffer, 0, dataBuffer.Length);
  36.         ++i;
  37.         if (i >= int.MaxValue)
  38.         {
  39.             i = 0;
  40.         }
  41.         System.Threading.Thread.Sleep(500);
  42.     }
  43.     // Close network stream
  44.     ns.Close();
  45. }
复制代码

代码3
Windows Embedded Source Tools for Bluetooth不支持自发现功能,所以在客户端的设备首先要和服务端的设备进行配对,所谓配对就是把对端的信息写入注册表里面。PairedDevices()取出配对信息,其实就是从注册表里面取信息,Windows Embedded Source Tools for Bluetooth这个功能也写得不好,如果在wince下使用需要修改BluetoothRadio.cs文件的PairedDevices属性。
//const string BT_DEVICE_KEY_NAME = "Software//Microsoft//Bluetooth//Device";
const
string BT_DEVICE_KEY_NAME =
"Software//Microsoft//Bluetooth//Device//pan"; //wince 5
代码4
在wince下,注册表的位置取决于配对设备的类型,见下图。

图1
不同类型的配对设备放在不同的目录下。
但是在Windows Mobile下,所有配对信息存放于Software//Microsoft//Bluetooth//Device下。

图2
ConnectService()的功能是链接服务端的设备。链接前同样选择串口服务,服务端和客户端需要使用统一的服务类型才能通信。在例子中连接后从服务端接收欢迎信息,然后不断往服务端发送数据。
从上面的例子看Windows Embedded Source Tools for Bluetooth的功能不是很完整,没有自动发现功能,也就是通信双方在通信之前需要配对成功,因此这样很不方便。而且Windows Embedded Source Tools for Bluetooth只是支持 Microsoft windows stack,不支持broadcom stack,后面文章会介绍另外一个的开源库32feet.NET。这个库支持自发现功能,同时部分支持broadcom stack。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值