diff --git a/src/SharpBrick.PoweredUp.Cli/Commands/DevicesList.cs b/src/SharpBrick.PoweredUp.Cli/Commands/DevicesList.cs index 4ead5ba..07e4e8d 100644 --- a/src/SharpBrick.PoweredUp.Cli/Commands/DevicesList.cs +++ b/src/SharpBrick.PoweredUp.Cli/Commands/DevicesList.cs @@ -23,6 +23,7 @@ public DevicesList(ILegoWirelessProtocol protocol, DiscoverPorts discoverPorts) public async Task ExecuteAsync(SystemType knownSystemType) { Console.WriteLine("Discover Ports. Receiving Messages ..."); + protocol.DiscoveryMode = true; await protocol.ConnectAsync(knownSystemType); // registering to bluetooth notification diff --git a/src/SharpBrick.PoweredUp.Cli/Commands/DumpStaticPortInfo.cs b/src/SharpBrick.PoweredUp.Cli/Commands/DumpStaticPortInfo.cs index 8de4259..fba6db7 100644 --- a/src/SharpBrick.PoweredUp.Cli/Commands/DumpStaticPortInfo.cs +++ b/src/SharpBrick.PoweredUp.Cli/Commands/DumpStaticPortInfo.cs @@ -22,6 +22,7 @@ public DumpStaticPortInfo(ILegoWirelessProtocol protocol, DiscoverPorts discover public async Task ExecuteAsync(SystemType knownSystemType, byte portId, bool headerEnabled) { Console.WriteLine($"Discover Port {portId}. Receiving Messages ..."); + protocol.DiscoveryMode = true; await protocol.ConnectAsync(knownSystemType); // registering to bluetooth notification diff --git a/src/SharpBrick.PoweredUp/Protocol/ILegoWirelessProtocol.cs b/src/SharpBrick.PoweredUp/Protocol/ILegoWirelessProtocol.cs index ec0dfdf..74874ae 100644 --- a/src/SharpBrick.PoweredUp/Protocol/ILegoWirelessProtocol.cs +++ b/src/SharpBrick.PoweredUp/Protocol/ILegoWirelessProtocol.cs @@ -17,4 +17,10 @@ public interface ILegoWirelessProtocol : IDisposable ProtocolKnowledge Knowledge { get; } IServiceProvider ServiceProvider { get; } + + /// + /// Indicates if this is running in normal mode, using known configurations/behavior of hub and devices (default). + /// Or in discovery mode where all hub and devices are queried for their knowledge and any known configuration is ignored. + /// + bool DiscoveryMode { get; set; } } diff --git a/src/SharpBrick.PoweredUp/Protocol/Knowledge/KnowledgeManager.cs b/src/SharpBrick.PoweredUp/Protocol/Knowledge/KnowledgeManager.cs index 0305624..343f757 100644 --- a/src/SharpBrick.PoweredUp/Protocol/Knowledge/KnowledgeManager.cs +++ b/src/SharpBrick.PoweredUp/Protocol/Knowledge/KnowledgeManager.cs @@ -103,7 +103,17 @@ public static bool ApplyStaticProtocolKnowledge(LegoWirelessMessage message, Pro return applicableMessage; } - public static Task ApplyDynamicProtocolKnowledge(LegoWirelessMessage message, ProtocolKnowledge knowledge, IDeviceFactory deviceFactory) + + /// + /// + /// + /// + /// + /// + /// Indicates to apply known information about reported devices. + /// On normal operation this should be used a discovery can takes tens of seconds. Don't use this on discovery as the cached information will be mixed with received information. + /// + public static Task ApplyDynamicProtocolKnowledge(LegoWirelessMessage message, ProtocolKnowledge knowledge, IDeviceFactory deviceFactory, bool useCachedInformation = true) { HubInfo hub; PortInfo port; @@ -125,7 +135,10 @@ public static Task ApplyDynamicProtocolKnowledge(LegoWirelessMessage message, Pr port.HardwareRevision = msg.HardwareRevision; port.SoftwareRevision = msg.SoftwareRevision; - AddCachePortAndPortModeInformation(msg.IOTypeId, msg.HardwareRevision, msg.SoftwareRevision, hub, port, knowledge, deviceFactory); + if (useCachedInformation) + { + AddCachePortAndPortModeInformation(msg.IOTypeId, msg.HardwareRevision, msg.SoftwareRevision, hub, port, knowledge, deviceFactory); + } break; case HubAttachedIOForDetachedDeviceMessage msg: port = knowledge.Port(msg.HubId, msg.PortId); @@ -144,7 +157,10 @@ public static Task ApplyDynamicProtocolKnowledge(LegoWirelessMessage message, Pr port.HardwareRevision = partOfVirtual.HardwareRevision; port.SoftwareRevision = partOfVirtual.SoftwareRevision; - AddCachePortAndPortModeInformation(msg.IOTypeId, partOfVirtual.HardwareRevision, partOfVirtual.SoftwareRevision, hub, port, knowledge, deviceFactory); + if (useCachedInformation) + { + AddCachePortAndPortModeInformation(msg.IOTypeId, partOfVirtual.HardwareRevision, partOfVirtual.SoftwareRevision, hub, port, knowledge, deviceFactory); + } port.IsVirtual = true; port.PortAId = msg.PortAId; diff --git a/src/SharpBrick.PoweredUp/Protocol/LegoWirelessProtocol.cs b/src/SharpBrick.PoweredUp/Protocol/LegoWirelessProtocol.cs index a099677..dace327 100644 --- a/src/SharpBrick.PoweredUp/Protocol/LegoWirelessProtocol.cs +++ b/src/SharpBrick.PoweredUp/Protocol/LegoWirelessProtocol.cs @@ -17,13 +17,16 @@ public class LegoWirelessProtocol : ILegoWirelessProtocol private readonly ILogger _logger; private readonly IDeviceFactory _deviceFactory; private readonly Subject<(byte[] data, LegoWirelessMessage message)> _upstreamSubject; - + public ProtocolKnowledge Knowledge { get; } = new ProtocolKnowledge(); public IObservable<(byte[] data, LegoWirelessMessage message)> UpstreamRawMessages => _upstreamSubject; public IObservable UpstreamMessages => _upstreamSubject.Select(x => x.message); public IServiceProvider ServiceProvider { get; } + /// + public bool DiscoveryMode { get; set; } = false; + public LegoWirelessProtocol(BluetoothKernel kernel, ILogger logger, IDeviceFactory deviceFactory, IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; @@ -39,7 +42,7 @@ public async Task ConnectAsync(SystemType knownSystemType = default) await KnowledgeManager.ApplyDynamicProtocolKnowledge(new HubPropertyMessage(HubProperty.SystemTypeId, HubPropertyOperation.Update, knownSystemType) { HubId = 0x00, - }, Knowledge, _deviceFactory); + }, Knowledge, _deviceFactory, UseCachedInformation()); await _kernel.ConnectAsync(); _logger.LogInformation("Connected to device, getting protocol information"); @@ -49,7 +52,7 @@ await _kernel.ReceiveBytesAsync(async data => { var message = MessageEncoder.Decode(data, Knowledge); - await KnowledgeManager.ApplyDynamicProtocolKnowledge(message, Knowledge, _deviceFactory); + await KnowledgeManager.ApplyDynamicProtocolKnowledge(message, Knowledge, _deviceFactory, UseCachedInformation()); _upstreamSubject.OnNext((data, message)); } @@ -73,7 +76,7 @@ public async Task SendMessageAsync(LegoWirelessMessage message) { var data = MessageEncoder.Encode(message, Knowledge); - await KnowledgeManager.ApplyDynamicProtocolKnowledge(message, Knowledge, _deviceFactory); + await KnowledgeManager.ApplyDynamicProtocolKnowledge(message, Knowledge, _deviceFactory, UseCachedInformation()); await _kernel.SendBytesAsync(data); } @@ -84,6 +87,11 @@ public async Task SendMessageAsync(LegoWirelessMessage message) throw; } } + + private bool UseCachedInformation() + { + return !DiscoveryMode; + } #region Disposable Pattern private bool disposedValue;