• .NET Compact Framework下的蓝牙开发


    蓝牙的应用十分广泛,基于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, 
    050);
                
    string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 050);
                WriteMessage(
    "Receiving data:" + data);
            }
        }

        
    // Clear and close stream
        ns.Flush();
        ns.Close();
    }

    代码1
    SetRadioMode检查本端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);

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

    客户端 

    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[
    0as 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, 050);

        
    // Convert Data to String
        string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 050);
        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();
    }

    代码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。

    转载 没有测试

  • 相关阅读:
    Jquery 学习一
    响应式设计
    微信开发一
    Ajax 技术二
    Ajax 技术一
    SVN版本控制软件
    正则表达式概述
    编写小游戏:贪吃蛇
    POJ 3356 AGTC(DP-最小编辑距离)
    算法模板の字符串处理
  • 原文地址:https://www.cnblogs.com/TNTZWC/p/1511080.html
Copyright © 2020-2023  润新知