Esempio n. 1
0
        public async Task When_Devices_From_Another_Gateway_Is_Cached_Return_Null()
        {
            var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway"));

            using var loraDevice1   = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, ConnectionManager);
            loraDevice1.IsOurDevice = false;

            DeviceCache.Register(loraDevice1);

            var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234");

            var apiService = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            using var target  = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object, DeviceCache);
            using var request = WaitableLoRaRequest.Create(payload);
            var queue = target.GetLoRaRequestQueue(request);

            queue.Queue(request);
            Assert.IsType <ExternalGatewayLoRaRequestQueue>(queue);
            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason);

            // Device was searched by DevAddr
            apiService.VerifyAll();

            // Device was created by factory
            this.loraDeviceFactoryMock.VerifyAll();
        }
Esempio n. 2
0
        public async Task CreateIfRequired_Result_Has_Correct_Bundler_Request()
        {
            // arrange
            const string gatewayId = "foo";
            const double rssi      = 2.3;
            var          device    = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(0));

            using var loRaDevice = TestUtils.CreateFromSimulatedDevice(device, new Mock <ILoRaDeviceClientConnectionManager>().Object);
            var payload = device.CreateConfirmedDataUpMessage("foo");

            using var request = WaitableLoRaRequest.Create(TestUtils.GenerateTestRadioMetadata(rssi: rssi), payload);
            var deviceApiServiceMock = new Mock <LoRaDeviceAPIServiceBase>();

            deviceApiServiceMock.Setup(s => s.ExecuteFunctionBundlerAsync(It.IsAny <DevEui>(), It.IsAny <FunctionBundlerRequest>())).ReturnsAsync(new FunctionBundlerResult());
            var subject = new FunctionBundlerProvider(deviceApiServiceMock.Object, NullLoggerFactory.Instance, NullLogger <FunctionBundlerProvider> .Instance);

            // act
            var bundler = subject.CreateIfRequired(gatewayId, payload, loRaDevice, new Mock <IDeduplicationStrategyFactory>().Object, request);

            _ = await bundler.Execute();

            // assert
            deviceApiServiceMock.Verify(s => s.ExecuteFunctionBundlerAsync(loRaDevice.DevEUI,
                                                                           It.Is <FunctionBundlerRequest>(actual => actual.ClientFCntDown == 0 &&
                                                                                                          actual.ClientFCntUp == 1 &&
                                                                                                          actual.GatewayId == gatewayId &&
                                                                                                          actual.Rssi == rssi)));
        }
Esempio n. 3
0
        public void When_Data_Payload_Does_Not_Need_Confirmation_RequiresConfirmation_Should_Return_False()
        {
            // arrange
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(0));
            var dataPayload     = simulatedDevice.CreateUnconfirmedDataUpMessage("payload");

            using var loraRequest = WaitableLoRaRequest.Create(dataPayload);

            // act/assert
            Assert.False(dataPayload.RequiresConfirmation);
        }
        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();
        }
Esempio n. 5
0
        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_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 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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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.GetPrimaryKeyByEuiAsync(simDevice.DevEUI))
            .ReturnsAsync("123");

            var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            deviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .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, DeviceCache, ConnectionManager);

            using var deviceRegistry = new LoRaDeviceRegistry(
                      ServerConfiguration,
                      this.cache,
                      deviceApi.Object,
                      deviceFactory,
                      DeviceCache);

            Assert.NotNull(await deviceRegistry.GetDeviceByDevEUIAsync(simDevice.DevEUI));

            var payload = simDevice.CreateUnconfirmedDataUpMessage("1");

            using var request = WaitableLoRaRequest.Create(payload);

            deviceRegistry.GetLoRaRequestQueue(request).Queue(request);
            Assert.True(await request.WaitCompleteAsync());

            handlerImplementation.VerifyAll();
            deviceApi.VerifyAll();
            deviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Once());
        }
        public ConcentratorDeduplicationTest()
        {
            this.cache             = new MemoryCache(new MemoryCacheOptions());
            this.connectionManager = new LoRaDeviceClientConnectionManager(this.cache, NullLogger <LoRaDeviceClientConnectionManager> .Instance);

            this.simulatedABPDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(0));
            this.dataPayload        = this.simulatedABPDevice.CreateConfirmedDataUpMessage("payload");
            this.dataRequest        = WaitableLoRaRequest.Create(this.dataPayload);
            this.loRaDevice         = new LoRaDevice(this.simulatedABPDevice.DevAddr, this.simulatedABPDevice.DevEUI, this.connectionManager);

            this.simulatedOTAADevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(0));
            this.joinPayload         = this.simulatedOTAADevice.CreateJoinRequest(appkey: this.simulatedOTAADevice.AppKey);
            this.joinRequest         = WaitableLoRaRequest.Create(this.joinPayload);
            this.joinRequest.SetPayload(this.joinPayload);

            this.concentratorDeduplication = new ConcentratorDeduplication(
                this.cache,
                NullLogger <IConcentratorDeduplication> .Instance);
        }
Esempio n. 11
0
        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 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.DevEui, "pk");

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            // Will get device twin
            var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(TestUtils.CreateABPTwin(simulatedDevice));

            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();

            var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", appSKey: simulatedDevice.AppSKey, nwkSKey: TestKeys.CreateNetworkSessionKey(0xEEAAFF));

            using var request = WaitableLoRaRequest.Create(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();
        }
Esempio n. 13
0
        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");

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>();
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk")
            {
                GatewayId = deviceGatewayID
            };

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            // device will be initialized
            LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simulatedDevice.CreateABPTwin());

            using var request = WaitableLoRaRequest.Create(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(LoRaDeviceClient.Object, requestHandler.Object, DeviceCache, ConnectionManager);

            using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache);
            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
            Assert.True(DeviceCache.TryGetForPayload(request.Payload, out var actualCachedLoRaDevice));

            // request was handled
            requestHandler.VerifyAll();
        }
Esempio n. 14
0
        public async Task When_Multiple_Devices_With_Same_DevAddr_Are_Cached_Should_Find_Matching_By_Mic(string deviceGatewayID)
        {
            var connectionManager = new Mock <ILoRaDeviceClientConnectionManager>();
            var simulatedDevice1  = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));

            using var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, connectionManager.Object);

            var simulatedDevice2 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: ServerConfiguration.GatewayID));

            simulatedDevice2.LoRaDevice.DeviceID = new DevEui(2).ToString();
            simulatedDevice2.LoRaDevice.NwkSKey  = TestKeys.CreateNetworkSessionKey(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
            using var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, connectionManager.Object);

            DeviceCache.Register(loraDevice1);
            DeviceCache.Register(loraDevice2);

            var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234");

            var apiService = new Mock <LoRaDeviceAPIServiceBase>();

            using var request = WaitableLoRaRequest.Create(payload);
            var requestHandler = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);

            requestHandler.Setup(x => x.ProcessRequestAsync(request, loraDevice1))
            .ReturnsAsync(new LoRaDeviceRequestProcessResult(loraDevice1, request));
            loraDevice1.SetRequestHandler(requestHandler.Object);

            using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object, DeviceCache);
            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();

            requestHandler.VerifyAll();
        }
Esempio n. 15
0
        public async Task When_Loading_Device_By_DevAddr_Should_Be_Able_To_Load_By_DevEUI()
        {
            var simDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1));

            var deviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            deviceApi.Setup(x => x.SearchByDevAddrAsync(simDevice.DevAddr.Value))
            .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(simDevice.DevAddr, simDevice.DevEUI, "123").AsList()));

            var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            deviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simDevice.CreateABPTwin());

            var handlerImplementation = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);
            var deviceFactory         = new TestLoRaDeviceFactory(deviceClient.Object, handlerImplementation.Object, DeviceCache, ConnectionManager);

            using var deviceRegistry = new LoRaDeviceRegistry(
                      ServerConfiguration,
                      this.cache,
                      deviceApi.Object,
                      deviceFactory,
                      DeviceCache);

            var payload = simDevice.CreateUnconfirmedDataUpMessage("1");

            using var request = WaitableLoRaRequest.Create(payload);

            deviceRegistry.GetLoRaRequestQueue(request).Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            await Task.Delay(50);

            Assert.NotNull(await deviceRegistry.GetDeviceByDevEUIAsync(simDevice.DevEUI));

            handlerImplementation.VerifyAll();
            deviceApi.VerifyAll();
            deviceClient.VerifyAll();
            deviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Once());
        }
Esempio n. 16
0
        public async Task When_Takes_Too_Long_Processing_C2D_Should_Abandon_Message()
        {
            const uint PayloadFcnt           = 10;
            const uint InitialDeviceFcntUp   = 9;
            const uint InitialDeviceFcntDown = 20;

            var simulatedDevice = new SimulatedDevice(
                TestDeviceInfo.CreateABPDevice(1, gatewayID: ServerConfiguration.GatewayID),
                frmCntUp: InitialDeviceFcntUp,
                frmCntDown: InitialDeviceFcntDown);

            var devAddr = simulatedDevice.DevAddr.Value;
            var devEUI  = simulatedDevice.DevEUI;

            // Will get twin to initialize LoRaDevice
            var deviceTwin = TestUtils.CreateABPTwin(simulatedDevice);

            this.LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None)).ReturnsAsync(deviceTwin);
            this.LoRaDeviceClient.Setup(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>(), It.IsAny <CancellationToken>())).ReturnsAsync(true);

            LoRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null))
            .ReturnsAsync(true);

            using var cloudToDeviceMessage = new ReceivedLoRaCloudToDeviceMessage()
                  {
                      Payload = "c2d", Fport = TestPort
                  }
                  .CreateMessage();

            LoRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>()))
            .ReturnsAsync(cloudToDeviceMessage);

            LoRaDeviceClient.Setup(x => x.AbandonAsync(cloudToDeviceMessage))
            .ReturnsAsync(true);

            LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(devAddr))
            .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(devAddr, devEUI, "adad").AsList()));

            using var cache = NewMemoryCache();
            using var loRaDeviceRegistry = new LoRaDeviceRegistry(ServerConfiguration, cache, LoRaDeviceApi.Object, LoRaDeviceFactory, DeviceCache);

            // Send to message processor
            using var messageProcessor = new MessageDispatcher(
                      ServerConfiguration,
                      loRaDeviceRegistry,
                      FrameCounterUpdateStrategyProvider);

            var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", fcnt: PayloadFcnt);

            using var request = WaitableLoRaRequest.Create(TestUtils.GenerateTestRadioMetadata(), DownstreamMessageSender,
                                                           inTimeForC2DMessageCheck: true,
                                                           inTimeForAdditionalMessageCheck: false,
                                                           inTimeForDownlinkDelivery: false,
                                                           payload);
            request.SetRegion(this.DefaultRegion);

            messageProcessor.DispatchRequest(request);
            Assert.True(await request.WaitCompleteAsync());

            // Expectations
            // 1. Message was sent to IoT Hub
            LoRaDeviceClient.VerifyAll();
            LoRaDeviceApi.VerifyAll();

            // 2. No downstream message
            Assert.Null(request.ResponseDownlink);
            Assert.True(request.ProcessingSucceeded);
            Assert.Empty(DownstreamMessageSender.DownlinkMessages);

            // 3. Device FcntDown did change
            Assert.True(DeviceCache.TryGetForPayload(request.Payload, out var loRaDevice));
            Assert.Equal(InitialDeviceFcntDown + Constants.MaxFcntUnsavedDelta, loRaDevice.FCntDown);
        }
Esempio n. 17
0
        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();
        }