Skip to content

Commit

Permalink
Add additional debug logging
Browse files Browse the repository at this point in the history
  • Loading branch information
DJDavid98 committed Oct 8, 2023
1 parent ce87cb7 commit c83c707
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 23 deletions.
18 changes: 18 additions & 0 deletions BluetoothHeartrateModule/BluetoothHeartrateModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public BluetoothHeartrateModule()

protected override BluetoothHeartrateProvider CreateProvider()
{
LogDebug("Creating provider");
var provider = new BluetoothHeartrateProvider(this);
provider.OnHeartrateUpdate += SendWebcoketHeartrate;
return provider;
Expand All @@ -29,8 +30,14 @@ protected override BluetoothHeartrateProvider CreateProvider()
base.Log(message);
}

internal new void LogDebug(string message)
{
base.LogDebug(message);
}

protected override void CreateAttributes()
{
LogDebug("Creating attributes");
base.CreateAttributes();
CreateSetting(BluetoothHeartrateSetting.DeviceMac, "Device MAC address", "MAC address of the Bluetooth heartrate monitor", string.Empty);

Expand All @@ -43,19 +50,23 @@ protected override void CreateAttributes()

protected override async void OnModuleStart()
{
LogDebug("Starting module");
CreateWatcher();
base.OnModuleStart();
if (GetWebocketEnabledSetting())
{
LogDebug("Starting wsServer");
await wsServer.Start();
}
}

protected override void OnModuleStop()
{
LogDebug("Stopping module");
StopWatcher();
if (GetWebocketEnabledSetting())
{
LogDebug("Stopping wsServer");
wsServer.Stop();
}
base.OnModuleStop();
Expand Down Expand Up @@ -87,6 +98,7 @@ private async void SendWebcoketHeartrate(int heartrate)
{
if (!GetWebocketEnabledSetting())
{
LogDebug("Not sending HR to websocket because it is disabled");
return;
}

Expand All @@ -96,14 +108,17 @@ internal BluetoothLEAdvertisementWatcher CreateWatcher()
{
if (watcher == null)
{
LogDebug("Creating new watcher");
watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active };
LogDebug("Adding watcher stopped event handler");
watcher.Stopped += Watcher_Stopped;
}
return watcher;
}

private void Watcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)
{
LogDebug($"Watcher stopped, error: {args.Error}");
string scanStatus;
bool invokeDisconnect = true;
switch (args.Error)
Expand All @@ -122,6 +137,7 @@ private void Watcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLE
Log($"Stopped scanning for devices ({scanStatus})");
if (invokeDisconnect)
{
LogDebug("Invoking OnDisconnected action");
HeartrateProvider?.OnDisconnected?.Invoke();
}
}
Expand All @@ -130,6 +146,7 @@ internal void StartWatcher()
{
if (watcher != null)
{
LogDebug($"Starting watcher, current status: {watcher.Status}");
if (watcher.Status != BluetoothLEAdvertisementWatcherStatus.Started)
{
watcher.Start();
Expand All @@ -140,6 +157,7 @@ internal void StartWatcher()

internal void StopWatcher()
{
LogDebug("Stopping watcher");
watcher?.Stop();
}

Expand Down
4 changes: 2 additions & 2 deletions BluetoothHeartrateModule/BluetoothHeartrateModule.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<TargetFramework>net6.0-windows10.0.22621.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyVersion>1.3.3</AssemblyVersion>
<FileVersion>1.3.3</FileVersion>
<AssemblyVersion>1.3.4</AssemblyVersion>
<FileVersion>1.3.4</FileVersion>
<Authors>DJDavid98</Authors>
<Product>Bluetooth Heartrate</Product>
<ApplicationIcon>logo\logo.ico</ApplicationIcon>
Expand Down
80 changes: 69 additions & 11 deletions BluetoothHeartrateModule/BluetoothHeartrateProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public BluetoothHeartrateProvider(BluetoothHeartrateModule module)

public override void Initialise()
{
module.LogDebug("Initializing BluetoothHeartrateProvider");
if (module.GetDeviceMacSetting() == string.Empty)
{
Log("Device MAC setting is not set, module will log discovered devices");
Expand All @@ -36,7 +37,9 @@ public override void Initialise()
return;
}

module.LogDebug("Registering watcher received handler");
module.watcher.Received += Watcher_Received;
module.LogDebug("Starting watcher");
module.StartWatcher();
}

Expand All @@ -49,45 +52,54 @@ public override async Task Teardown()

private void Reset()
{

module.LogDebug("Resetting provider");
if (module.watcher != null)
{
module.LogDebug("Unregistering watcher received handler");
module.watcher.Received -= Watcher_Received;
}
module.LogDebug("Clearing device names");
deviceNames.Clear();
module.LogDebug("Clearing missing characteristics");
missingCharacteristicDevices.Clear();
ResetDevice();
processingData = false;
}

private async void ResetDevice()
{
module.LogDebug("Resetting device data");
if (heartRateService != null)
{
module.LogDebug("Resetting heartRateService");
try
{
heartRateService.Dispose();
}
catch (ObjectDisposedException)
{
// Ignore if object is already disposed
module.LogDebug("heartRateService already disposed");
}
heartRateService = null;
}
if (heartRateCharacteristic != null)
{
module.LogDebug("Resetting heartRateCharacteristic");
try
{
heartRateCharacteristic.ValueChanged -= HeartRateCharacteristic_ValueChanged;
}
catch (ObjectDisposedException)
{
// Ignore if object is already disposed
module.LogDebug("heartRateCharacteristic already disposed");
}
heartRateCharacteristic = null;
}
if (currentDevice != null)
{
module.LogDebug("Resetting currentDevice");
try
{
currentDevice.ConnectionStatusChanged -= Device_ConnectionStatusChanged;
Expand All @@ -96,6 +108,7 @@ private async void ResetDevice()
catch (ObjectDisposedException)
{
// Ignore if object is already disposed
module.LogDebug("currentDevice already disposed");
}
currentDevice = null;
}
Expand All @@ -104,64 +117,87 @@ private async void ResetDevice()

private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{

var advertisementId = Guid.NewGuid().ToString();
// We need a prefix to follow the logs as advertisements can come in pretty rapidly
var logPrefix = $"[{advertisementId}]";
module.LogDebug($"{logPrefix} Watcher received advertisement");
var advertisementMac = Converter.FormatAsMac(args.BluetoothAddress);
module.LogDebug($"{logPrefix} advertisementMac = {advertisementMac}");
var deviceMacSetting = module.GetDeviceMacSetting();
module.LogDebug($"{logPrefix} deviceMacSetting = {deviceMacSetting}");
var isConfiguredDevice = advertisementMac == deviceMacSetting;
module.LogDebug($"{logPrefix} isConfiguredDevice = {isConfiguredDevice}");
if (deviceMacSetting == string.Empty || isConfiguredDevice)
{
var deviceNamesValue = deviceNames.GetValueOrDefault(advertisementMac, null);
module.LogDebug($"{logPrefix} Cached device name: {deviceNamesValue}");
if (deviceNamesValue == null)
{
module.LogDebug($"{logPrefix} Creating device name resolver");
var dnr = new DeviceNameResolver(module);
var advertisementDeviceName = await dnr.GetDeviceNameAsync(args.Advertisement, args.BluetoothAddress);
deviceNames[advertisementMac] = advertisementDeviceName;
module.LogDebug($"{logPrefix} Resolving device name");
var resolvedDeviceName = await dnr.GetDeviceNameAsync(args.Advertisement, args.BluetoothAddress);
module.LogDebug($"{logPrefix} Caching device name");
deviceNames[advertisementMac] = resolvedDeviceName;
if (!isConfiguredDevice)
{
Log($"Discovered device: {advertisementDeviceName} (MAC: {advertisementMac})");
Log($"Discovered device: {resolvedDeviceName} (MAC: {advertisementMac})");
}
}
if (!isConfiguredDevice)
{
return;
}
}

if (!isConfiguredDevice)
{
// Not the droid we're looking for
module.LogDebug($"{logPrefix} Not the configured device, stop further advertisement processing");
return;
}
if (heartRateCharacteristic != null)
{
// Characteristic already found
module.LogDebug($"{logPrefix} heartRateCharacteristic already found, stop further advertisement processing");
return;
}

if (processingData) return;
if (processingData)
{
module.LogDebug($"{logPrefix} Currently another advertisement is being processed, ignore this advertisement");
return;
}
processingData = true;
module.LogDebug($"{logPrefix} Begin processing advertisement data");
try
{
if (currentDevice == null)
{
module.LogDebug($"{logPrefix} Setting currrent device");
currentDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
var currentDeviceName = deviceNames[advertisementMac] ?? "Unknown";
Log($"Found device named {currentDeviceName} for MAC {advertisementMac}");
module.SetDeviceName(currentDeviceName);
module.LogDebug($"{logPrefix} Register connection status change handler");
currentDevice.ConnectionStatusChanged += Device_ConnectionStatusChanged;
}
else
{
module.LogDebug($"{logPrefix} Current device already set");
}

var missungUnknown = !missingCharacteristicDevices.Contains(deviceMacSetting);
module.LogDebug($"{logPrefix} missungUnknown = {missungUnknown}");
module.LogDebug($"{logPrefix} Finding HeratRate service");
var services = await currentDevice.GetGattServicesForUuidAsync(GattServiceUuids.HeartRate, BluetoothCacheMode.Uncached);
if (services.Services.Count > 0)
{
module.LogDebug($"{logPrefix} Queueuing all found services for cleanup");
IEnumerable<GattDeviceService> cleanupServices = services.Services;
var firstService = cleanupServices.First();
if (missungUnknown)
{
Log("Found heartrate service");
}
var characteristics = await firstService.GetCharacteristicsForUuidAsync(GattCharacteristicUuids.HeartRateMeasurement, BluetoothCacheMode.Uncached);
module.LogDebug($"{logPrefix} Finding HeartRateMeasurement characteristic");
if (characteristics.Characteristics.Count > 0)
{
if (heartRateCharacteristic == null)
Expand All @@ -181,11 +217,15 @@ private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, Blue
// Remove receive handler
if (module.watcher != null)
{
module.LogDebug($"{logPrefix} Unregistering watcher recived handler");
module.watcher.Received -= Watcher_Received;
}
module.LogDebug($"{logPrefix} Invoking OnConnected action");
OnConnected?.Invoke();
Log("Connection successful");
module.LogDebug($"{logPrefix} Stopping watcher");
module.StopWatcher();
module.LogDebug($"{logPrefix} Excluding first service from cleanup");
cleanupServices = services.Services.Skip(1);
}
else
Expand All @@ -194,16 +234,26 @@ private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, Blue
}
}
}
else
{
module.LogDebug($"{logPrefix} No characteristics found");
}

if (cleanupServices.Any())
{
module.LogDebug($"{logPrefix} Cleaning up services queued for cleanup");
foreach (var service in cleanupServices)
service.Dispose();
}
}
else
{
module.LogDebug($"{logPrefix} No services found");
}

if (heartRateCharacteristic == null && missungUnknown)
{
module.LogDebug($"{logPrefix} Adding device to missing characteristic list");
missingCharacteristicDevices.Add(deviceMacSetting);
throw new Exception("No heartrate characteristic found");
}
Expand All @@ -216,22 +266,30 @@ private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, Blue
finally
{
processingData = false;
module.LogDebug($"{logPrefix} Stopped processing advertisement");
}
}

private void HeartRateCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
module.LogDebug("HeartRateCharacteristic_ValueChanged");
var data = new byte[args.CharacteristicValue.Length];
module.LogDebug("Reading new hartrate value into buffer");
DataReader.FromBuffer(args.CharacteristicValue).ReadBytes(data);

OnHeartrateUpdate?.Invoke(data[1]);
var updateData = data[1];
module.LogDebug($"Invoking OnHeartrateUpdate action with data {updateData}");
OnHeartrateUpdate?.Invoke(updateData);
}

private async void Device_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
module.LogDebug("Device_ConnectionStatusChanged");
module.LogDebug($"sender.ConnectionStatus = {sender.ConnectionStatus}");
if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected)
{
Log("Current device disconected");
module.LogDebug($"Invoking OnDisconnected action");
OnDisconnected?.Invoke();
}
}
Expand Down
Loading

0 comments on commit c83c707

Please sign in to comment.