Connect to BTLE device using 32feet.net using unique service protocol

11

I have a bluetooth low energy (BTLE) device, which I need to connect to my PC. To do so, I use the windows API reference in a desktop WPF app.

The bluetooth device is rather simple: 1 service, 2 characteristics (one read/notify, one to write to).

To make below code work, add the following references to the WPF (for windows 10):
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd

Windows API code for C#

public GattDeviceService BLEService;
public GattCharacteristic BLEData_ReadNotify;
public GattCharacteristic BLEData_Write;
private static readonly Guid Guid_service = new Guid("25FB9E91-1616-448D-B5A3-F70A64BDA73A");
public static readonly Guid Characteristics_ReadNotify = new Guid("C3FBC9E2-676B-9FB5-3749-2F471DCF07B2");
public static readonly Guid Characteristics_Write = new Guid("D6AF9B3C-FE92-1CB2-F74B-7AFB7DE57E6D");


// Find all BTLE devices that have the service Guid: Guid_service
public void findandconnect() { 
    var BTLEdeviceList = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(Guid_service));
    // lets assume at least one device is found, store it's id.
    id = BTLEdeviceList[0].id;

    // Connect to the SERVICE of the device
    BLEService = await GattDeviceService.FromIdAsync(id);

    // Get the first "ReadNotify" characteristics of that service
    BLEData_ReadNotify = BLEService.GetCharacteristics(Characteristics_ReadNotify).First();
    // If that value changes, update an event
    BLEData_ReadNotify.ValueChanged += BLEData_ValueChanged;

    // Also get the first "write" characteristics of that service
    BLEData_Write = BLEService.GetCharacteristics(Characteristics_Write).First();
    // and tell that characteristics to NOTIFY me if the BTLE device has an update.
    await BLEData_ReadNotify.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
    // Successfully connected

    // Send the command "RUN\r" to the write characteristics, to let it start to execute the program
    byte[] buffer = Encoding.ASCII.GetBytes("RUN" + "\r");
    IBuffer ibuffer = buffer.AsBuffer();
    // Sending "RUN"
    await BLEData_Write.WriteValueAsync(ibuffer);
}
// And here should be some event function for the ValueChanged

Well, it works, kinda... It is unstable as hell, most of the time it generates errors that can't be solved:

Line: BLEData_ReadNotify.WriteClientCharacteri... produces There is no user session key for the specified logon session. (Exception from HRESULT: 0x80070572)

and The semaphore timeout period has expired. (Exception from HRESULT: 0x80070079). This second error is less common and appears when the script first does not receive anything, then via a timer it tries to send the RUN command again, then all crashed and the error apears.

Searching on stackoverflow and many sites, I found that both above errors are impossible to solve. Hence my question:

Can the above code be rewritten using 32Feet.net?

In 2012 it was not possible link to use ble at all, but perhaps now it is? Using the scanning method in this answer link, I CAN find my BLE device when it it NOT paired.

so, I tried some code

// mac is mac address of local bluetooth device
Guid Guid_service = new Guid("25FB9E91-1616-448D-B5A3-F70A64BDA73A");
localEndpoint = new BluetoothEndPoint(myRadio.LocalAddress, Guid_service);
// client is used to manage connections
localClient = new BluetoothClient(localEndpoint);

BluetoothAddress a = new BluetoothAddress(new byte[] { 180, 99, 76, 86, 31, 21 });
Guid Guid_service = new Guid("25FB9E91-1616-448D-B5A3-F70A64BDA73A");
localClient.Connect(a, Guid_service);

NetworkStream stream = localClient.GetStream();

but I am stranded at the line localClient.Connect with the error: An exception of type 'System.Net.Sockets.SocketException' occurred. Additional information: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

Can the windows API code be rewritten in 32feet.net, ifso, how to proceed?

Note: I tried to connect to a BT2.1 device using windows native .net code, but the serial port is unstable and a pain in the head. With 32feet.net it now works splendidly over SerialPort, very stable and it connect each time!

c#
wpf
bluetooth
32feet
btle
asked on Stack Overflow Nov 12, 2015 by Jeffrey • edited May 23, 2017 by Community

1 Answer

0

I had simular issue with this relating to

the semaphore timeout period has expired. (Exception from HRESULT: 0x80070079).

My issue was resolved with .net 4.7.1. Also I needed to make sure I had the latest microsoft bluetooth driver for the bluetooth device i was using

SerialPort streams no longer terminate the process when exceptions occur on the background thread. This can happen when removing a USB serial port while in use. This new behavior is controlled by the Switch.System.IO.Ports.DoNotCatchSerialStreamThreadExceptions AppContext switch. This switch is set to truetf get by default when targeting .NET 4.7 or below. [428461, System.dll, Bug]

https://github.com/Microsoft/dotnet/blob/0745983093568027ff931672d9db021e3e120b5b/releases/net471/dotnet471-changes.md

Update: Actually it appears to be 2 issues in one. .net bug and a firmware issue where the device was never turning back on the bluetooth module.

answered on Stack Overflow Oct 30, 2017 by nate_weldon • edited Nov 1, 2017 by nate_weldon

User contributions licensed under CC BY-SA 3.0