2

I am developing a c# console application that is going to have to communicate with multiple mobile phones (both iOS and android). My team's first thought was to use bluetooth since a wi-fi/internet connection may not always be available. I wrote code using 32Feet.net (https://inthehand.com/components/32feet/) that used bluetooth classic. However, the use of bluetooth classic on IPhone for anything other than audio devices seems to be strongly discouraged/not possible. So, I tired to use 32Feet's Bluetooth Low Energy framework. I was unable to figure out how to use it because it is outdated and the documentation isn't strong. I then switched to the demo version of BTFramework (https://www.btframework.com) which advertises support for Bluetooth Low Energy but I was unable to get that working as well. So my questions are:

  • Is there any other Bluetooth Low Energy frameworks that I should take a look at? (I would like the framework to be cross-platform but I am targeting Windows 10 and later)
  • Am I doing something wrong?
  • Should I be using Bluetooth in the first place?

Here is some of my code for BTFramework, I closely followed the documentation:

using wclBluetooth;
using wclCommon;
using System.Text;

public class BluetoothManager
{
    // BTFramework objects
    private readonly wclBluetoothManager _wclBluetoothManager = new wclBluetoothManager();
    private wclBluetoothRadio? _radio;
    private wclGattServer? _gattServer;
    
    private readonly List<wclGattServerClient> _clients = new List<wclGattServerClient>();
    private bool _btReady;

    private byte[]? _recvBuffer;
    private int? _lastClientToWriteId;

    public void Init()
    {
        _wclBluetoothManager.Open();
        _radio = GetRadio();
        if (!_radio.LeSupported)
        {
            Console.WriteLine("This device does not support Bluetooth Low Energy.");

            return;
        }
        
        
        _radio.GetName(out string radioName);
        _radio.SetConnectable(true);
        _radio.SetDiscoverable(true);
        Console.WriteLine($"Bluetooth radio name: {radioName}");

        _gattServer = new wclGattServer();
        // define callbacks
        _gattServer.OnClientConnected += OnClientConnected;
        _gattServer.OnWrite += OnWrite;
        _gattServer.Initialize(_radio);
        if (!_gattServer.Initialized)
        {
            Console.WriteLine("Gatt server was not initialized.");

            return;
        }
        
        _btReady = true;
        Console.WriteLine("Bluetooth Initialization completed.");
    }

    private wclBluetoothRadio GetRadio()
    {
        Int32 res = _wclBluetoothManager.GetLeRadio(out wclBluetoothRadio bluetoothRadio);
        if (res != wclErrors.WCL_E_SUCCESS)
        {
            throw new BluetoothNotAvailableException("Error getting bluetooth radio.");
        }
        return bluetoothRadio;
    }

    private void OnClientConnected(object sender, wclGattServerClient client)
    {
        _clients.Add(client);

        Console.WriteLine($"New client connected.");
    }

    private void OnWrite(object sender, wclGattServerClient client, wclGattLocalCharacteristic characteristic, byte[] data)
    {
        _recvBuffer = data;
        _lastClientToWriteId = _clients.IndexOf(client);
    }

Thanks for your help!

  • 32Feet.Net Bluetooth Classic: Although this worked when testing with another windows laptop, iPhone support for bluetooth classic is very limited.
  • 32Feet.Net Bluetooth Low Energy: Unable to figure out how to use the framework
  • BTFramework Bluetooth Low Energy: Couldn't get the callbacks to get called/couldn't recognize newly connected phones.
BigBoyTaco
  • 23
  • 2
  • have you checked the BLE eco systems around Xamarin and Maui? https://github.com/shinyorg/shiny/tree/v2.7.0 Windows only: https://learn.microsoft.com/en-us/windows/uwp/devices-sensors/bluetooth-low-energy-overview – Falco Alexander Mar 22 '23 at 08:27

1 Answers1

1

First I would say that we have great and fast support so you can contact us at any time you like: www.btframework.com/contacts.htm We would be happy to help to resolve the issue.

Now about your question: on Windows platform there is no way to detect when remote device connects to a GATT server. Bluetooth Framework internally emulates this and calls the OnClientConnected event when client subscribes, reads or writes characteristic.

Also, as you run your application in console you need to change default internal synchronization. By default Bluetooth Framework uses Windows messages to synchronize events with main/UI thread. It works OK for UI based applications but for console or services it needs message processing loop.

Fortunately Bluetooth Framework allows to change synchronization. There are two: APC and Thread. APC one uses Asynchronous Procedure Call. Thread synchronization uses separate thread and all the events always called in separate thread.

To change default synchronization the very first link in your code before using any Bluetooth Framework methods must be: wclMessageBroadcaster.SetSyncMethod(wclMessageSynchronizationKind.skThread); This changes default synchronization to Thread one. Put this code line in the very beginning ofr your Init() method.

Good starting point for console GATT server is GattServer demo from IoT demos folder. Even it is called IoT it can run on desktop OS as well.

Please do not hesitate to contact us if you have any questions.