简体   繁体   English

在 C# 中从 BLE 设备读取数据

[英]Reading Data from a BLE device in C#

I have to write a Windows desktop application to read logs from a portable medical device.我必须编写一个 Windows 桌面应用程序才能从便携式医疗设备读取日志。 The scenario is that the device goes into the repair depot for maintenance.场景是设备进入维修站进行维护。 The tech connects the PC to the device via Bluetooth and downloads the logs.该技术人员通过蓝牙将 PC 连接到设备并下载日志。 After some maintenance, the device is shipped back to the customer and may not be seen again for months.经过一些维护后,设备会被运回客户,并且可能几个月都不会再看到。

I already tried using the Serial Port Profile, but learned very quickly that BLE doesn't support it.我已经尝试使用串行端口配置文件,但很快了解到 BLE 不支持它。 The device which is being developed by another company is constrained to be BLE-only so I can't use the SPP.由另一家公司开发的设备仅限于 BLE,因此我无法使用 SPP。 The data will be in the 10kb to 100 kb size range.数据将在 10kb 到 100kb 大小范围内。

I've looked at creating a custom service to get the number of log entries available as well as possibly setting date ranges for getting the logs.我已经研究过创建自定义服务来获取可用日志条目的数量以及可能设置获取日志的日期范围。 This part looks reasonable.这部分看起来很合理。

What I'm not sure of is how to open a stream to read the logs once I know how many there are to retrieve.我不确定的是一旦我知道有多少要检索,如何打开流来读取日志。 Each log entry will be sent as a character string that the Windows code will parse into individual values for display to the tech.每个日志条目都将作为字符串发送,Windows 代码会将其解析为单独的值以显示给技术人员。

I'm somewhat new to BLE so I'm not sure which way to go to get the actual log entries.我对 BLE 有点陌生,所以我不确定要获取实际日志条目的方法。 Thanks in advance for guidance.预先感谢您的指导。

Update:更新:

Doing more investigating, It looks like the Object Transfer Protocol may be the way to go.做更多调查,看起来对象传输协议可能是要走的路。 A quick calculation has each log record in the size range of 64 bytes, more or less.快速计算使每个日志记录的大小范围为 64 字节,或多或少。

My understanding is that the OTP allows me to get a count of objects, in this case log records, and request them one-by-one from the device.我的理解是 OTP 允许我获取对象的数量,在这种情况下是日志记录,并从设备中一一请求它们。 Does this approach look reasonable?这种方法看起来合理吗?

Here is some code I wrote a few years ago to talk to my LG G3 phone via Bluetooth.这是我几年前编写的一些代码,用于通过蓝牙与我的 LG G3 手机通话。 I used the InTheHand library.我使用了 InTheHand 库。 I don't recall if it supports BLE....我不记得它是否支持 BLE....

using InTheHand.Net;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Bluetooth.AttributeIds;
using InTheHand.Net.Sockets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace BluetoothPrototype1
{
    class Program
    {
        private const string DEVICE_NAME = "G3";

        private static BluetoothDeviceInfo _device = null;
        private static BluetoothWin32Events _bluetoothEvents = null;

        static void Main(string[] args)
        {
            try
            {
                displayBluetoothRadio();

                _bluetoothEvents = BluetoothWin32Events.GetInstance();
                _bluetoothEvents.InRange += onInRange;
                _bluetoothEvents.OutOfRange += onOutOfRange;

                using (BluetoothClient client = new BluetoothClient())
                {
                    BluetoothComponent component = new BluetoothComponent(client);
                    component.DiscoverDevicesProgress += onDiscoverDevicesProgress;
                    component.DiscoverDevicesComplete += onDiscoverDevicesComplete;
                    component.DiscoverDevicesAsync(255, true, false, false, false, null);

                    //BluetoothDeviceInfo[] peers = client.DiscoverDevices();

                    //device = peers.ToList().Where(p => p.DeviceName == DEVICE_NAME).FirstOrDefault();
                }                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.ReadKey();
            }
        }

        static void onOutOfRange(object sender, BluetoothWin32RadioOutOfRangeEventArgs e)
        {
            Console.WriteLine(string.Format("Device {0} out of range", e.Device.DeviceName));
        }

        static void onInRange(object sender, BluetoothWin32RadioInRangeEventArgs e)
        {
            Console.WriteLine(string.Format("Device {0} in range.  Connected:{1}", e.Device.DeviceName, e.Device.Connected));
        }

        static void onDiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e)
        {
            Console.WriteLine("Device discovery in progress");
            foreach (var device in e.Devices)
            {
                Console.WriteLine(device.DeviceName);
            }
            Console.WriteLine();
        }

        static void onDiscoverDevicesComplete(object sender, DiscoverDevicesEventArgs e)
        {
            Console.WriteLine("Device discovery complete");
            foreach (var device in e.Devices)
            {
                Console.WriteLine(device.DeviceName);
            }
            Console.WriteLine();

            _device = e.Devices.ToList().Where(p => p.DeviceName == DEVICE_NAME).FirstOrDefault();

            if (_device != null)
            {                
                Console.WriteLine("Selected {0} device with address {1}", _device.DeviceName, _device.DeviceAddress);               

                using (BluetoothClient client = new BluetoothClient())
                {
                    client.Connect(new BluetoothEndPoint(_device.DeviceAddress, BluetoothService.SerialPort));
                    Stream peerStream = client.GetStream();

                    for (int i = 0; i < 100; i++)
                    {
                        byte[] wb = Encoding.ASCII.GetBytes(string.Format("{0:X2} : This is a test : {1}{2}", i, DateTime.Now.ToString("o"), Environment.NewLine));
                        peerStream.Write(wb, 0, wb.Length);
                    }

                    byte [] buf = new byte[1024];
                    int readLength = peerStream.Read(buf, 0, buf.Length);
                    if (readLength > 0)
                    {
                        Console.WriteLine("Received {0} bytes", readLength);
                    }
                    else
                    {
                        Console.WriteLine("Connection is closed");
                    }
                }
            }
        }

        private static void displayBluetoothRadio()
        {
            BluetoothRadio myRadio = BluetoothRadio.PrimaryRadio;
            if (myRadio == null)
            {
                Console.WriteLine("No radio hardware or unsupported software stack");
                return;
            }
            RadioMode mode = myRadio.Mode;
            // Warning: LocalAddress is null if the radio is powered-off.
            Console.WriteLine("* Radio, address: {0:C}", myRadio.LocalAddress);
            Console.WriteLine("Mode: " + mode.ToString());
            Console.WriteLine("Name: " + myRadio.Name);
            Console.WriteLine("HCI Version: " + myRadio.HciVersion
                + ", Revision: " + myRadio.HciRevision);
            Console.WriteLine("LMP Version: " + myRadio.LmpVersion
                + ", Subversion: " + myRadio.LmpSubversion);
            Console.WriteLine("ClassOfDevice: " + myRadio.ClassOfDevice.ToString()
                + ", device: " + myRadio.ClassOfDevice.Device.ToString()
                + " / service: " + myRadio.ClassOfDevice.Service.ToString());
            //
            //
            // Enable discoverable mode
            Console.WriteLine();
            myRadio.Mode = RadioMode.Discoverable;
            Console.WriteLine("Radio Mode now: " + myRadio.Mode.ToString());
            Console.WriteLine();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM