public async Task When_Sending_Message_Should_Send_Downlink_To_PacketForwarder(string deviceGatewayID) { var simDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, deviceClassType: 'c', gatewayID: deviceGatewayID)); var devEUI = simDevice.DevEUI; this.deviceApi.Setup(x => x.SearchByDevEUIAsync(devEUI)) .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(string.Empty, devEUI, "123").AsList())); var twin = simDevice.CreateABPTwin(reportedProperties: new Dictionary <string, object> { { TwinProperty.Region, LoRaRegionType.EU868.ToString() } }); this.deviceClient.Setup(x => x.GetTwinAsync()) .ReturnsAsync(twin); if (string.IsNullOrEmpty(deviceGatewayID)) { // will update the fcnt down this.deviceApi.Setup(x => x.NextFCntDownAsync(devEUI, simDevice.FrmCntDown, 0, this.serverConfiguration.GatewayID)) .ReturnsAsync((ushort)(simDevice.FrmCntDown + 1)); } var c2dToDeviceMessage = new ReceivedLoRaCloudToDeviceMessage() { Payload = "hello", DevEUI = devEUI, Fport = 10, MessageId = Guid.NewGuid().ToString(), }; this.packetForwarder.Setup(x => x.SendDownstreamAsync(It.IsNotNull <DownlinkPktFwdMessage>())) .Returns(Task.CompletedTask) .Callback <DownlinkPktFwdMessage>(d => { this.EnsureDownlinkIsCorrect(d, simDevice, c2dToDeviceMessage); }); var target = new DefaultClassCDevicesMessageSender( this.serverConfiguration, this.loRaDeviceRegistry, this.packetForwarder.Object, this.frameCounterStrategyProvider); Assert.True(await target.SendAsync(c2dToDeviceMessage)); this.packetForwarder.Verify(x => x.SendDownstreamAsync(It.IsNotNull <DownlinkPktFwdMessage>()), Times.Once()); this.packetForwarder.VerifyAll(); this.deviceApi.VerifyAll(); this.deviceClient.VerifyAll(); }
public async Task Validate_Function_Bundler_Execution() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); var devEUI = simulatedDevice.LoRaDevice.DevEui; var loRaDevice = CreateLoRaDevice(simulatedDevice); loRaDevice.Deduplication = DeduplicationMode.Drop; LoRaDeviceApi .Setup(x => x.ExecuteFunctionBundlerAsync(devEUI, It.IsAny <FunctionBundlerRequest>())) .ReturnsAsync(() => new FunctionBundlerResult { AdrResult = new LoRaTools.ADR.LoRaADRResult { CanConfirmToDevice = true, FCntDown = simulatedDevice.FrmCntDown + 1, }, DeduplicationResult = new DeduplicationResult(), NextFCntDown = simulatedDevice.FrmCntDown + 1 }); LoRaDeviceApi.Setup(x => x.ABPFcntCacheResetAsync(It.IsNotNull <DevEui>(), It.IsAny <uint>(), It.IsNotNull <string>())) .ReturnsAsync(true); LoRaDeviceClient .Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); LoRaDeviceClient .Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>())) .ReturnsAsync((Message)null); using var cache = EmptyMemoryCache(); using var loraDeviceCache = CreateDeviceCache(loRaDevice); using var loRaDeviceRegistry1 = new LoRaDeviceRegistry(ServerConfiguration, cache, LoRaDeviceApi.Object, LoRaDeviceFactory, loraDeviceCache); using var messageProcessor1 = new MessageDispatcher( ServerConfiguration, loRaDeviceRegistry1, FrameCounterUpdateStrategyProvider); var payload = simulatedDevice.CreateConfirmedDataUpMessage("1234", fcnt: 1); using var request = CreateWaitableRequest(payload); messageProcessor1.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); LoRaDeviceApi.VerifyAll(); }
public async Task <IActionResult> MakeCoffee(int?id) { //var iotDevice = await _context.IoTDevices.FindAsync(id); //var iotDevice = _context.IoTDevices.FirstOrDefault(x => x.DeviceId == id); var iotDevice = await _context.IoTDevices.FindAsync(id); //var iotDevice = _context.IoTDevices.Where(x => x.DeviceId == id).FirstOrDefault(); //SimulatedDevice simulatedDevice = new SimulatedDevice(iotDevice.ModelName.Replace(" ", "") + iotDevice.UserId, iotDevice.ConnectionString, iotDevice); SimulatedDevice simulated = new SimulatedDevice(iotDevice.ModelName.Replace(" ", "") + iotDevice.UserId, iotDevice.ConnectionString, iotDevice); await simulated.Startsimulating(); return(Ok()); }
public async Task When_ABP_Device_With_Relaxed_FrameCounter_Has_FCntUP_Zero_Or_One_Should_Reset_Counter_And_Process_Message(uint payloadFCnt) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: this.ServerConfiguration.GatewayID)); // generate payload with frame count 0 or 1 var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", fcnt: payloadFCnt); simulatedDevice.FrmCntDown = 0; simulatedDevice.FrmCntUp = 10; // Create Rxpk var rxpk = payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var loraDevice = this.CreateLoRaDevice(simulatedDevice); // Will send the event to IoT Hub this.LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); // will try to get C2D message this.LoRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>())).ReturnsAsync((Message)null); // Will save the fcnt up/down to zero this.LoRaDeviceClient.Setup(x => x.UpdateReportedPropertiesAsync(It.Is <TwinCollection>((t) => this.IsTwinFcntZero(t)))) .ReturnsAsync(true); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, this.NewNonEmptyCache(loraDevice), this.LoRaDeviceApi.Object, this.LoRaDeviceFactory); // Send to message processor var messageProcessor = new MessageDispatcher( this.ServerConfiguration, deviceRegistry, this.FrameCounterUpdateStrategyProvider); var request = this.CreateWaitableRequest(rxpk); messageProcessor.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); // Expectations // 1. Message was sent to IoT Hub this.LoRaDeviceClient.VerifyAll(); this.LoRaDeviceApi.VerifyAll(); // 3. Return is null (there is nothing to send downstream) Assert.Null(request.ResponseDownlink); Assert.True(request.ProcessingSucceeded); // 4. Frame counter up was updated Assert.Equal(payloadFCnt, loraDevice.FCntUp); }
public async Task When_New_ABP_Device_Instance_Is_Created_Should_Increment_FCntDown() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: ServerGatewayID)); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk"); LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); // device will: // - be initialized // - send event // - receive c2d LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None)) .ReturnsAsync(simulatedDevice.CreateABPTwin()); LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); LoRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>())) .ReturnsAsync((Message)null); using var cache = NewMemoryCache(); using var deviceRegistry = new LoRaDeviceRegistry(ServerConfiguration, cache, LoRaDeviceApi.Object, LoRaDeviceFactory, DeviceCache); // Send to message processor using var messageProcessor = new MessageDispatcher( ServerConfiguration, deviceRegistry, FrameCounterUpdateStrategyProvider); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("2", fcnt: 2); using var request = CreateWaitableRequest(TestUtils.GenerateTestRadioMetadata(), payload, constantElapsedTime: TimeSpan.FromMilliseconds(300)); messageProcessor.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingSucceeded); // Wait until loader updates the device cache await Task.Delay(50); Assert.Equal(1, DeviceCache.RegistrationCount(simulatedDevice.DevAddr.Value)); Assert.True(DeviceCache.TryGetForPayload(request.Payload, out var cachedDevice)); Assert.True(cachedDevice.IsOurDevice); Assert.Equal(Constants.MaxFcntUnsavedDelta - 1U, cachedDevice.FCntDown); Assert.Equal(payload.Fcnt, (ushort)cachedDevice.FCntUp); // Device was searched by DevAddr LoRaDeviceApi.VerifyAll(); // Device was created by factory LoRaDeviceClient.VerifyAll(); }
public async Task When_Device_With_Downlink_Disabled_Received_Unconfirmed_Data_Should_Not_Check_For_C2D(string deviceGatewayID) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var devEUI = simulatedDevice.LoRaDevice.DeviceID; var devAddr = simulatedDevice.LoRaDevice.DevAddr; // message will be sent var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); loRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); // Lora device api var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); // using factory to create mock of var loRaDeviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var memoryCache = new MemoryCache(new MemoryCacheOptions()); var cachedDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, loRaDeviceClient.Object); cachedDevice.DownlinkEnabled = false; var devEUIDeviceDict = new DevEUIToLoRaDeviceDictionary(); devEUIDeviceDict.TryAdd(devEUI, cachedDevice); memoryCache.Set(devAddr, devEUIDeviceDict); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, loRaDeviceApi.Object, loRaDeviceFactory); var frameCounterUpdateStrategyFactory = new LoRaDeviceFrameCounterUpdateStrategyFactory(this.ServerConfiguration.GatewayID, loRaDeviceApi.Object); // Send to message processor var messageProcessor = new MessageProcessor( this.ServerConfiguration, deviceRegistry, frameCounterUpdateStrategyFactory, new LoRaPayloadDecoder()); // sends unconfirmed message var unconfirmedMessagePayload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); var rxpk = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var unconfirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk); Assert.Null(unconfirmedMessageResult); loRaDeviceClient.Verify(x => x.ReceiveAsync(It.IsAny <TimeSpan>()), Times.Never()); loRaDeviceClient.VerifyAll(); loRaDeviceApi.VerifyAll(); }
public async Task ABP_Unconfirmed_Message_Should_Send_Data_To_IotHub_Update_FcntUp_And_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: this.ServerConfiguration.GatewayID)); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", fcnt: 10); simulatedDevice.FrmCntUp = 9; // Create Rxpk var rxpk = payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var loraDeviceClient = new Mock <ILoRaDeviceClient>(); var loraDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, loraDeviceClient.Object); loraDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); var payloadDecoder = new Mock <ILoRaPayloadDecoder>(); this.LoRaDeviceRegistry.Setup(x => x.GetDeviceForPayloadAsync(It.IsAny <LoRaTools.LoRaMessage.LoRaPayloadData>())) .ReturnsAsync(loraDevice); // Setup frame counter strategy this.FrameCounterUpdateStrategyFactory.Setup(x => x.GetSingleGatewayStrategy()) .Returns(this.FrameCounterUpdateStrategy.Object); // Frame counter will be asked to save changes this.FrameCounterUpdateStrategy.Setup(x => x.SaveChangesAsync(loraDevice)).ReturnsAsync(true); // Send to message processor var messageProcessor = new MessageProcessor( this.ServerConfiguration, this.LoRaDeviceRegistry.Object, this.FrameCounterUpdateStrategyFactory.Object, payloadDecoder.Object); var actual = await messageProcessor.ProcessMessageAsync(rxpk); // Expectations // 1. Message was sent to IoT Hub loraDeviceClient.VerifyAll(); // 2. Single gateway frame counter strategy was used this.FrameCounterUpdateStrategyFactory.VerifyAll(); // 3. Return is null (there is nothing to send downstream) Assert.Null(actual); // 4. Frame counter up was updated Assert.Equal(10, loraDevice.FCntUp); }
public async Task Validate_Function_Bundler_Execution() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); var devEUI = simulatedDevice.LoRaDevice.DeviceID; var loRaDevice = this.CreateLoRaDevice(simulatedDevice); loRaDevice.Deduplication = DeduplicationMode.Drop; this.LoRaDeviceApi .Setup(x => x.ExecuteFunctionBundlerAsync(devEUI, It.IsAny <FunctionBundlerRequest>())) .ReturnsAsync(() => new FunctionBundlerResult { AdrResult = new LoRaTools.ADR.LoRaADRResult { CanConfirmToDevice = true, FCntDown = simulatedDevice.FrmCntDown + 1, }, DeduplicationResult = new DeduplicationResult(), NextFCntDown = simulatedDevice.FrmCntDown + 1 }); this.LoRaDeviceClient .Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); this.LoRaDeviceClient .Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>())) .ReturnsAsync((Message)null); var loRaDeviceRegistry1 = new LoRaDeviceRegistry(this.ServerConfiguration, this.NewNonEmptyCache(loRaDevice), this.LoRaDeviceApi.Object, this.LoRaDeviceFactory); var messageProcessor1 = new MessageDispatcher( this.ServerConfiguration, loRaDeviceRegistry1, this.FrameCounterUpdateStrategyProvider); var payload = simulatedDevice.CreateConfirmedDataUpMessage("1234", fcnt: 1); // Create Rxpk var rxpk = payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var request = this.CreateWaitableRequest(rxpk); messageProcessor1.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); this.LoRaDeviceApi.VerifyAll(); }
public async Task When_Device_Does_Not_Match_Gateway_Should_Fail_Request() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "a_different_one")); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DeviceID, string.Empty) { GatewayId = "a_different_one", }; apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var destinationDictionary = new DevEUIToLoRaDeviceDictionary(); var finished = new SemaphoreSlim(0); var target = new DeviceLoaderSynchronizer( simulatedDevice.DevAddr, apiService.Object, deviceFactory, destinationDictionary, null, this.serverConfiguration, (_, l) => { finished.Release(); }, (d) => destinationDictionary.TryAdd(d.DevEUI, d)); var request = new WaitableLoRaRequest(payload); target.Queue(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason); // device should not be initialized, since it belongs to another gateway loRaDeviceClient.Verify(x => x.GetTwinAsync(), Times.Never()); // device should not be disconnected (was never connected) loRaDeviceClient.Verify(x => x.Disconnect(), Times.Never()); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory loRaDeviceClient.VerifyAll(); }
private static void EnsureDownlinkIsCorrect(DownlinkMessage downlink, SimulatedDevice simDevice, ReceivedLoRaCloudToDeviceMessage sentMessage) { Assert.NotNull(downlink); Assert.False(downlink.Data.IsEmpty); var downstreamPayloadBytes = downlink.Data; var downstreamPayload = new LoRaPayloadData(downstreamPayloadBytes); Assert.Equal(sentMessage.Fport, downstreamPayload.Fport); Assert.Equal(downstreamPayload.DevAddr, simDevice.DevAddr); var decryptedPayload = downstreamPayload.GetDecryptedPayload(simDevice.AppSKey.Value); Assert.Equal(sentMessage.Payload, Encoding.UTF8.GetString(decryptedPayload)); }
public async Task When_Device_Is_Assigned_To_Another_Gateway_Cache_Locally_And_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway")); var apiService = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk") { GatewayId = "another-gateway", NwkSKey = simulatedDevice.NwkSKey.Value }; apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, DeviceCache, ConnectionManager); using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache); // request #1 var payload1 = simulatedDevice.CreateUnconfirmedDataUpMessage("1", fcnt: 11); using var request1 = WaitableLoRaRequest.Create(payload1); target.GetLoRaRequestQueue(request1).Queue(request1); Assert.True(await request1.WaitCompleteAsync()); Assert.True(request1.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request1.ProcessingFailedReason); // request #2 var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2", fcnt: 12); using var request2 = WaitableLoRaRequest.Create(payload2); target.GetLoRaRequestQueue(request2).Queue(request2); Assert.True(await request2.WaitCompleteAsync()); Assert.True(request2.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request2.ProcessingFailedReason); // Device was searched by DevAddr apiService.VerifyAll(); apiService.Verify(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()), Times.Once()); // Device should not be connected LoRaDeviceClient.VerifyAll(); LoRaDeviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Never()); LoRaDeviceClient.Verify(x => x.Disconnect(), Times.Never()); // device is in cache Assert.True(DeviceCache.TryGetForPayload(request1.Payload, out var loRaDevice)); Assert.False(loRaDevice.IsOurDevice); }
public async Task When_Getting_DLSettings_From_Twin_Returns_JoinAccept_With_Correct_Settings(int rx1DROffset, DataRateIndex rx2datarate) { var deviceGatewayID = ServerGatewayID; var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: deviceGatewayID)); var joinRequest = simulatedDevice.CreateJoinRequest(); var devAddr = (DevAddr?)null; var devEui = simulatedDevice.LoRaDevice.DevEui; // Device twin will be queried var twin = new Twin(); twin.Properties.Desired[TwinProperty.DevEUI] = devEui.ToString(); twin.Properties.Desired[TwinProperty.AppEui] = simulatedDevice.LoRaDevice.AppEui?.ToString(); twin.Properties.Desired[TwinProperty.AppKey] = simulatedDevice.LoRaDevice.AppKey?.ToString(); twin.Properties.Desired[TwinProperty.GatewayID] = deviceGatewayID; twin.Properties.Desired[TwinProperty.SensorDecoder] = simulatedDevice.LoRaDevice.SensorDecoder; twin.Properties.Desired[TwinProperty.RX1DROffset] = rx1DROffset; twin.Properties.Desired[TwinProperty.RX2DataRate] = rx2datarate; LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None)).ReturnsAsync(twin); LoRaDeviceClient.Setup(x => x.UpdateReportedPropertiesAsync(It.IsNotNull <TwinCollection>(), It.IsAny <CancellationToken>())) .ReturnsAsync(true); // Lora device api will be search by devices with matching deveui, LoRaDeviceApi.Setup(x => x.SearchAndLockForJoinAsync(ServerConfiguration.GatewayID, devEui, joinRequest.DevNonce)) .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(devAddr, devEui, "aabb").AsList())); using var memoryCache = new MemoryCache(new MemoryCacheOptions()); using var deviceRegistry = new LoRaDeviceRegistry(ServerConfiguration, memoryCache, LoRaDeviceApi.Object, LoRaDeviceFactory, DeviceCache); // Send to message processor using var messageProcessor = new MessageDispatcher( ServerConfiguration, deviceRegistry, FrameCounterUpdateStrategyProvider); using var request = CreateWaitableRequest(TestUtils.GenerateTestRadioMetadata(), joinRequest); messageProcessor.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); Assert.NotNull(request.ResponseDownlink); Assert.Single(DownstreamMessageSender.DownlinkMessages); var downlinkMessage = DownstreamMessageSender.DownlinkMessages[0]; var joinAccept = new LoRaPayloadJoinAccept(downlinkMessage.Data, simulatedDevice.LoRaDevice.AppKey.Value); Assert.Equal(rx1DROffset, joinAccept.Rx1DrOffset); Assert.Equal(rx2datarate, joinAccept.Rx2Dr); }
public async Task When_Device_Is_Assigned_To_Another_Gateway_Cache_Locally_And_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway")); var apiService = new Mock<LoRaDeviceAPIServiceBase>(MockBehavior.Strict); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DeviceID, string.Empty); apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull<string>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); this.loRaDeviceClient.Setup(x => x.GetTwinAsync()) .ReturnsAsync(simulatedDevice.CreateABPTwin()); this.loRaDeviceClient.Setup(x => x.Disconnect()) .Returns(true); var deviceFactory = new TestLoRaDeviceFactory(this.loRaDeviceClient.Object); var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, deviceFactory); // request #1 var payload1 = simulatedDevice.CreateUnconfirmedDataUpMessage("1", fcnt: 11); payload1.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var request1 = new WaitableLoRaRequest(payload1); target.GetLoRaRequestQueue(request1).Queue(request1); Assert.True(await request1.WaitCompleteAsync()); Assert.True(request1.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request1.ProcessingFailedReason); // request #2 var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2", fcnt: 12); payload2.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var request2 = new WaitableLoRaRequest(payload2); target.GetLoRaRequestQueue(request2).Queue(request2); Assert.True(await request2.WaitCompleteAsync()); Assert.True(request2.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request2.ProcessingFailedReason); // Device was searched by DevAddr apiService.VerifyAll(); apiService.Verify(x => x.SearchByDevAddrAsync(It.IsNotNull<string>()), Times.Once()); this.loRaDeviceClient.VerifyAll(); this.loRaDeviceClient.Verify(x => x.GetTwinAsync(), Times.Once()); // device is in cache var devAddrDictionary = target.InternalGetCachedDevicesForDevAddr(LoRaTools.Utils.ConversionHelper.ByteArrayToString(payload1.DevAddr)); Assert.NotNull(devAddrDictionary); Assert.True(devAddrDictionary.TryGetValue(simulatedDevice.DevEUI, out var cachedLoRaDevice)); Assert.False(cachedLoRaDevice.IsOurDevice); }
public async Task When_Device_Does_Not_Exist_Should_Complete_Requests_As_Failed(int loadDevicesDurationInMs) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); var devAddr = simulatedDevice.DevAddr.Value; var payload1 = simulatedDevice.CreateUnconfirmedDataUpMessage("1"); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var searchMock = apiService.Setup(x => x.SearchByDevAddrAsync(devAddr)); if (loadDevicesDurationInMs > 0) { searchMock.ReturnsAsync(new SearchDevicesResult(), TimeSpan.FromMilliseconds(loadDevicesDurationInMs)); } else { searchMock.ReturnsAsync(new SearchDevicesResult()); } var deviceFactory = new Mock <ILoRaDeviceFactory>(MockBehavior.Strict); using var deviceCache = LoRaDeviceCacheDefault.CreateDefault(); var target = new DeviceLoaderSynchronizer( devAddr, apiService.Object, deviceFactory.Object, new NetworkServerConfiguration(), deviceCache, null, NullLogger <DeviceLoaderSynchronizer> .Instance); _ = target.LoadAsync(); using var req1 = WaitableLoRaRequest.Create(payload1); target.Queue(req1); Assert.True(await req1.WaitCompleteAsync()); Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByDevAddr, req1.ProcessingFailedReason); var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2"); using var req2 = WaitableLoRaRequest.Create(payload2); target.Queue(req2); Assert.True(await req2.WaitCompleteAsync()); Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByDevAddr, req2.ProcessingFailedReason); // Device was searched by DevAddr apiService.VerifyAll(); }
public void When_Faulty_MAC_Message_Is_Received_Processing_Abort_Without_Infinite_Loop() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: ServerConfiguration.GatewayID)) { FrmCntUp = 9 }; var loraDevice = CreateLoRaDevice(simulatedDevice); LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); LoRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>())) .ReturnsAsync((Message)null); using var cache = EmptyMemoryCache(); using var loraDeviceCache = CreateDeviceCache(loraDevice); using var deviceRegistry = new LoRaDeviceRegistry(ServerConfiguration, cache, LoRaDeviceApi.Object, LoRaDeviceFactory, loraDeviceCache); // Send to message processor using var messageProcessor = new MessageDispatcher( ServerConfiguration, deviceRegistry, FrameCounterUpdateStrategyProvider); // Keeping message as future reference, this was a poisonous message with faulty mac commands that caused our engine to crash. //var request = new LoRaRequest( // new Rxpk // { // Data = "QDDaAAGxfh0FAI6wAENHbvgt1UK5Je1uPo/bLPB9HlnOXLGlLRUrTtA0KOHrZhusGl+L4g==" // }, // null, // DateTime.Now); var payload = new LoRaPayloadData(new DevAddr(0x0100DA30), new MacHeader(MacMessageType.JoinAccept), FrameControlFlags.ClassB | FrameControlFlags.Ack | FrameControlFlags.Adr, counter: 7550, options: "05", "8EB00043476EF82DD542B925ED6E3E8FDB2CF07D1E59CE5CB1A52D152B4ED03428E1EB661BAC", FramePort.MacCommand, new Mic(0x1A5F8BE2), NullLogger.Instance); using var request = WaitableLoRaRequest.Create(payload); request.SetRegion(TestUtils.TestRegion); messageProcessor.DispatchRequest(request); }
public async Task When_Device_Does_Not_Match_Gateway_Should_Fail_Request() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "a_different_one")); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk") { GatewayId = "a_different_one", NwkSKey = simulatedDevice.NwkSKey.Value }; apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose); using var deviceCache = LoRaDeviceCacheDefault.CreateDefault(); var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object, deviceCache, this.connectionManager); var target = new DeviceLoaderSynchronizer( simulatedDevice.DevAddr.Value, apiService.Object, deviceFactory, new NetworkServerConfiguration(), deviceCache, null, NullLogger <DeviceLoaderSynchronizer> .Instance); _ = target.LoadAsync(); using var request = WaitableLoRaRequest.Create(payload); target.Queue(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason); // device should not be initialized, since it belongs to another gateway loRaDeviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Never()); // device should not be disconnected (was never connected) loRaDeviceClient.Verify(x => x.Disconnect(), Times.Never()); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory loRaDeviceClient.VerifyAll(); }
public async Task Join_Device_Has_Mismatching_AppKey_Should_Return_Null(string deviceGatewayID) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: deviceGatewayID)); var joinRequestPayload = simulatedDevice.CreateJoinRequest(); // Create Rxpk var joinRequestRxpk = joinRequestPayload.SerializeUplink(simulatedDevice.AppKey).Rxpk[0]; var joinRequestDevNonce = ConversionHelper.ByteArrayToString(joinRequestPayload.DevNonce); var devAddr = string.Empty; var devEUI = simulatedDevice.LoRaDevice.DeviceID; var appEUI = simulatedDevice.LoRaDevice.AppEUI; // Device twin will be queried var twin = new Twin(); twin.Properties.Desired[TwinProperty.DevEUI] = devEUI; twin.Properties.Desired[TwinProperty.AppEUI] = simulatedDevice.LoRaDevice.AppEUI; twin.Properties.Desired[TwinProperty.AppKey] = "012345678901234567890123456789FF"; twin.Properties.Desired[TwinProperty.GatewayID] = deviceGatewayID; twin.Properties.Desired[TwinProperty.SensorDecoder] = simulatedDevice.LoRaDevice.SensorDecoder; this.LoRaDeviceClient.Setup(x => x.GetTwinAsync()).ReturnsAsync(twin); // Lora device api will be search by devices with matching deveui, this.LoRaDeviceApi.Setup(x => x.SearchAndLockForJoinAsync(this.ServerConfiguration.GatewayID, devEUI, appEUI, joinRequestDevNonce)) .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(devAddr, devEUI, "aabb").AsList())); // using factory to create mock of var memoryCache = new MemoryCache(new MemoryCacheOptions()); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, this.LoRaDeviceApi.Object, this.LoRaDeviceFactory); var messageProcessor = new MessageDispatcher( this.ServerConfiguration, deviceRegistry, this.FrameCounterUpdateStrategyProvider); // join request should fail var joinRequest = this.CreateWaitableRequest(joinRequestRxpk); messageProcessor.DispatchRequest(joinRequest); Assert.True(await joinRequest.WaitCompleteAsync()); Assert.True(joinRequest.ProcessingFailed); Assert.Null(joinRequest.ResponseDownlink); this.LoRaDeviceClient.Verify(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>()), Times.Never); this.LoRaDeviceClient.VerifyAll(); this.LoRaDeviceApi.VerifyAll(); }
public static async Task CreateSimulatedDevices(IActorRef buildingsManager) { for (int simulatedDeviceId = 0; simulatedDeviceId < 10; simulatedDeviceId++) { var newSimulatedDevice = new SimulatedDevice("basement", $"{simulatedDeviceId}", buildingsManager); await newSimulatedDevice.Connect(); var simulateNoReadingYet = simulatedDeviceId == 3; if (!simulateNoReadingYet) { newSimulatedDevice.StartSendingSimulatedReadings(); } } }
async Task <List <WaitableLoRaRequest> > SendMessages(SimulatedDevice device, MessageDispatcher dispatcher, uint payloadInitialFcnt, int delayBetweenMessages = 1000, int messagePerDeviceCount = 5) { var requests = new List <WaitableLoRaRequest>(); for (uint i = 0; i < messagePerDeviceCount; ++i) { var rxpk = device.CreateUnconfirmedMessageUplink((i + 1).ToString(), fcnt: payloadInitialFcnt + i).Rxpk[0]; var req = this.CreateWaitableRequest(rxpk); dispatcher.DispatchRequest(req); requests.Add(req); await Task.Delay(delayBetweenMessages); } return(requests); }
private async Task <List <WaitableLoRaRequest> > SendMessages(SimulatedDevice device, MessageDispatcher dispatcher, uint payloadInitialFcnt, int delayBetweenMessages = 1000, int messagePerDeviceCount = 5) { var requests = new List <WaitableLoRaRequest>(); for (uint i = 0; i < messagePerDeviceCount; ++i) { var payload = device.CreateUnconfirmedDataUpMessage((i + 1).ToString(CultureInfo.InvariantCulture), fcnt: payloadInitialFcnt + i); var req = CreateWaitableRequest(payload); dispatcher.DispatchRequest(req); requests.Add(req); await Task.Delay(delayBetweenMessages); } return(requests); }
private (X509Certificate2 deviceCertificate, X509Certificate2Collection collectionCertificates) LoadCertificateFromPfx(byte[] certificateRaw, string password) { var certificateCollection = new X509Certificate2Collection(); certificateCollection.Import( certificateRaw, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet); X509Certificate2 certificate = null; var outcollection = new X509Certificate2Collection(); foreach (X509Certificate2 element in certificateCollection) { DebugHelper.LogVerbose($"Found certificate: {element?.Thumbprint} " + $"{element?.Subject}; PrivateKey: {element?.HasPrivateKey}"); if (certificate == null && element.HasPrivateKey) { certificate = element; } else if (certificate == null && !((X509BasicConstraintsExtension)element.Extensions["Basic Constraints"]).CertificateAuthority) { using (RSA key = SimulatedDevice.GetPrivateKey()) { certificate = new X509Certificate2(RSACertificateExtensions.CopyWithPrivateKey(element, key) .Export(X509ContentType.Pkcs12, SecretManager.CertificatePasskey), SecretManager.CertificatePasskey, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet); } } else { outcollection.Add(element); } } if (certificate == null) { DebugHelper.LogError($"ERROR: the certificate did not " + $"contain any certificate with a private key."); return(null, null); } else { DebugHelper.LogVerbose($"Using certificate {certificate.Thumbprint} " + $"{certificate.Subject}"); return(certificate, outcollection); } }
private void EnsureDownlinkIsCorrect(DownlinkPktFwdMessage downlink, SimulatedDevice simDevice, ReceivedLoRaCloudToDeviceMessage sentMessage) { Assert.NotNull(downlink); Assert.NotNull(downlink.Txpk); Assert.True(downlink.Txpk.Imme); Assert.Equal(0, downlink.Txpk.Tmst); Assert.NotEmpty(downlink.Txpk.Data); byte[] downstreamPayloadBytes = Convert.FromBase64String(downlink.Txpk.Data); var downstreamPayload = new LoRaPayloadData(downstreamPayloadBytes); Assert.Equal(sentMessage.Fport, downstreamPayload.GetFPort()); Assert.Equal(downstreamPayload.DevAddr.ToArray(), ConversionHelper.StringToByteArray(simDevice.DevAddr)); var decryptedPayload = downstreamPayload.GetDecryptedPayload(simDevice.AppSKey); Assert.Equal(sentMessage.Payload, Encoding.UTF8.GetString(decryptedPayload)); }
public async Task Should_Accept( bool isConfirmed, bool hasMacInUpstream, bool hasMacInC2D, bool isTooLongForUpstreamMacCommandInAnswer, bool isSendingInRx2, [CombinatorialValues("SF10BW125", "SF9BW125", "SF8BW125", "SF7BW125")] string datr) { const int InitialDeviceFcntUp = 9; const int InitialDeviceFcntDown = 20; // This scenario makes no sense if (hasMacInUpstream && isTooLongForUpstreamMacCommandInAnswer) { return; } var simulatedDevice = new SimulatedDevice( TestDeviceInfo.CreateABPDevice(1, gatewayID: ServerConfiguration.GatewayID), frmCntUp: InitialDeviceFcntUp, frmCntDown: InitialDeviceFcntDown); var loraDevice = CreateLoRaDevice(simulatedDevice); var(radioMetaData, loraPayload) = CreateUpstreamMessage(isConfirmed, hasMacInUpstream, LoRaDataRate.Parse(datr), simulatedDevice); if (!hasMacInUpstream) { LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); } var euRegion = TestUtils.TestRegion; var c2dMessageMacCommand = new DevStatusRequest(); var c2dMessageMacCommandSize = hasMacInC2D ? c2dMessageMacCommand.Length : 0; var upstreamMessageMacCommandSize = 0; DataRateIndex expectedDownlinkDatr; if (hasMacInUpstream && !isTooLongForUpstreamMacCommandInAnswer) { upstreamMessageMacCommandSize = new LinkCheckAnswer(1, 1).Length; } expectedDownlinkDatr = isSendingInRx2 ? euRegion.GetDefaultRX2ReceiveWindow(default).DataRate
public async Task When_Loading_Device_By_DevEUI_Should_Be_Able_To_Load_By_DevAddr() { var simDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); var deviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); deviceApi.Setup(x => x.SearchByDevEUIAsync(simDevice.DevEUI)) .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(simDevice.DevAddr, simDevice.DevEUI, "123").AsList())); var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); deviceClient.Setup(x => x.GetTwinAsync()) .ReturnsAsync(simDevice.CreateABPTwin()); var handlerImplementation = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict); handlerImplementation.Setup(x => x.ProcessRequestAsync(It.IsNotNull <LoRaRequest>(), It.IsNotNull <LoRaDevice>())) .Returns <LoRaRequest, LoRaDevice>((req, device) => { return(Task.FromResult(new LoRaDeviceRequestProcessResult(device, req))); }); var deviceFactory = new TestLoRaDeviceFactory(deviceClient.Object, handlerImplementation.Object); var deviceRegistry = new LoRaDeviceRegistry( this.serverConfiguration, this.cache, deviceApi.Object, deviceFactory); Assert.NotNull(await deviceRegistry.GetDeviceByDevEUIAsync(simDevice.DevEUI)); var payload = simDevice.CreateUnconfirmedDataUpMessage("1"); payload.SerializeUplink(simDevice.AppSKey, simDevice.NwkSKey); var request = new WaitableLoRaRequest(payload); deviceRegistry.GetLoRaRequestQueue(request).Queue(request); Assert.True(await request.WaitCompleteAsync()); handlerImplementation.VerifyAll(); deviceApi.VerifyAll(); deviceClient.VerifyAll(); deviceClient.Verify(x => x.GetTwinAsync(), Times.Once()); }
public async Task When_Api_Takes_Too_Long_Should_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: this.ServerConfiguration.GatewayID)); var joinRequest = simulatedDevice.CreateJoinRequest(); var loRaDevice = this.CreateLoRaDevice(simulatedDevice); loRaDevice.SetFcntDown(10); loRaDevice.SetFcntUp(20); // Create Rxpk var rxpk = joinRequest.SerializeUplink(simulatedDevice.AppKey).Rxpk[0]; var devNonce = ConversionHelper.ByteArrayToString(joinRequest.DevNonce); var devEUI = simulatedDevice.LoRaDevice.DeviceID; var appEUI = simulatedDevice.LoRaDevice.AppEUI; var loRaDeviceRegistryMock = new Mock <ILoRaDeviceRegistry>(MockBehavior.Strict); loRaDeviceRegistryMock.Setup(x => x.RegisterDeviceInitializer(It.IsNotNull <ILoRaDeviceInitializer>())); loRaDeviceRegistryMock.Setup(x => x.GetDeviceForJoinRequestAsync(devEUI, appEUI, devNonce)) .Returns(Task.Delay(TimeSpan.FromSeconds(7)).ContinueWith((_) => loRaDevice)); // Send to message processor var messageProcessor = new MessageDispatcher( this.ServerConfiguration, loRaDeviceRegistryMock.Object, this.FrameCounterUpdateStrategyProvider); var request = this.CreateWaitableRequest(rxpk); messageProcessor.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); Assert.Null(request.ResponseDownlink); Assert.Empty(this.PacketForwarder.DownlinkMessages); Assert.Equal(LoRaDeviceRequestFailedReason.ReceiveWindowMissed, request.ProcessingFailedReason); // Device frame counts were not modified Assert.Equal(10U, loRaDevice.FCntDown); Assert.Equal(20U, loRaDevice.FCntUp); // Twin property were updated this.LoRaDeviceClient.VerifyAll(); loRaDeviceRegistryMock.VerifyAll(); this.LoRaDeviceApi.VerifyAll(); }
public async Task When_Device_Is_Assigned_To_Another_Gateway_After_No_Connection_Should_Be_Established() { const string gatewayId = "another-gateway"; var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: gatewayId)); var apiService = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk") { NwkSKey = simulatedDevice.NwkSKey.Value, GatewayId = gatewayId }; apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, DeviceCache, ConnectionManager); using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache); // setup 2 requests - ensure the cache is validated before fetching from the function var requests = Enumerable.Range(1, 2).Select((n) => { var payload = simulatedDevice.CreateUnconfirmedDataUpMessage(n.ToString(CultureInfo.InvariantCulture), fcnt: (uint)n + 10); var request = WaitableLoRaRequest.Create(payload); target.GetLoRaRequestQueue(request).Queue(request); return(request); } ).ToList(); foreach (var request in requests) { Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason); } // Device was searched by DevAddr apiService.VerifyAll(); apiService.Verify(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()), Times.Once()); LoRaDeviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Never()); // device is in cache Assert.True(DeviceCache.TryGetForPayload(requests.First().Payload, out var cachedLoRaDevice)); Assert.False(cachedLoRaDevice.IsOurDevice); }
public async Task When_Api_Returns_DevAlreadyUsed_Should_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: null)); var joinRequest = simulatedDevice.CreateJoinRequest(); // Create Rxpk var rxpk = joinRequest.SerializeUplink(simulatedDevice.LoRaDevice.AppKey).Rxpk[0]; var payloadDecoder = new Mock <ILoRaPayloadDecoder>(); var devNonce = ConversionHelper.ByteArrayToString(joinRequest.DevNonce); var devAddr = string.Empty; var devEUI = simulatedDevice.LoRaDevice.DeviceID; var appEUI = simulatedDevice.LoRaDevice.AppEUI; var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); // Lora device api will be search by devices with matching deveui, var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); loRaDeviceApi.Setup(x => x.SearchAndLockForJoinAsync(this.ServerConfiguration.GatewayID, devEUI, appEUI, devNonce)) .ReturnsAsync(new SearchDevicesResult() { IsDevNonceAlreadyUsed = true }); var loRaDeviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var memoryCache = new MemoryCache(new MemoryCacheOptions()); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, loRaDeviceApi.Object, loRaDeviceFactory); // Send to message processor var messageProcessor = new MessageProcessor( this.ServerConfiguration, deviceRegistry, this.FrameCounterUpdateStrategyFactory.Object, payloadDecoder.Object); var downlinkMessage = await messageProcessor.ProcessMessageAsync(rxpk); Assert.Null(downlinkMessage); loRaDeviceApi.VerifyAll(); loRaDeviceClient.VerifyAll(); }
public async Task When_Device_Is_Not_In_Cache_And_Found_In_Api_Does_Not_Match_Mic_Should_Fail_Request(string deviceGatewayID) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DeviceID, string.Empty); apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); // Will get device twin var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); loRaDeviceClient.Setup(x => x.GetTwinAsync()) .ReturnsAsync(TestUtils.CreateABPTwin(simulatedDevice)); var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var destinationDictionary = new DevEUIToLoRaDeviceDictionary(); var finished = new SemaphoreSlim(0); var target = new DeviceLoaderSynchronizer( simulatedDevice.DevAddr, apiService.Object, deviceFactory, destinationDictionary, null, this.serverConfiguration, (_, l) => { finished.Release(); }, (d) => destinationDictionary.TryAdd(d.DevEUI, d)); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice.AppSKey, "00000000000000000000000000EEAAFF"); var request = new WaitableLoRaRequest(payload); target.Queue(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByMicCheck, request.ProcessingFailedReason); // Device was searched by DevAddr apiService.VerifyAll(); loRaDeviceClient.VerifyAll(); }
public async Task When_Device_Is_Not_In_Cache_And_Found_In_Api_Should_Cache_And_Process_Request(string deviceGatewayID) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DeviceID, string.Empty); apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); // device will be initialized this.loRaDeviceClient.Setup(x => x.GetTwinAsync()) .ReturnsAsync(simulatedDevice.CreateABPTwin()); var request = new WaitableLoRaRequest(payload); var requestHandler = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict); requestHandler.Setup(x => x.ProcessRequestAsync(request, It.IsNotNull <LoRaDevice>())) .ReturnsAsync(new LoRaDeviceRequestProcessResult(null, request)); var deviceFactory = new TestLoRaDeviceFactory(this.loRaDeviceClient.Object, requestHandler.Object); var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, deviceFactory); target.GetLoRaRequestQueue(request).Queue(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingSucceeded); // Device was searched by DevAddr apiService.VerifyAll(); // ensure device is in cache var cachedItem = target.InternalGetCachedDevicesForDevAddr(simulatedDevice.DevAddr); Assert.NotNull(cachedItem); Assert.Single(cachedItem); Assert.True(cachedItem.TryGetValue(simulatedDevice.DevEUI, out var actualCachedLoRaDevice)); // request was handled requestHandler.VerifyAll(); }
public async Task When_Device_AppEUI_Does_Not_Match_Should_Return_Null() { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: this.ServerConfiguration.GatewayID)); var joinRequest = simulatedDevice.CreateJoinRequest(); // Create Rxpk var rxpk = joinRequest.SerializeUplink(simulatedDevice.AppKey).Rxpk[0]; var devNonce = ConversionHelper.ByteArrayToString(joinRequest.DevNonce); var devEUI = simulatedDevice.LoRaDevice.DeviceID; var appEUI = simulatedDevice.LoRaDevice.AppEUI; simulatedDevice.LoRaDevice.AppEUI = "FFFFFFFFFFFFFFFF"; var loRaDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, null); 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, appEUI, devNonce)) .ReturnsAsync(() => loRaDevice); // Send to message processor var messageProcessor = new MessageDispatcher( this.ServerConfiguration, loRaDeviceRegistryMock.Object, this.FrameCounterUpdateStrategyProvider); var request = this.CreateWaitableRequest(rxpk); 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); this.LoRaDeviceClient.VerifyAll(); this.LoRaDeviceApi.VerifyAll(); loRaDeviceRegistryMock.VerifyAll(); }