GATT Service
Peripheral Manager (GATT Server)
This allows you to accept client connections
Each OS has different limitations and functions
On iOS - you need to advertise as well as create a gatt server
Services
Services are nothing more than categories in the overall perspective of BluetoothLE. You should be aware that you must setup all characters & descriptors that belong to a service BEFORE starting advertising or adding a service to a running server!
You should always know your service UUID for future client consumption!
From a functionality perspective, there is not a lot you do with services
General Setup
After creating your server instance and a service, you can do the following:
You should always assign a known GUID ID to your characteristic in order for your GATT service to be consumed by a client.
Below are examples of a basic read/write characteristic and a notification characteristic setup
var service = CrossBleAdapter.Current.AddService(new Guid(...));
var characteristic = service.AddCharacteristic( Guid.NewGuid(), CharacteristicProperties.Read | CharacteristicProperties.Write | CharacteristicProperties.WriteWithoutResponse, GattPermissions.Read | GattPermissions.Write);
var notifyCharacteristic = service.AddCharacteristic( Guid.NewGuid(), CharacteristicProperties.Indicate | CharacteristicProperties.Notify, GattPermissions.Read | GattPermissions.Write);
Setup a Service
These are the heart and soul of BLE. This is where data is exchanged between client & server
await hostingManager.AddService( "Your Service UUID", true, sb => { byte[]? currentData = null;
var notifier = sb.AddCharacteristic("Your NotifyCharacteristicUuid" , x => x.SetNotification(sub => { var smsg = sub.IsSubscribing ? "Subscribed" : "UnSubscribed"; this.Log($"{sub.Peripheral.Uuid} {smsg} to Characteristic");
return Task.CompletedTask; }));
sb.AddCharacteristic(BleConfiguration.ReadCharacteristicUuid, x => x.SetRead(request => { var data = currentData ?? new byte[] { 0x0 }; this.Log($"{request.Peripheral.Uuid} Read Characteristic", data);
return Task.FromResult(GattResult.Success(data)); }));
sb.AddCharacteristic(BleConfiguration.WriteCharacteristicUuid, cb => cb.SetWrite(async request => { currentData = request.Data; this.Log($"{request.Peripheral.Uuid} Wrote to Characteristic", request.Data);
if (notifier.SubscribedCentrals.Count > 0) { await notifier.Notify(request.Data); this.Log("Notification Broadcasted to subscribers"); } }, WriteOptions.Write | WriteOptions.WriteWithoutResponse)); });
Managed Characteristic
A managed characteristic as shown below, respresents a single characteristic but multiple operations
[BleGattCharacteristic("Your Service UUID", "Your Characteristic UUID")]public class MyManagedCharacteristics : BleGattCharacteristic{ readonly SampleSqliteConnection conn;
public MyManagedCharacteristics(SampleSqliteConnection conn) => this.conn = conn;
// setup any initial wiring before the characteristic is started public override Task OnStart() { return Task.Completed; }
// cleanup any resources/timers/etc you may have had running public override void OnStop() => base.OnStop();
// override this to make your characteristic readable public override Task<GattResult> OnRead(ReadRequest request) => base.OnRead(request);
// override this to make your characteristic writeable public override Task OnWrite(WriteRequest request) => base.OnWrite(request);
// override this to make your characteristic notify based public override Task OnSubscriptionChanged(IPeripheral peripheral, bool subscribed) => base.OnSubscriptionChanged(peripheral, subscribed);}
To register your managed characteristic, during your host building operation (ie. MauiProgram.cs), add the following:
builder.Services.AddBleHostedCharacteristic<MyManagedCharacteristics>();
And lastly to start/stop your managed characteristic
// now inject/resolve the Shiny.BluetoothLE.Hosting.IBleHostingManager and now you can toggle on/offShiny.BluetoothLE.Hosting.IBleHostingManager hostingManager;if (hostingManager.IsRegisteredServicesAttached){ hostingManager.DetachRegisteredServices();}else{ await hostingManager.AttachRegisteredServices();}