diff --git a/src/devices/Gpio/Drivers/VirtualGpioController.cs b/src/devices/Gpio/Drivers/VirtualGpioController.cs index cf6fe4dd83..38774d51d1 100644 --- a/src/devices/Gpio/Drivers/VirtualGpioController.cs +++ b/src/devices/Gpio/Drivers/VirtualGpioController.cs @@ -144,9 +144,16 @@ public override ComponentInformation QueryComponentInformation() { ComponentInformation self = new ComponentInformation(this, "Virtual GPIO Controller"); - foreach (var cp in self.SubComponents) + HashSet controllers = new HashSet(); + foreach (var pin in _pins) { - self.AddSubComponent(cp); + controllers.Add(pin.Value.OldController); + self.Properties.Add($"PinMapping{pin.Key}", pin.Value.OldPinNumber.ToString()); + } + + foreach (var c in controllers) + { + self.AddSubComponent(c.QueryComponentInformation()); } return self; @@ -270,13 +277,15 @@ public GpioPin GetOpenPin(int pinNumber) /// public override WaitForEventResult WaitForEvent(int pinNumber, PinEventTypes eventTypes, CancellationToken cancellationToken) { - throw new NotImplementedException(); + var pin = _pins[pinNumber]; + return pin.OldController.WaitForEvent(pin.OldPinNumber, eventTypes, cancellationToken); } /// - public override ValueTask WaitForEventAsync(int pinNumber, PinEventTypes eventTypes, CancellationToken token) + public override async ValueTask WaitForEventAsync(int pinNumber, PinEventTypes eventTypes, CancellationToken token) { - throw new NotImplementedException(); + var pin = _pins[pinNumber]; + return await pin.OldController.WaitForEventAsync(pin.OldPinNumber, eventTypes, token); } } } diff --git a/src/devices/Gpio/Drivers/VirtualGpioPin.cs b/src/devices/Gpio/Drivers/VirtualGpioPin.cs index 5a9d33b4c2..0b01cdc7bd 100644 --- a/src/devices/Gpio/Drivers/VirtualGpioPin.cs +++ b/src/devices/Gpio/Drivers/VirtualGpioPin.cs @@ -30,6 +30,8 @@ protected internal VirtualGpioPin(GpioPin oldPin, int newPinNumber, GpioControll internal int OldPinNumber => _oldPin.PinNumber; + internal GpioController OldController => _oldPin.Controller; + public override event PinChangeEventHandler ValueChanged { add diff --git a/src/devices/Gpio/tests/VirtualGpioTests.cs b/src/devices/Gpio/tests/VirtualGpioTests.cs index 07c2d52a32..270c702847 100644 --- a/src/devices/Gpio/tests/VirtualGpioTests.cs +++ b/src/devices/Gpio/tests/VirtualGpioTests.cs @@ -8,6 +8,8 @@ using System.Device.I2c; using System.Device.Spi; using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using Moq; using Xunit; @@ -171,15 +173,76 @@ public void Callback3() controller.SetPinMode(7, PinMode.Input); bool wasCalled = false; int callbackAsNo = 0; - controller.RegisterCallbackForPinValueChangedEvent(7, PinEventTypes.Falling, (o, e) => + + void Callback(object o, PinValueChangedEventArgs e) { wasCalled = true; callbackAsNo = e.PinNumber; - }); + } + + controller.RegisterCallbackForPinValueChangedEvent(7, PinEventTypes.Falling, Callback); _mockedGpioDriver.Object.FireEventHandler(1, PinEventTypes.Rising); // We expect no callback when we expect a Falling event but a Rising event is triggered Assert.False(wasCalled); + controller.UnregisterCallbackForPinValueChangedEvent(7, Callback); + } + + [Fact] + public async Task WaitForEventAsync() + { + VirtualGpioController controller = new VirtualGpioController(); + var myPin = _baseController.OpenPin(1); + controller.Add(7, myPin); + _mockedGpioDriver.Setup(x => x.IsPinModeSupportedEx(1, PinMode.Input)).Returns(true); + controller.SetPinMode(7, PinMode.Input); + _mockedGpioDriver.Setup(x => x.WaitForEventEx(1, PinEventTypes.Rising | PinEventTypes.Falling, It.IsAny())) + .Returns(new WaitForEventResult() { EventTypes = PinEventTypes.Falling, TimedOut = false }); + var ret = controller.WaitForEventAsync(7, PinEventTypes.Rising | PinEventTypes.Falling, TimeSpan.FromMinutes(1)); + WaitForEventResult result = await ret; + Assert.False(result.TimedOut); + Assert.Equal(PinEventTypes.Falling, result.EventTypes); + } + + [Fact] + public void CtorCall() + { + var myPin1 = _baseController.OpenPin(99); + var myPin2 = _baseController.OpenPin(100); + VirtualGpioController controller = new VirtualGpioController(new GpioPin[] { myPin1, myPin2 }); + Assert.NotNull(controller.GetOpenPin(0)); + Assert.NotNull(controller.GetOpenPin(1)); + } + + [Fact] + public void CtorCall2() + { + var myPin1 = _baseController.OpenPin(99); + var myPin2 = _baseController.OpenPin(100); + VirtualGpioController controller = new VirtualGpioController(new Dictionary + { + { 5, myPin1 }, + { 9, myPin2 } + }); + Assert.NotNull(controller.GetOpenPin(5)); + Assert.NotNull(controller.GetOpenPin(9)); + Assert.Throws(() => controller.GetOpenPin(0)); + } + + [Fact] + public void QueryComponentInformation() + { + var myPin1 = _baseController.OpenPin(99); + var myPin2 = _baseController.OpenPin(100); + VirtualGpioController controller = new VirtualGpioController(new Dictionary + { + { 5, myPin1 }, + { 9, myPin2 } + }); + + var result = controller.QueryComponentInformation(); + Assert.NotNull(result); + Assert.NotEmpty(result.SubComponents); } } }