Windows Embedded Source Tools for Bluetooth

    技术2022-05-19  20

    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。服务端

    using Microsoft.WindowsMobile.SharedSource.Bluetooth;private void SetRadioMode(){    BluetoothRadio br = new BluetoothRadio();    WriteMessage("Radio Mode:" + br.BluetoothRadioMode);    if (br.BluetoothRadioMode != BluetoothRadioMode.Discoverable)    {        br.BluetoothRadioMode = BluetoothRadioMode.Discoverable;        WriteMessage("Radio Mode:" + br.BluetoothRadioMode);    }}private void StartService(){    Guid guid = StandardServices.SerialPortServiceGuid;     service = new BluetoothService(guid);    service.Start();    WriteMessage("Service started!");    System.Net.Sockets.NetworkStream ns = service.AcceptConnection(); //Warning: this is blocking code     WriteMessage("Got a request!");        string dataToSend = "Hello from service!";    // Convert dataToSend into a byte array    byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(dataToSend);    // Output data to stream    ns.Write(dataBuffer, 0, dataBuffer.Length);    byte[] buffer = new byte[2000];    while (service.Started && !stop)    {        if (ns.DataAvailable)        {            ns.Read(buffer, 0, 50);            string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, 50);            WriteMessage("Receiving data:" + data);        }    }    // Clear and close stream    ns.Flush();    ns.Close();} 复制代码

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

    //It does not support Wince 5 since Wince 5 does not include bthutil.dll//[DllImport(BTHUTIL_DLL)]//public static extern int BthGetMode(ref BluetoothRadioMode mode);//[DllImport(BTHUTIL_DLL)]//public static extern int BthSetMode(BluetoothRadioMode mode);public static int BthGetMode(ref BluetoothRadioMode mode){    int mask = 0;    int ret = BthReadScanEnableMask(ref mask);    switch (mask)    {        case 0x0:            mode = BluetoothRadioMode.Off;            break;        case 0x2:            mode = BluetoothRadioMode.On;            break;        case 0x3:            mode = BluetoothRadioMode.Discoverable;            break;    }    return ret;}public static int BthSetMode(BluetoothRadioMode mode){    int mask = 0;    switch (mode)    {        case BluetoothRadioMode.Off:            mask = 0x0;            break;        case BluetoothRadioMode.On:            mask = 0x2;            break;        case BluetoothRadioMode.Discoverable:            mask = 0x3;            break;    }    return BthWriteScanEnableMask(mask);}[DllImport(BTDRT_DLL)]public static extern int BthReadScanEnableMask(ref int mask);[DllImport(BTDRT_DLL)]public static extern int BthWriteScanEnableMask(int mask); 复制代码

    代码2Wince里面没有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!"给客户端后开始不停的接收,实际通信顺序由具体需求决定。客户端

    private void PairedDevices(){    BluetoothRadio br = new BluetoothRadio();        BluetoothDeviceCollection devices = br.PairedDevices;    foreach (BluetoothDevice device in devices)    {        WriteMessage("ID:" + device.Address[5].ToString("X2") + "-"            + device.Address[4].ToString("X2") + "-"            + device.Address[3].ToString("X2") + "-"            + device.Address[2].ToString("X2") + "-"            + device.Address[1].ToString("X2") + "-"            + device.Address[0].ToString("X2") + ", Name:" + device.Name);    }    ConnectService(devices[0] as BluetoothDevice);}private void ConnectService(BluetoothDevice device){    Guid guid = StandardServices.SerialPortServiceGuid;     // Create network stream object    // Connect to the device service (via the GUID)    System.Net.Sockets.NetworkStream ns = device.Connect(guid);    // Create storage for receiving data    byte[] buffer = new byte[2000];    // Read Data    ns.Read(buffer, 0, 50);    // Convert Data to String    string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, 50);    WriteMessage("Receiving data: " + data);    int i = 0;    while (!stop)    {        WriteMessage("Writing: " + i.ToString());        byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(i.ToString());        ns.Write(dataBuffer, 0, dataBuffer.Length);        ++i;        if (i >= int.MaxValue)        {            i = 0;        }        System.Threading.Thread.Sleep(500);    }    // Close network stream    ns.Close();} 复制代码

    代码3Windows 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";conststring BT_DEVICE_KEY_NAME ="Software//Microsoft//Bluetooth//Device//pan"; //wince 5代码4在wince下,注册表的位置取决于配对设备的类型,见下图。图1不同类型的配对设备放在不同的目录下。但是在Windows Mobile下,所有配对信息存放于Software//Microsoft//Bluetooth//Device下。图2ConnectService()的功能是链接服务端的设备。链接前同样选择串口服务,服务端和客户端需要使用统一的服务类型才能通信。在例子中连接后从服务端接收欢迎信息,然后不断往服务端发送数据。从上面的例子看Windows Embedded Source Tools for Bluetooth的功能不是很完整,没有自动发现功能,也就是通信双方在通信之前需要配对成功,因此这样很不方便。而且Windows Embedded Source Tools for Bluetooth只是支持 Microsoft windows stack,不支持broadcom stack,后面文章会介绍另外一个的开源库32feet.NET。这个库支持自发现功能,同时部分支持broadcom stack。


    最新回复(0)