简体   繁体   中英

Reading Data from a BLE device in C#

I have to write a Windows desktop application to read logs from a portable medical device. 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. 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. The device which is being developed by another company is constrained to be BLE-only so I can't use the SPP. The data will be in the 10kb to 100 kb size range.

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.

I'm somewhat new to BLE so I'm not sure which way to go to get the actual log entries. 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.

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. Does this approach look reasonable?

Here is some code I wrote a few years ago to talk to my LG G3 phone via Bluetooth. I used the InTheHand library. I don't recall if it supports 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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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