public void When_ResetFcnt_In_Device_With_Pending_Changes_Should_Have_HasFrameCountChanges_True() { var devAddr = new DevAddr(0x1231); // Non zero fcnt up using var target = CreateDefaultDevice(); target.SetFcntUp(1); target.AcceptFrameCountChanges(); target.ResetFcnt(); Assert.Equal(0U, target.FCntUp); Assert.Equal(0U, target.FCntDown); Assert.True(target.HasFrameCountChanges); // Non zero fcnt down using var secondConnectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object); using var secondTarget = new LoRaDevice(devAddr, new DevEui(0x12312), secondConnectionManager); secondTarget.SetFcntDown(1); secondTarget.AcceptFrameCountChanges(); secondTarget.ResetFcnt(); Assert.Equal(0U, secondTarget.FCntUp); Assert.Equal(0U, secondTarget.FCntDown); Assert.True(secondTarget.HasFrameCountChanges); // Non zero fcnt down and up using var thirdConnectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object); using var thirdTarget = new LoRaDevice(devAddr, new DevEui(0x12312), thirdConnectionManager); thirdTarget.SetFcntDown(1); thirdTarget.SetFcntDown(2); thirdTarget.AcceptFrameCountChanges(); thirdTarget.ResetFcnt(); Assert.Equal(0U, thirdTarget.FCntUp); Assert.Equal(0U, thirdTarget.FCntDown); Assert.True(thirdTarget.HasFrameCountChanges); }
public async Task When_Initialized_New_OTAA_Device_Should_Have_All_Properties() { var appKey = TestKeys.CreateAppKey(0xABC0200000000000, 0x09); var joinEui = new JoinEui(0xABC0200000000009); var twin = TestUtils.CreateTwin( desired: new Dictionary <string, object> { { "AppEUI", joinEui.ToString() }, { "AppKey", appKey.ToString() }, { "GatewayID", "mygateway" }, { "SensorDecoder", "DecoderValueSensor" }, { "$version", 1 }, }, reported: new Dictionary <string, object> { { "$version", 1 }, }); this.loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None)) .ReturnsAsync(twin); using var connectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object); using var loRaDevice = new LoRaDevice(null, new DevEui(0xabc0200000000009), connectionManager); await loRaDevice.InitializeAsync(this.configuration); Assert.Equal(joinEui, loRaDevice.AppEui); Assert.Equal(appKey, loRaDevice.AppKey); Assert.Equal("mygateway", loRaDevice.GatewayID); Assert.Equal("DecoderValueSensor", loRaDevice.SensorDecoder); Assert.Equal(0U, loRaDevice.FCntDown); Assert.Equal(0U, loRaDevice.LastSavedFCntDown); Assert.Equal(0U, loRaDevice.FCntUp); Assert.Equal(0U, loRaDevice.LastSavedFCntUp); Assert.False(loRaDevice.HasFrameCountChanges); Assert.Null(loRaDevice.AppSKey); Assert.Null(loRaDevice.NwkSKey); Assert.Null(loRaDevice.DevAddr); Assert.Null(loRaDevice.DevNonce); Assert.Null(loRaDevice.NetId); Assert.False(loRaDevice.IsABP); Assert.False(loRaDevice.IsOurDevice); Assert.Null(loRaDevice.ReportedDwellTimeSetting); }
public async Task When_Device_AppEUI_Does_Not_Match_Should_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: ServerConfiguration.GatewayID)); var joinRequest = simulatedDevice.CreateJoinRequest(); var devEui = simulatedDevice.LoRaDevice.DevEui; simulatedDevice.LoRaDevice.AppEui = new JoinEui(0xFFFFFFFFFFFFFFFF); using var connectionManager = new SingleDeviceConnectionManager(LoRaDeviceClient.Object); using var loRaDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, connectionManager); loRaDevice.SetFcntDown(10); loRaDevice.SetFcntUp(20); var loRaDeviceRegistryMock = new Mock <ILoRaDeviceRegistry>(MockBehavior.Strict); loRaDeviceRegistryMock.Setup(x => x.RegisterDeviceInitializer(It.IsNotNull <ILoRaDeviceInitializer>())); loRaDeviceRegistryMock.Setup(x => x.GetDeviceForJoinRequestAsync(devEui, joinRequest.DevNonce)) .ReturnsAsync(() => loRaDevice); // Send to message processor using var messageProcessor = new MessageDispatcher( ServerConfiguration, loRaDeviceRegistryMock.Object, FrameCounterUpdateStrategyProvider); using var request = CreateWaitableRequest(TestUtils.GenerateTestRadioMetadata(), joinRequest); messageProcessor.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); Assert.Null(request.ResponseDownlink); // Device frame counts did not changed Assert.Equal(10U, loRaDevice.FCntDown); Assert.Equal(20U, loRaDevice.FCntUp); LoRaDeviceClient.VerifyAll(); LoRaDeviceApi.VerifyAll(); loRaDeviceRegistryMock.VerifyAll(); loRaDeviceRegistryMock.Setup(dr => dr.Dispose()); LoRaDeviceClient.Setup(ldc => ldc.Dispose()); }
public async Task When_ABP_Device_Is_Created_Should_Call_Initializers(string deviceGatewayID) { LoRaDeviceClient.Setup(ldc => ldc.Dispose()); var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, string.Empty); apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); using var connectionManager = new SingleDeviceConnectionManager(LoRaDeviceClient.Object); using var createdLoraDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, connectionManager); this.loraDeviceFactoryMock.Setup(x => x.CreateAndRegisterAsync(iotHubDeviceInfo, It.IsAny <CancellationToken>())) .ReturnsAsync(createdLoraDevice); // device will be initialized LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None)) .ReturnsAsync(simulatedDevice.CreateABPTwin()); using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object, DeviceCache); var initializer = new Mock <ILoRaDeviceInitializer>(); initializer.Setup(x => x.Initialize(createdLoraDevice)); target.RegisterDeviceInitializer(initializer.Object); using var request = WaitableLoRaRequest.Create(payload); target.GetLoRaRequestQueue(request).Queue(request); Assert.True(await request.WaitCompleteAsync()); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); // initializer was called initializer.VerifyAll(); }
public void When_ResetFcnt_In_NonZero_FcntUp_Or_FcntDown_Should_Have_HasFrameCountChanges_True() { var devAddr = new DevAddr(0x1231); // Non zero fcnt up using var target = CreateDefaultDevice(); target.SetFcntUp(1); target.AcceptFrameCountChanges(); target.ResetFcnt(); Assert.Equal(0U, target.FCntUp); Assert.Equal(0U, target.FCntDown); Assert.True(target.HasFrameCountChanges); // Non zero fcnt down using var secondConnectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object); using var secondTarget = new LoRaDevice(devAddr, new DevEui(0x12312), secondConnectionManager); secondTarget.SetFcntDown(1); secondTarget.AcceptFrameCountChanges(); secondTarget.ResetFcnt(); Assert.Equal(0U, secondTarget.FCntUp); Assert.Equal(0U, secondTarget.FCntDown); Assert.Equal(0U, secondTarget.LastSavedFCntUp); Assert.Equal(1U, secondTarget.LastSavedFCntDown); Assert.True(secondTarget.HasFrameCountChanges); // Non zero fcnt down and up using var thirdConnectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object); using var thirdTarget = new LoRaDevice(devAddr, new DevEui(0x12312), thirdConnectionManager); thirdTarget.SetFcntDown(1); thirdTarget.SetFcntDown(2); thirdTarget.AcceptFrameCountChanges(); thirdTarget.ResetFcnt(); Assert.Equal(0U, thirdTarget.FCntUp); Assert.Equal(0U, thirdTarget.FCntDown); Assert.Equal(0U, thirdTarget.LastSavedFCntUp); Assert.Equal(2U, thirdTarget.LastSavedFCntDown); Assert.Empty(thirdTarget.PreferredGatewayID); Assert.Equal(LoRaRegionType.NotSet, thirdTarget.LoRaRegion); Assert.True(thirdTarget.HasFrameCountChanges); }
public void When_Cache_Clear_Is_Called_Should_Removed_Cached_Devices(string deviceGatewayID) { LoRaDeviceClient.Setup(ldc => ldc.Dispose()); const int deviceCount = 10; var deviceList = new HashSet <LoRaDevice>(); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, DeviceCache); using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache); using var connectionManager = new SingleDeviceConnectionManager(LoRaDeviceClient.Object); for (var deviceID = 1; deviceID <= deviceCount; ++deviceID) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice((uint)deviceID, gatewayID: deviceGatewayID)); #pragma warning disable CA2000 // Dispose objects before losing scope - transfer ownership var device = TestUtils.CreateFromSimulatedDevice(simulatedDevice, connectionManager); #pragma warning restore CA2000 // Dispose objects before losing scope DeviceCache.Register(device); deviceList.Add(device); } Assert.Equal(deviceCount, DeviceCache.CalculateStatistics().Count); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); // ensure all devices are in cache Assert.Equal(deviceCount, deviceList.Count(x => DeviceCache.TryGetByDevEui(x.DevEUI, out _))); target.ResetDeviceCache(); Assert.False(deviceList.Any(x => DeviceCache.TryGetByDevEui(x.DevEUI, out _)), "Should not find devices again"); }
public LoRaCloudToDeviceMessageWrapperTest() { this.connectionManager = new SingleDeviceConnectionManager(new Mock <ILoRaDeviceClient>().Object); this.sampleDevice = new LoRaDevice(new DevAddr(0x123131), new DevEui(0x1231231232132), this.connectionManager); }
public async Task Multi_OTAA_Unconfirmed_Message_Should_Send_Data_To_IotHub_Update_FcntUp_And_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); // 1 messages will be sent LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); SecondLoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); LoRaDeviceApi.Setup(x => x.ABPFcntCacheResetAsync(It.IsNotNull <DevEui>(), It.IsAny <uint>(), It.IsNotNull <string>())) .ReturnsAsync(true); SecondLoRaDeviceApi.Setup(x => x.ABPFcntCacheResetAsync(It.IsNotNull <DevEui>(), It.IsAny <uint>(), It.IsNotNull <string>())) .ReturnsAsync(true); // cloud to device messages will be checked twice LoRaDeviceClient.SetupSequence(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>())) .ReturnsAsync((Message)null) .ReturnsAsync((Message)null); SecondLoRaDeviceClient.SetupSequence(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>())) .ReturnsAsync((Message)null) .ReturnsAsync((Message)null); using var loRaDevice1 = CreateLoRaDevice(simulatedDevice); using var connectionManager2 = new SingleDeviceConnectionManager(SecondLoRaDeviceClient.Object); using var loRaDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice, connectionManager2, SecondRequestHandlerImplementation); using var cache1 = EmptyMemoryCache(); using var loraDeviceCache = CreateDeviceCache(loRaDevice1); using var loRaDeviceRegistry1 = new LoRaDeviceRegistry(ServerConfiguration, cache1, LoRaDeviceApi.Object, LoRaDeviceFactory, loraDeviceCache); using var cache2 = EmptyMemoryCache(); using var loraDeviceCache2 = CreateDeviceCache(loRaDevice2); using var loRaDeviceRegistry2 = new LoRaDeviceRegistry(ServerConfiguration, cache2, SecondLoRaDeviceApi.Object, SecondLoRaDeviceFactory, loraDeviceCache2); // Send to message processor using var messageProcessor1 = new MessageDispatcher( ServerConfiguration, loRaDeviceRegistry1, FrameCounterUpdateStrategyProvider); using var messageProcessor2 = new MessageDispatcher( SecondServerConfiguration, loRaDeviceRegistry2, SecondFrameCounterUpdateStrategyProvider); // Starts with fcnt up zero Assert.Equal(0U, loRaDevice1.FCntUp); Assert.Equal(0U, loRaDevice2.FCntUp); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", fcnt: 1); // Create Rxpk using var request1 = CreateWaitableRequest(payload, DownstreamMessageSender); using var request2 = CreateWaitableRequest(payload, SecondDownstreamMessageSender); messageProcessor1.DispatchRequest(request1); messageProcessor2.DispatchRequest(request2); await Task.WhenAll(request1.WaitCompleteAsync(), request2.WaitCompleteAsync()); // Expectations // 1. Message was sent to IoT Hub LoRaDeviceClient.VerifyAll(); SecondLoRaDeviceClient.VerifyAll(); LoRaDeviceApi.VerifyAll(); SecondLoRaDeviceApi.VerifyAll(); LoRaDeviceClient.Verify(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null), Times.Once()); SecondLoRaDeviceClient.Verify(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null), Times.Once()); // 2. Return is null (there is nothing to send downstream) Assert.Null(request1.ResponseDownlink); Assert.Null(request2.ResponseDownlink); // 3. Frame counter up was updated to 1 Assert.Equal(1U, loRaDevice1.FCntUp); Assert.Equal(1U, loRaDevice2.FCntUp); // the following setup is required after VerifyAll() is called LoRaDeviceClient.Setup(ldc => ldc.Dispose()); SecondLoRaDeviceClient.Setup(ldc => ldc.Dispose()); }
public async Task When_Queueing_To_Multiple_Devices_With_Same_DevAddr_Should_Queue_To_Device_Matching_Mic(string deviceGatewayID) { var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234"); var loRaDeviceClient1 = new Mock <ILoRaDeviceClient>(MockBehavior.Loose); loRaDeviceClient1.Setup(x => x.GetTwinAsync(CancellationToken.None)) .ReturnsAsync(simulatedDevice1.CreateABPTwin()); using var connectionManager1 = new SingleDeviceConnectionManager(loRaDeviceClient1.Object); using var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, connectionManager1); var devAddr = loraDevice1.DevAddr.Value; var reqHandler1 = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict); reqHandler1.Setup(x => x.ProcessRequestAsync(It.IsNotNull <LoRaRequest>(), loraDevice1)) .ReturnsAsync(new LoRaDeviceRequestProcessResult(loraDevice1, null)); loraDevice1.SetRequestHandler(reqHandler1.Object); var simulatedDevice2 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); simulatedDevice2.LoRaDevice.DeviceID = new DevEui(2).ToString(); simulatedDevice2.LoRaDevice.NwkSKey = TestKeys.CreateNetworkSessionKey(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF); var loRaDeviceClient2 = new Mock <ILoRaDeviceClient>(MockBehavior.Loose); loRaDeviceClient2.Setup(x => x.GetTwinAsync(CancellationToken.None)) .ReturnsAsync(simulatedDevice2.CreateABPTwin()); using var connectionManager2 = new SingleDeviceConnectionManager(loRaDeviceClient2.Object); using var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, connectionManager2); // Api service: search devices async var iotHubDeviceInfo1 = new IoTHubDeviceInfo(devAddr, loraDevice1.DevEUI, string.Empty); var iotHubDeviceInfo2 = new IoTHubDeviceInfo(devAddr, loraDevice2.DevEUI, string.Empty); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); apiService.Setup(x => x.SearchByDevAddrAsync(devAddr)) .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo[] { iotHubDeviceInfo2, iotHubDeviceInfo1, })); // Device factory: create 2 devices this.loraDeviceFactoryMock.Setup(x => x.CreateAndRegisterAsync(iotHubDeviceInfo1, It.IsAny <CancellationToken>())).ReturnsAsync(() => { DeviceCache.Register(loraDevice1); return(loraDevice1); }); this.loraDeviceFactoryMock.Setup(x => x.CreateAndRegisterAsync(iotHubDeviceInfo2, It.IsAny <CancellationToken>())).ReturnsAsync(() => { DeviceCache.Register(loraDevice2); return(loraDevice2); }); using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object, DeviceCache); using var request = WaitableLoRaRequest.Create(payload); target.GetLoRaRequestQueue(request).Queue(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingSucceeded); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); // Both devices are in cache Assert.Equal(2, DeviceCache.RegistrationCount(devAddr)); // 2 devices with same devAddr exist in cache // find device 1 Assert.True(DeviceCache.TryGetForPayload(request.Payload, out var actualCachedLoRaDevice1)); Assert.Same(loraDevice1, actualCachedLoRaDevice1); Assert.True(loraDevice1.IsOurDevice); // find device 2 Assert.True(DeviceCache.TryGetByDevEui(loraDevice2.DevEUI, out var actualCachedLoRaDevice2)); Assert.Same(loraDevice2, actualCachedLoRaDevice2); Assert.True(loraDevice2.IsOurDevice); reqHandler1.VerifyAll(); }