diff --git a/BrickController2/BrickController2.Android/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs b/BrickController2/BrickController2.Android/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs index c31c1ba2..881e0877 100644 --- a/BrickController2/BrickController2.Android/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs +++ b/BrickController2/BrickController2.Android/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs @@ -1,5 +1,6 @@ using BrickController2.DeviceManagement.CaDA; using BrickController2.Protocols; +using System; namespace BrickController2.Droid.PlatformServices.DeviceManagement.CaDA; @@ -8,6 +9,8 @@ public class CaDAPlatformService : ICaDAPlatformService private const int HeaderOffset = 15; private const int PayloadLength = 24; + private const int PayloadRev2Length = 16; + public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) { rfPayload = new byte[PayloadLength]; @@ -16,4 +19,11 @@ public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) return true; } + + public bool TryGetRfPayload(ushort manufacturerId, ReadOnlySpan rawData, out byte[] rfPayload) + { + // copy past data + rfPayload = rawData.ToArray(); + return rawData.Length == PayloadRev2Length; + } } diff --git a/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDADeviceManagerTests.cs b/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDADeviceManagerTests.cs index 3595d7ab..0f3fa083 100644 --- a/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDADeviceManagerTests.cs +++ b/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDADeviceManagerTests.cs @@ -30,6 +30,23 @@ public CaDADeviceManagerTests() _manager = new CaDADeviceManager(_preferencesService.Object, _cadaPlatformService.Object); } + [Fact] + public void CreateScanData_IosPlatform_PatchesAppIdIntoScanData() + { + // arrange + _cadaPlatformService.TryGetRfPayload_ForIosPlatform(); + + var scanData = _manager.CreateScanData(); + + scanData.Should().BeEquivalentTo(new[] + { + 0xC0, 0x3D, 0xCA, 0x66, 0x6D, 0x32, 0xB2, 0x9D, + 0xD2, 0x57, 0xA1, 0x5C, 0xC5, 0x05, 0xB0, 0x75, + 0xB1, 0x91, 0x48, 0x96, 0x77, 0xF8, 0x00, 0x8D, + 0x18, 0x19 + }); + } + [Fact] public void TryGetDevice_CadaCarWithMatchingAppId_ReturnsCaDaRaceCarDevice() { @@ -65,7 +82,7 @@ public void TryGetDevice_CadaCarWithMatchingAppId_ReturnsCaDaRaceCarDevice() } [Fact] - public void TryGetDevice_CadaCarWithDifferentAppId_ReturnsCaDaRaceCarDevice() + public void TryGetDevice_CadaCarWithDifferentAppId_ReturnsFalse() { byte[] manufacturerData = { @@ -91,4 +108,67 @@ public void TryGetDevice_CadaCarWithDifferentAppId_ReturnsCaDaRaceCarDevice() result.Should().BeFalse(); device.DeviceType.Should().Be(DeviceType.Unknown); } + + [Fact] + public void TryGetDevice_CadaCarRev2WithZeroAppId_ReturnsCaDaRaceCarRev2Device() + { + byte[] manufacturerData = + [ + // manufacturerId + 0xAA,0x11, + // CADA RaceCar + 0x11, + // 2 bytes AppID + 0x00, 0x00, + // Seed + 0x20, 0xB9, + // flag + 0x85, + 0x00, 0x00, 0x00, 0xA1, 0xCC, 0xB8, 0x92, 0xA0 + ]; + + var scanResult = new ScanResult("RaceCar-Revision2", "AA-BB-CC-DD", new Dictionary() + { + { 0xFF, manufacturerData } + }); + + var result = _manager.TryGetDevice(scanResult, out var device); + + result.Should().BeTrue(); + device.Should().BeEquivalentTo(new FoundDevice() + { + DeviceAddress = "AA-BB-CC-DD", + DeviceName = "RaceCar-Revision2", + DeviceType = DeviceType.CaDA_RaceCar_Rev2, + ManufacturerData = manufacturerData + }); + } + + [Fact] + public void TryGetDevice_CadaCarRev2WithSomeAppId_ReturnsFalse() + { + byte[] manufacturerData = + [ + // manufacturerId + 0xAA,0x11, + // CADA RaceCar + 0x11, + // 2 bytes AppID + 0x12, 0x34, + // Seed + 0x20, 0xB9, + // flag + 0x86, + 0x00, 0x00, 0x00, 0xA1, 0xCC, 0xB8, 0x92, 0xA0 + ]; + + var scanResult = new ScanResult("RaceCar-Revision2", "AA-BB-CC-DD", new Dictionary() + { + { 0xFF, manufacturerData } + }); + + var result = _manager.TryGetDevice(scanResult, out var device); + + result.Should().BeFalse(); + } } diff --git a/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDARaceCarRev2Tests.cs b/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDARaceCarRev2Tests.cs new file mode 100644 index 00000000..f7bbae09 --- /dev/null +++ b/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/CaDARaceCarRev2Tests.cs @@ -0,0 +1,77 @@ +using BrickController2.DeviceManagement; +using BrickController2.DeviceManagement.CaDA; +using BrickController2.PlatformServices.BluetoothLE; +using FluentAssertions; +using Moq; +using Xunit; + +namespace BrickController2.Tests.DeviceManagement.CaDA; + +public class CaDARaceCarRev2Tests +{ + private readonly CaDARaceCarRev2 _device; + private readonly Mock _cadaPlatformService = new(MockBehavior.Strict); + + public CaDARaceCarRev2Tests() + { + _device = new CaDARaceCarRev2("RC", + "1-2-3", + [ + // manufacturerId + 0xAA, 0x11, + // CADA RaceCar? + 0x11, + // 2 bytes AppID + 0x00, 0x00, + // Device Seed + 0x20, 0xB9, + // some flag(s) + 0x86, 0x00, 0x00, 0x00, + // hardware id + 0xA1, 0xCC, 0xB8, 0x92, 0xA0 + ], + Mock.Of(MockBehavior.Strict), + Mock.Of(MockBehavior.Strict), + _cadaPlatformService.Object); + } + + [Fact] + public void TryGetTelegram_ConnectTelegram_ReturnsProperDatagram() + { + // arrange + _cadaPlatformService.TryGetRfPayload_ForIosPlatform(); + + var result = _device.TryGetTelegram(true, out var telegram); + + result.Should().BeTrue(); + telegram.Should().StartWith(new byte[] + { + 0xC0, 0x00, 0xAA, 0x11, 0x11, + 0x20, 0xB9, + 0xAD, 0x42, + 0x6B, 0x6B, 0x00, /*0xEB,*/ 0xD6, //TODO checksum + 0xA1, 0xCC, 0xB8, 0x92, 0xA0, + 0xEF, 0xF2, 0xC5, 0x67, 0x8F, 0x9F, 0xF1, 0xF8 + }); + } + + [Fact] + public void TryGetTelegram_WithZeroValuesTelegram_ReturnsProperDatagram() + { + // arrange + _cadaPlatformService.TryGetRfPayload_ForIosPlatform(); + + var result = _device.TryGetTelegram(false, out var telegram); + + result.Should().BeTrue(); + telegram.Should().StartWith(new byte[] + { + 0xC0, 0x00, 0xBB, 0x11, 0x11, + 0x20, 0xB9, + 0xAD, 0x42, + 0x80, 0x80, 0x80, 0x80, //TODO checksum + 0xA1, 0xCC, 0xB8, 0x92, 0xB0, + 0xEF, 0xF2, 0xC5, 0x67, 0x8F, 0x9F, 0xF1, 0xF8 + }); + } +} diff --git a/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/MockSetups.cs b/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/MockSetups.cs new file mode 100644 index 00000000..bcdce27a --- /dev/null +++ b/BrickController2/BrickController2.Tests/DeviceManagement/CaDA/MockSetups.cs @@ -0,0 +1,37 @@ +using BrickController2.DeviceManagement.CaDA; +using BrickController2.Protocols; +using Moq; + +namespace BrickController2.Tests.DeviceManagement.CaDA; + +public static class MockSetups +{ + public static Mock TryGetRfPayload_ForIosPlatform(this Mock mock) + { + const int HeaderOffset = 13; + const int PayloadLength = 26; + + mock.Setup(m => m.TryGetRfPayload(It.IsAny(), out It.Ref.IsAny)) + .Callback((byte[] rawData, out byte[] rfPayload) => + { + rfPayload = new byte[PayloadLength]; + int payloadLength = CryptTools.GetRfPayload(CaDAProtocol.SeedArray, + CaDAProtocol.HeaderArray, + rawData, + HeaderOffset, + CaDAProtocol.CTXValue1, + CaDAProtocol.CTXValue2, + rfPayload); + + // fill rest of array + byte bVar = 0x18; // initial value + for (int index = payloadLength; index < PayloadLength; index++) + { + rfPayload[index] = bVar++; + } + }) + .Returns(true); + + return mock; + } +} diff --git a/BrickController2/BrickController2.WinUI/Extensions/AdvertismentExtensions.cs b/BrickController2/BrickController2.WinUI/Extensions/AdvertisementExtensions.cs similarity index 71% rename from BrickController2/BrickController2.WinUI/Extensions/AdvertismentExtensions.cs rename to BrickController2/BrickController2.WinUI/Extensions/AdvertisementExtensions.cs index 5526b3b4..e9d1bac1 100644 --- a/BrickController2/BrickController2.WinUI/Extensions/AdvertismentExtensions.cs +++ b/BrickController2/BrickController2.WinUI/Extensions/AdvertisementExtensions.cs @@ -2,7 +2,7 @@ namespace BrickController2.Windows.Extensions; -public static class AdvertismentExtensions +public static class AdvertisementExtensions { public static string GetLocalName(this BluetoothLEAdvertisementReceivedEventArgs args) => args.Advertisement.LocalName.TrimEnd(); @@ -10,5 +10,6 @@ public static class AdvertismentExtensions public static bool CanCarryData(this BluetoothLEAdvertisementReceivedEventArgs args) => args.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse || - args.AdvertisementType == BluetoothLEAdvertisementType.ConnectableUndirected; + args.AdvertisementType == BluetoothLEAdvertisementType.ConnectableUndirected || + args.AdvertisementType == BluetoothLEAdvertisementType.NonConnectableUndirected; // some per advertisement devices which are not directly connectable } diff --git a/BrickController2/BrickController2.WinUI/PlatformServices/BluetoothLE/BleScanner.cs b/BrickController2/BrickController2.WinUI/PlatformServices/BluetoothLE/BleScanner.cs index d0a4f556..7e54b653 100644 --- a/BrickController2/BrickController2.WinUI/PlatformServices/BluetoothLE/BleScanner.cs +++ b/BrickController2/BrickController2.WinUI/PlatformServices/BluetoothLE/BleScanner.cs @@ -59,7 +59,7 @@ private void _passiveWatcher_Received(BluetoothLEAdvertisementWatcher sender, Bl else if (args.Advertisement.DataSections?.Count > 0) { // allow processing of advertised data from a device - var advertismentData = args.Advertisement.DataSections + var advertisementData = args.Advertisement.DataSections .Where(s => AdvertismentDataTypes.Contains(s.DataType)) .ToDictionary(s => s.DataType, s => s.Data.ToByteArray()); @@ -68,7 +68,7 @@ private void _passiveWatcher_Received(BluetoothLEAdvertisementWatcher sender, Bl // if no local name is set, try to get it from the cache _deviceNameCache.TryGetValue(args.BluetoothAddress, out deviceName); - _scanCallback(new ScanResult(deviceName, bluetoothAddress, advertismentData)); + _scanCallback(new ScanResult(deviceName, bluetoothAddress, advertisementData)); } } @@ -79,6 +79,7 @@ private void _passiveWatcher_Stopped(BluetoothLEAdvertisementWatcher sender, Blu private void _activeWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { + var bt = args.BluetoothAddress; if (!args.CanCarryData()) { return; @@ -92,17 +93,17 @@ private void _activeWatcher_Received(BluetoothLEAdvertisementWatcher sender, Blu var bluetoothAddress = args.BluetoothAddress.ToBluetoothAddressString(); - var advertismentData = args.Advertisement.DataSections + var advertisementData = args.Advertisement.DataSections .Where(s => AdvertismentDataTypes.Contains(s.DataType)) .ToDictionary(s => s.DataType, s => s.Data.ToByteArray()); // enrich data with name manually (SBrick do not like CompleteLocalName, but Buwizz3 requires it) - if (!advertismentData.ContainsKey(BluetoothLEAdvertisementDataTypes.CompleteLocalName)) + if (!advertisementData.ContainsKey(BluetoothLEAdvertisementDataTypes.CompleteLocalName)) { - advertismentData[BluetoothLEAdvertisementDataTypes.CompleteLocalName] = Encoding.ASCII.GetBytes(deviceName); + advertisementData[BluetoothLEAdvertisementDataTypes.CompleteLocalName] = Encoding.ASCII.GetBytes(deviceName); } - _scanCallback(new ScanResult(deviceName, bluetoothAddress, advertismentData)); + _scanCallback(new ScanResult(deviceName, bluetoothAddress, advertisementData)); } public void Stop() diff --git a/BrickController2/BrickController2.WinUI/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs b/BrickController2/BrickController2.WinUI/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs index 04bc9467..245a6be5 100644 --- a/BrickController2/BrickController2.WinUI/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs +++ b/BrickController2/BrickController2.WinUI/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs @@ -1,5 +1,6 @@ using BrickController2.DeviceManagement.CaDA; using BrickController2.Protocols; +using System; namespace BrickController2.Windows.PlatformServices.DeviceManagement.CaDA; @@ -9,6 +10,8 @@ public class CaDAPlatformService : ICaDAPlatformService private const int PayloadOffset = 3; private const int PayloadLength = 24 + PayloadOffset; + private const int PayloadRev2Length = 16; + public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) { // JK: @@ -28,4 +31,11 @@ public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) return true; } + + public bool TryGetRfPayload(ushort manufacturerId, ReadOnlySpan rawData, out byte[] rfPayload) + { + // copy past data + rfPayload = rawData.ToArray(); + return rawData.Length == PayloadRev2Length; + } } diff --git a/BrickController2/BrickController2.iOS/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs b/BrickController2/BrickController2.iOS/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs index 3bca9878..73b1c792 100644 --- a/BrickController2/BrickController2.iOS/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs +++ b/BrickController2/BrickController2.iOS/PlatformServices/DeviceManagement/CaDA/CaDAPlatformService.cs @@ -1,5 +1,6 @@ using BrickController2.DeviceManagement.CaDA; using BrickController2.Protocols; +using System; namespace BrickController2.iOS.PlatformServices.DeviceManagement.CaDA; @@ -8,6 +9,19 @@ public class CaDAPlatformService : ICaDAPlatformService private const int HeaderOffset = 13; private const int PayloadLength = 26; + private const int SessionLength = 8; + private const int PayloadRev2Length = 16; + + // Session - 8 bytes per application run + private static readonly Lazy _sessionPostfix = new(() => + { + var session = new byte[SessionLength]; + Random.Shared.NextBytes(session); + return session; + }); + + public ReadOnlySpan Session => _sessionPostfix.Value; + public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) { rfPayload = new byte[PayloadLength]; @@ -22,4 +36,16 @@ public bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload) return true; } + + public bool TryGetRfPayload(short manufacturerId, ReadOnlySpan rawData, out byte[] rfPayload) + { + rfPayload = new byte[2 + rawData.Length + PayloadLength]; + + BitConverter.TryWriteBytes(rfPayload, manufacturerId); + + rawData.CopyTo(rfPayload.AsSpan(2)); + Session.CopyTo(rfPayload.AsSpan(2 + rawData.Length)); + + return rawData.Length == PayloadRev2Length; + } } diff --git a/BrickController2/BrickController2/DeviceManagement/CaDA/CaDADeviceManager.cs b/BrickController2/BrickController2/DeviceManagement/CaDA/CaDADeviceManager.cs index 624a9865..253d15c3 100644 --- a/BrickController2/BrickController2/DeviceManagement/CaDA/CaDADeviceManager.cs +++ b/BrickController2/BrickController2/DeviceManagement/CaDA/CaDADeviceManager.cs @@ -82,7 +82,18 @@ protected override bool TryGetDeviceByManufacturerData(ScanResult scanResult, Fo } break; - // extend if needed to other CaDA devices + // extend if needed to other CaDA devices + case 0x11aa: + if (IsCadaRaceCarRev2(manufacturerData)) + { + device = template with + { + DeviceType = DeviceType.CaDA_RaceCar_Rev2 + }; + return true; + } + break; + } // no match device = default; @@ -104,15 +115,23 @@ private bool IsCadaRaceCar(ReadOnlySpan manufacturerData) manufacturerData[9] == _appIdChecksumMaskArray[2]; } + private static bool IsCadaRaceCarRev2(ReadOnlySpan manufacturerData) => manufacturerData.Length == 16 && + manufacturerData[2] == 0x11 && + // response has 2 zeros as AppId - not connected yet + manufacturerData[3] == 0x00 && + manufacturerData[4] == 0x00 && + // flag not connected yet + manufacturerData[7] == 0x85; + /// - /// gets or creates an App-persistant AppIdentifier + /// gets or creates an App-persistent AppIdentifier /// /// reference to preferencesService singleton /// byte array containing the AppIdentifier private static byte[] GetAppIdentifier(IPreferencesService preferencesService) { byte[] appIdChecksumMaskArray; - // gets or creates an App-persistant AppIdentifier + // gets or creates an App-persistent AppIdentifier try { if (preferencesService.ContainsKey(APPIDKEY, SECTION)) diff --git a/BrickController2/BrickController2/DeviceManagement/CaDA/CaDARaceCarRev2.cs b/BrickController2/BrickController2/DeviceManagement/CaDA/CaDARaceCarRev2.cs new file mode 100644 index 00000000..df52db1f --- /dev/null +++ b/BrickController2/BrickController2/DeviceManagement/CaDA/CaDARaceCarRev2.cs @@ -0,0 +1,107 @@ +using BrickController2.DeviceManagement.IO; +using BrickController2.PlatformServices.BluetoothLE; +using BrickController2.Protocols; +using System; + +namespace BrickController2.DeviceManagement.CaDA; + +/// +/// CaDA RaceCar - hardware revision 2 +/// +internal class CaDARaceCarRev2 : BluetoothAdvertisingDevice +{ + private readonly byte[] _payloadTemplate; + + private readonly ICaDAPlatformService _cadaPlatformService; + private readonly OutputValuesGroup _outputValues = new(3); + + public CaDARaceCarRev2(string name, string address, byte[] deviceData, IDeviceRepository deviceRepository, IBluetoothLEService bleService, ICaDAPlatformService cadaPlatformService) + : base(name, address, deviceData, deviceRepository, bleService) + { + _cadaPlatformService = cadaPlatformService; + + if (deviceData?.Length == 16) + { + _payloadTemplate = deviceData; + // seed + _payloadTemplate[3] = deviceData[5]; + _payloadTemplate[4] = deviceData[6]; + //TODO app id + _payloadTemplate[5] = 0xAD; + _payloadTemplate[6] = 0x42; + } + else + { + throw new ApplicationException($"Invalid {nameof(deviceData)} array!"); + } + } + public override DeviceType DeviceType => DeviceType.CaDA_RaceCar_Rev2; + + /// + /// manufacturerId to advertise + /// + protected override ushort ManufacturerId => CaDAProtocol.ManufacturerID; + + public override int NumberOfChannels => 3; + + public override void SetOutput(int channelNo, float value) + { + CheckChannel(channelNo); + value = CutOutputValue(value); + + var rawValue = (short)(value * 0x7F); // scale and cast + + if (_outputValues.SetOutput(channelNo, rawValue)) + { + _bluetoothAdvertisingDeviceHandler.SetChannelState(channelNo, rawValue == 0x80); + _bluetoothAdvertisingDeviceHandler.NotifyDataChanged(); + } + } + + protected override void InitDevice() + { + } + + protected override void DisconnectDevice() + { + } + + protected internal bool TryGetTelegram(bool getConnectTelegram, out byte[] currentData) + { + // compose payload + var payload = _payloadTemplate.AsSpan(); + + // device data: AA vs BB flag + payload[2] = getConnectTelegram ? (byte)0xAA : (byte)0xBB; + + // command data + if (getConnectTelegram) + { + ReadOnlySpan command = [0x6B, 0x6B, 0x00]; + command.CopyTo(payload.Slice(7)); + } + else + { + _outputValues.TryGetValues(out var values); + + payload[7] = (byte)Math.Max(0, Math.Min(0x80 - values[0], 0xFF)); + payload[8] = (byte)Math.Max(0, Math.Min(0x80 + values[1], 0xFF)); + payload[9] = (byte)Math.Max(0, Math.Min(0x80 + values[2], 0xFF)); + } + //TODO XOR using AppId + //currentData[9] ^= 0xAD; + // currentData[10] ^= 0x42; + payload[10] = (byte)(payload[7] + payload[8] + payload[9]); + + // update flags + payload[15] = getConnectTelegram ? (byte)0xA0 : (byte)0xB0; + + return _cadaPlatformService.TryGetRfPayload(ManufacturerId, payload, out currentData); + } + + /// + /// Get or create BluetoothAdvertisingDeviceHandler + /// + protected override BluetoothAdvertisingDeviceHandler GetBluetoothAdvertisingDeviceHandler() + => new(_bleService, ManufacturerId, TryGetTelegram, TimeSpan.MaxValue); +} diff --git a/BrickController2/BrickController2/DeviceManagement/CaDA/CaDa.cs b/BrickController2/BrickController2/DeviceManagement/CaDA/CaDa.cs new file mode 100644 index 00000000..172f0c2c --- /dev/null +++ b/BrickController2/BrickController2/DeviceManagement/CaDA/CaDa.cs @@ -0,0 +1,24 @@ +using BrickController2.DeviceManagement.DI; +using BrickController2.DeviceManagement.Vendors; +using BrickController2.Extensions; +using BrickController2.PlatformServices.BluetoothLE; + +namespace BrickController2.DeviceManagement.CaDA; + +/// +/// Vendor: CaDa with all its devices and implementation of IBluetoothLEDeviceManager +/// +internal class CaDa : Vendor +{ + public override string VendorName => "CaDA"; + + protected override void Register(VendorBuilder builder) + { + // classic devices + builder.ContainerBuilder.RegisterDevice(DeviceType.CaDA_RaceCar); + builder.ContainerBuilder.RegisterDevice(DeviceType.CaDA_RaceCar_Rev2); + + // device manager + builder.RegisterDeviceManager().As(); + } +} diff --git a/BrickController2/BrickController2/DeviceManagement/CaDA/ICaDAPlatformService.cs b/BrickController2/BrickController2/DeviceManagement/CaDA/ICaDAPlatformService.cs index 466f8add..45d4d186 100644 --- a/BrickController2/BrickController2/DeviceManagement/CaDA/ICaDAPlatformService.cs +++ b/BrickController2/BrickController2/DeviceManagement/CaDA/ICaDAPlatformService.cs @@ -1,4 +1,6 @@ -namespace BrickController2.DeviceManagement.CaDA; +using System; + +namespace BrickController2.DeviceManagement.CaDA; /// /// Interface definition for CaDA specific PlatformService @@ -6,4 +8,6 @@ public interface ICaDAPlatformService { bool TryGetRfPayload(byte[] rawData, out byte[] rfPayload); + + bool TryGetRfPayload(ushort manufacturerId, ReadOnlySpan rawData, out byte[] rfPayload); } diff --git a/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs b/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs index f8fc1442..76a5e2ee 100644 --- a/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs +++ b/BrickController2/BrickController2/DeviceManagement/DI/DeviceManagementModule.cs @@ -25,7 +25,6 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().Keyed(DeviceType.BuWizz3); builder.RegisterType().Keyed(DeviceType.Infrared); builder.RegisterType().Keyed(DeviceType.CircuitCubes); - builder.RegisterType().Keyed(DeviceType.CaDA_RaceCar); builder.RegisterType().Keyed(DeviceType.PfxBrick); builder.Register(c => @@ -40,7 +39,6 @@ protected override void Load(ContainerBuilder builder) // device managers builder.RegisterDeviceManager(); - builder.RegisterDeviceManager().As(); builder.RegisterDeviceManager(); builder.RegisterDeviceManager(); builder.RegisterDeviceManager(); diff --git a/BrickController2/BrickController2/DeviceManagement/DeviceType.cs b/BrickController2/BrickController2/DeviceManagement/DeviceType.cs index e7f2afd2..c5ab9586 100644 --- a/BrickController2/BrickController2/DeviceManagement/DeviceType.cs +++ b/BrickController2/BrickController2/DeviceManagement/DeviceType.cs @@ -23,5 +23,6 @@ public enum DeviceType MK5, MK3_8, RemoteControl, + CaDA_RaceCar_Rev2, } } diff --git a/BrickController2/BrickController2/DeviceManagement/IO/OutputValuesGroup.cs b/BrickController2/BrickController2/DeviceManagement/IO/OutputValuesGroup.cs index 87422415..71fd650c 100644 --- a/BrickController2/BrickController2/DeviceManagement/IO/OutputValuesGroup.cs +++ b/BrickController2/BrickController2/DeviceManagement/IO/OutputValuesGroup.cs @@ -26,7 +26,7 @@ public OutputValuesGroup(int channelCount) _sendAttemptsLeft = 0; } - public void SetOutput(int channel, TValue value) + public bool SetOutput(int channel, TValue value) { lock (_outputLock) { @@ -34,8 +34,10 @@ public void SetOutput(int channel, TValue value) { _outputValues[channel] = value; _sendAttemptsLeft = MAX_SEND_ATTEMPTS; + return true; } - } + } + return false; } public void Initialize() diff --git a/BrickController2/BrickController2/UI/Converters/DeviceTypeToImageConverter.cs b/BrickController2/BrickController2/UI/Converters/DeviceTypeToImageConverter.cs index ec45aa58..9ca28313 100644 --- a/BrickController2/BrickController2/UI/Converters/DeviceTypeToImageConverter.cs +++ b/BrickController2/BrickController2/UI/Converters/DeviceTypeToImageConverter.cs @@ -71,6 +71,7 @@ public class DeviceTypeToImageConverter : IValueConverter return ResourceHelper.GetImageResource("mk_diy_image.png"); case DeviceType.CaDA_RaceCar: + case DeviceType.CaDA_RaceCar_Rev2: return ResourceHelper.GetImageResource("cada_racecar_image.png"); case DeviceType.RemoteControl: diff --git a/BrickController2/BrickController2/UI/Converters/DeviceTypeToSmallImageConverter.cs b/BrickController2/BrickController2/UI/Converters/DeviceTypeToSmallImageConverter.cs index 532a6965..2f186487 100644 --- a/BrickController2/BrickController2/UI/Converters/DeviceTypeToSmallImageConverter.cs +++ b/BrickController2/BrickController2/UI/Converters/DeviceTypeToSmallImageConverter.cs @@ -63,6 +63,7 @@ public class DeviceTypeToSmallImageConverter : IValueConverter return ResourceHelper.GetImageResource("mk_diy_image_small.png"); case DeviceType.CaDA_RaceCar: + case DeviceType.CaDA_RaceCar_Rev2: return ResourceHelper.GetImageResource("cada_racecar_image_small.png"); case DeviceType.PfxBrick: