Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading;
using System.Threading.Tasks;

using static BrickController2.Protocols.GattProtocol;

namespace BrickController2.DeviceManagement
{
internal class BuWizz2Device : BluetoothDevice, IDeviceType<BuWizz2Device>
Expand All @@ -17,10 +19,6 @@ internal class BuWizz2Device : BluetoothDevice, IDeviceType<BuWizz2Device>
internal static readonly Guid SERVICE_UUID = new Guid("4e050000-74fb-4481-88b3-9919b1676e93");
private static readonly Guid CHARACTERISTIC_UUID = new Guid("000092d1-0000-1000-8000-00805f9b34fb");

private static readonly Guid SERVICE_UUID_DEVICE_INFORMATION = new Guid("0000180a-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_MODEL_NUMBER = new Guid("00002a24-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_FIRMWARE_REVISION = new Guid("00002a26-0000-1000-8000-00805f9b34fb");

private static readonly TimeSpan VoltageMeasurementTimeout = TimeSpan.FromSeconds(5);

private const string SwapChannelsSettingName = "BuWizz2SwapChannels";
Expand Down Expand Up @@ -98,9 +96,9 @@ protected override async Task<bool> ValidateServicesAsync(IEnumerable<IGattServi
var service = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID);
_characteristic = service?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID);

var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID_DEVICE_INFORMATION);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_FIRMWARE_REVISION);
_modelNumberCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_MODEL_NUMBER);
var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == Services.DeviceInformation);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.FirmwareRevision);
_modelNumberCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.ModelNumber);

if (_characteristic is not null)
{
Expand All @@ -110,6 +108,14 @@ protected override async Task<bool> ValidateServicesAsync(IEnumerable<IGattServi
return _characteristic is not null && _firmwareRevisionCharacteristic is not null && _modelNumberCharacteristic is not null;
}

protected override async ValueTask BeforeDisconnectAsync(CancellationToken token)
{
if (_characteristic != null && _bleDevice != null)
{
await _bleDevice.DisableNotificationAsync(_characteristic, token);
}
}

protected override void BeforeDisconnectCleanup()
{
// Clear cached characteristic references to prevent using stale native Android objects on reconnection
Expand All @@ -120,7 +126,7 @@ protected override void BeforeDisconnectCleanup()

protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[] data)
{
if (characteristicGuid != _characteristic!.Uuid || data.Length < 4 || data[0] != 0x00)
if (characteristicGuid != _characteristic?.Uuid || data.Length < 4 || data[0] != 0x00)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;

using static BrickController2.Protocols.BuWizz3Protocol;
using static BrickController2.Protocols.GattProtocol;

namespace BrickController2.DeviceManagement
{
Expand All @@ -33,10 +34,6 @@ internal class BuWizz3Device : BluetoothDevice
internal static readonly Guid SERVICE_UUID = new Guid("500592d1-74fb-4481-88b3-9919b1676e93");
private static readonly Guid CHARACTERISTIC_UUID = new Guid("50052901-74fb-4481-88b3-9919b1676e93");

private static readonly Guid SERVICE_UUID_DEVICE_INFORMATION = new Guid("0000180a-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_MODEL_NUMBER = new Guid("00002a24-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_FIRMWARE_REVISION = new Guid("00002a26-0000-1000-8000-00805f9b34fb");

private static readonly TimeSpan VoltageMeasurementTimeout = TimeSpan.FromSeconds(5);
private static readonly bool ApplyWriteWorkaround = DeviceInfo.Platform == DevicePlatform.Android;

Expand Down Expand Up @@ -68,7 +65,7 @@ internal class BuWizz3Device : BluetoothDevice
private IGattCharacteristic? _modelNumberCharacteristic;
private IGattCharacteristic? _firmwareRevisionCharacteristic;

public BuWizz3Device(string name, string address, byte[] deviceData, IEnumerable<NamedSetting> settings, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
public BuWizz3Device(string name, string address, IEnumerable<NamedSetting> settings, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
: base(name, address, deviceRepository, bleService)
{
// apply current limit for PU ports
Expand Down Expand Up @@ -195,12 +192,20 @@ protected override Task<bool> ValidateServicesAsync(IEnumerable<IGattService>? s
var service = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID);
_characteristic = service?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID);

var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID_DEVICE_INFORMATION);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_FIRMWARE_REVISION);
_modelNumberCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_MODEL_NUMBER);
var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == Services.DeviceInformation);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.FirmwareRevision);
_modelNumberCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.ModelNumber);

return Task.FromResult(_characteristic != null && _firmwareRevisionCharacteristic != null && _modelNumberCharacteristic != null);
}
protected override async ValueTask BeforeDisconnectAsync(CancellationToken token)
{
if (_characteristic != null && _bleDevice != null)
{
await _bleDevice.DisableNotificationAsync(_characteristic, token);
}
}

protected override void BeforeDisconnectCleanup()
{
// Clear cached characteristic references to prevent using stale native Android objects on reconnection
Expand All @@ -211,7 +216,7 @@ protected override void BeforeDisconnectCleanup()

protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[] data)
{
if (characteristicGuid != _characteristic!.Uuid || data.Length < 54 || data[0] != 0x01)
if (characteristicGuid != _characteristic?.Uuid || data.Length < 54 || data[0] != 0x01)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal class BuWizzDevice : BluetoothDevice

private IGattCharacteristic? _characteristic;

public BuWizzDevice(string name, string address, byte[] deviceData, IEnumerable<NamedSetting> settings, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
public BuWizzDevice(string name, string address, IEnumerable<NamedSetting> settings, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
: base(name, address, deviceRepository, bleService)
{
// apply values (if any) or default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Threading;
using System.Threading.Tasks;

using static BrickController2.Protocols.GattProtocol;

namespace BrickController2.DeviceManagement
{
internal class CircuitCubeDevice : BluetoothDevice
Expand All @@ -17,10 +19,6 @@ internal class CircuitCubeDevice : BluetoothDevice
private static readonly Guid CHARACTERISTIC_UUID_WRITE = new Guid("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
private static readonly Guid CHARACTERISTIC_UUID_NOTIFY = new Guid("6e400003-b5a3-f393-e0a9-e50e24dcca9e");

private static readonly Guid SERVICE_UUID_DEVICE_INFORMATION = new Guid("0000180a-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_HARDWARE_REVISION = new Guid("00002a27-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_FIRMWARE_REVISION = new Guid("00002a26-0000-1000-8000-00805f9b34fb");

// Turn off power to all motors command: <0>
private static readonly byte[] TURN_OFF_ALL_COMMAND = new[] { (byte)'0' };
// Battery Status Command: <b>
Expand All @@ -39,7 +37,7 @@ internal class CircuitCubeDevice : BluetoothDevice
private IGattCharacteristic? _hardwareRevisionCharacteristic;
private IGattCharacteristic? _firmwareRevisionCharacteristic;

public CircuitCubeDevice(string name, string address, byte[] deviceData, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
public CircuitCubeDevice(string name, string address, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
: base(name, address, deviceRepository, bleService)
{
}
Expand Down Expand Up @@ -73,9 +71,9 @@ protected override async Task<bool> ValidateServicesAsync(IEnumerable<IGattServi
var service = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID);
_writeCharacteristic = service?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_WRITE);

var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID_DEVICE_INFORMATION);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_FIRMWARE_REVISION);
_hardwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_HARDWARE_REVISION);
var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == Services.DeviceInformation);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.FirmwareRevision);
_hardwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.HardwareRevision);

_notifyCharacteristic = service?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_NOTIFY);
if (_notifyCharacteristic is not null)
Expand All @@ -88,7 +86,7 @@ protected override async Task<bool> ValidateServicesAsync(IEnumerable<IGattServi

protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[] data)
{
if (characteristicGuid != _notifyCharacteristic!.Uuid || data.Length <= 1)
if (characteristicGuid != _notifyCharacteristic?.Uuid || data.Length <= 1)
return;

var bateryVoltage = data.ToAsciiStringSafe();
Expand All @@ -97,6 +95,14 @@ protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[]
BatteryVoltage = bateryVoltage;
}
}
protected override async ValueTask BeforeDisconnectAsync(CancellationToken token)
{
if (_notifyCharacteristic != null && _bleDevice != null)
{
await _bleDevice.DisableNotificationAsync(_notifyCharacteristic, token);
}
}

protected override void BeforeDisconnectCleanup()
{
_writeCharacteristic = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ protected override void BeforeDisconnectCleanup()

protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[] data)
{
if (data.Length < 4 || Characteristic is null || characteristicGuid != Characteristic.Uuid)
if (data.Length < 4 || characteristicGuid != Characteristic?.Uuid)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected override async Task<bool> ValidateServicesAsync(IEnumerable<IGattServi

protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[] data)
{
if (characteristicGuid != _notifyCharacteristic!.Uuid || data.Length == 0)
if (characteristicGuid != _notifyCharacteristic?.Uuid || data.Length == 0)
return;

if (data.Length == 1) // notification
Expand All @@ -84,6 +84,14 @@ protected override void OnCharacteristicChanged(Guid characteristicGuid, byte[]
}
}

protected override async ValueTask BeforeDisconnectAsync(CancellationToken token)
{
if (_notifyCharacteristic != null && _bleDevice != null)
{
await _bleDevice.DisableNotificationAsync(_notifyCharacteristic, token);
}
}

protected override void BeforeDisconnectCleanup()
{
_writeCharacteristic = null;
Expand Down
24 changes: 10 additions & 14 deletions BrickController2/BrickController2/DeviceManagement/SBrickDevice.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
using BrickController2.Helpers;
using BrickController2.PlatformServices.BluetoothLE;
using BrickController2.Protocols;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using static BrickController2.DeviceManagement.Vengit.SBrickProtocol;

namespace BrickController2.DeviceManagement
{
internal class SBrickDevice : BluetoothDevice
{
private const int MAX_SEND_ATTEMPTS = 10;

private static readonly Guid SERVICE_UUID_DEVICE_INFORMATION = new Guid("0000180a-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_FIRMWARE_REVISION = new Guid("00002a26-0000-1000-8000-00805f9b34fb");
private static readonly Guid CHARACTERISTIC_UUID_HARDWARE_REVISION = new Guid("00002a27-0000-1000-8000-00805f9b34fb");
private static readonly Guid SERVICE_UUID_REMOTE_CONTROL = new Guid("4dc591b0-857c-41de-b5f1-15abda665b0c");
private static readonly Guid CHARACTERISTIC_UUID_REMOTE_CONTROL = new Guid("02b8cbcc-0e25-4bda-8790-a15f53e6010f");
private static readonly Guid CHARACTERISTIC_UUID_QUICK_DRIVE = new Guid("489a6ae0-c1ab-4c9c-bdb2-11d373c1b7fb");

private readonly int[] _outputValues = new int[4];
private readonly int[] _directions = new int[4];

Expand All @@ -31,7 +27,7 @@ internal class SBrickDevice : BluetoothDevice
private IGattCharacteristic? _remoteControlCharacteristic;
private IGattCharacteristic? _quickDriveCharacteristic;

public SBrickDevice(string name, string address, byte[] deviceData, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
public SBrickDevice(string name, string address, IDeviceRepository deviceRepository, IBluetoothLEService bleService)
: base(name, address, deviceRepository, bleService)
{
}
Expand Down Expand Up @@ -65,13 +61,13 @@ public override void SetOutput(int channel, float value)

protected override Task<bool> ValidateServicesAsync(IEnumerable<IGattService>? services, CancellationToken token)
{
var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID_DEVICE_INFORMATION);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_FIRMWARE_REVISION);
_hardwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_HARDWARE_REVISION);
var deviceInformationService = services?.FirstOrDefault(s => s.Uuid == GattProtocol.Services.DeviceInformation);
_firmwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == GattProtocol.Characteristics.FirmwareRevision);
_hardwareRevisionCharacteristic = deviceInformationService?.Characteristics?.FirstOrDefault(c => c.Uuid == GattProtocol.Characteristics.HardwareRevision);

var remoteControlService = services?.FirstOrDefault(s => s.Uuid == SERVICE_UUID_REMOTE_CONTROL);
_remoteControlCharacteristic = remoteControlService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_REMOTE_CONTROL);
_quickDriveCharacteristic = remoteControlService?.Characteristics?.FirstOrDefault(c => c.Uuid == CHARACTERISTIC_UUID_QUICK_DRIVE);
var remoteControlService = services?.FirstOrDefault(s => s.Uuid == Services.RemoteControl);
_remoteControlCharacteristic = remoteControlService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.RemoteControlCommand);
_quickDriveCharacteristic = remoteControlService?.Characteristics?.FirstOrDefault(c => c.Uuid == Characteristics.QuickDrive);

return Task.FromResult(
_firmwareRevisionCharacteristic is not null &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public static class Characteristics
/// Remote control service: Remote Control Commands characteristic UUID
/// </summary>
public static readonly Guid RemoteControlCommand = new("02b8cbcc-0e25-4bda-8790-a15f53e6010f");

/// <summary>
/// Remote control service: Quick Drive characteristic UUID
/// </summary>
public static readonly Guid QuickDrive = new("489a6ae0-c1ab-4c9c-bdb2-11d373c1b7fb");
}

// SBrick Light configuration
Expand Down
Loading
Loading