public async Task When_Devices_From_Another_Gateway_Is_Cached_Return_Null()
        {
            var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway"));
            var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null);
            loraDevice1.IsOurDevice = false;

            var existingCache = new DevEUIToLoRaDeviceDictionary();
            this.cache.Set<DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache);
            existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1);

            var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234");
            payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey);

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

            var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object);
            var request = new WaitableLoRaRequest(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();
        }
        public async Task When_Device_Api_Throws_Error_Should_Not_Create_Any_Device()
        {
            const string devAddr = "039090";

            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1));
            var payload         = simulatedDevice.CreateUnconfirmedDataUpMessage("1234");

            payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey);

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

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>()))
            .Throws(new Exception());

            var deviceFactory = new Mock <ILoRaDeviceFactory>(MockBehavior.Strict);

            var destinationDictionary = new DevEUIToLoRaDeviceDictionary();
            var finished = new SemaphoreSlim(0);
            var target   = new DeviceLoaderSynchronizer(
                devAddr,
                apiService.Object,
                deviceFactory.Object,
                destinationDictionary,
                null,
                this.serverConfiguration,
                (_, l) => { finished.Release(); },
                (d) => { destinationDictionary.TryAdd(d.DevEUI, d); });

            await finished.WaitAsync();

            Assert.Empty(destinationDictionary);

            // Device was searched by DevAddr
            apiService.VerifyAll();
        }
Ejemplo n.º 3
0
        public async Task When_Fcnt_Down_Fails_Should_Stop_And_Not_Update_Device_Twin(uint initialFcntDown, uint initialFcntUp, uint payloadFcnt)
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: null));

            simulatedDevice.FrmCntDown = initialFcntDown;
            simulatedDevice.FrmCntUp   = initialFcntUp;

            var devEUI  = simulatedDevice.LoRaDevice.DeviceID;
            var devAddr = simulatedDevice.LoRaDevice.DevAddr;

            this.LoRaDeviceApi.Setup(x => x.ExecuteFunctionBundlerAsync(devEUI, It.IsAny <FunctionBundlerRequest>())).ReturnsAsync(() => new FunctionBundlerResult
            {
                AdrResult = new LoRaTools.ADR.LoRaADRResult {
                    CanConfirmToDevice = true, FCntDown = 0
                },
                NextFCntDown = 0
            });

            this.LoRaDeviceApi.Setup(x => x.ABPFcntCacheResetAsync(devEUI, It.IsAny <uint>(), It.IsNotNull <string>()))
            .ReturnsAsync(true);

            var memoryCache = new MemoryCache(new MemoryCacheOptions());
            var device      = this.CreateLoRaDevice(simulatedDevice);

            var dicForDevAddr = new DevEUIToLoRaDeviceDictionary();

            dicForDevAddr.TryAdd(devEUI, device);
            memoryCache.Set(devAddr, dicForDevAddr);
            var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, this.LoRaDeviceApi.Object, this.LoRaDeviceFactory);

            // Send to message processor
            var messageDispatcher = new MessageDispatcher(
                this.ServerConfiguration,
                deviceRegistry,
                this.FrameCounterUpdateStrategyProvider);

            // sends unconfirmed message
            var unconfirmedMessagePayload = simulatedDevice.CreateConfirmedDataUpMessage("hello", fcnt: payloadFcnt);
            var rxpk    = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0];
            var request = this.CreateWaitableRequest(rxpk);

            messageDispatcher.DispatchRequest(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.Null(request.ResponseDownlink);

            // verify that the device in device registry has correct properties and frame counters
            var devicesForDevAddr = deviceRegistry.InternalGetCachedDevicesForDevAddr(devAddr);

            Assert.Single(devicesForDevAddr);
            Assert.True(devicesForDevAddr.TryGetValue(devEUI, out var loRaDevice));
            Assert.Equal(devAddr, loRaDevice.DevAddr);
            Assert.Equal(devEUI, loRaDevice.DevEUI);
            Assert.True(loRaDevice.IsABP);
            Assert.Equal(initialFcntUp, loRaDevice.FCntUp);
            Assert.Equal(initialFcntDown, loRaDevice.FCntDown);
            Assert.False(loRaDevice.HasFrameCountChanges);

            this.LoRaDeviceClient.VerifyAll();
            this.LoRaDeviceApi.VerifyAll();
        }
Ejemplo n.º 4
0
        public async Task When_Devices_From_Another_Gateway_Is_Cached_Return_Null()
        {
            var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway"));
            var loraDevice1      = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null);

            loraDevice1.IsOurDevice = false;

            var existingCache = new DevEUIToLoRaDeviceDictionary();

            this.cache.Set <DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache);
            existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1);

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

            payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey);

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

            var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object);

            var actual = await target.GetDeviceForPayloadAsync(payload);

            Assert.Null(actual);

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

            // Device was created by factory
            this.loraDeviceFactoryMock.VerifyAll();
        }
Ejemplo n.º 5
0
        public async Task When_Fcnt_Down_Fails_Should_Stop_And_Not_Update_Device_Twin(int initialFcntDown, int initialFcntUp, int payloadFcnt)
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: null));

            simulatedDevice.FrmCntDown = initialFcntDown;
            simulatedDevice.FrmCntUp   = initialFcntUp;
            var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict);

            var devEUI  = simulatedDevice.LoRaDevice.DeviceID;
            var devAddr = simulatedDevice.LoRaDevice.DevAddr;

            // Lora device api
            var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            loRaDeviceApi.Setup(x => x.NextFCntDownAsync(devEUI, initialFcntDown, payloadFcnt, ServerGatewayID)).ReturnsAsync((ushort)0);

            // using factory to create mock of
            var loRaDeviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object);

            var memoryCache = new MemoryCache(new MemoryCacheOptions());
            var device      = TestUtils.CreateFromSimulatedDevice(simulatedDevice, loRaDeviceClient.Object);

            var dicForDevAddr = new DevEUIToLoRaDeviceDictionary();

            dicForDevAddr.TryAdd(devEUI, device);
            memoryCache.Set(devAddr, dicForDevAddr);
            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.CreateConfirmedDataUpMessage("hello", fcnt: payloadFcnt);
            var rxpk = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0];
            var unconfirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk);

            Assert.Null(unconfirmedMessageResult);

            // verify that the device in device registry has correct properties and frame counters
            var devicesForDevAddr = deviceRegistry.InternalGetCachedDevicesForDevAddr(devAddr);

            Assert.Single(devicesForDevAddr);
            Assert.True(devicesForDevAddr.TryGetValue(devEUI, out var loRaDevice));
            Assert.Equal(devAddr, loRaDevice.DevAddr);
            Assert.Equal(devEUI, loRaDevice.DevEUI);
            Assert.True(loRaDevice.IsABP);
            Assert.Equal(initialFcntUp, loRaDevice.FCntUp);
            Assert.Equal(initialFcntDown, loRaDevice.FCntDown);
            Assert.False(loRaDevice.HasFrameCountChanges);

            loRaDeviceClient.VerifyAll();
            loRaDeviceApi.VerifyAll();
        }
        public async Task When_Device_With_Downlink_Disabled_Received_Confirmed_Data_Should_Not_Check_For_C2D(string deviceGatewayID)
        {
            const int payloadFcnt     = 10;
            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);

            // multi gateway will ask for next fcnt down
            if (string.IsNullOrEmpty(deviceGatewayID))
            {
                loRaDeviceApi.Setup(x => x.NextFCntDownAsync(devEUI, simulatedDevice.FrmCntDown, payloadFcnt, this.ServerConfiguration.GatewayID))
                .ReturnsAsync((ushort)(simulatedDevice.FrmCntDown + 1));
            }

            // 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 confirmed message
            var rxpk = simulatedDevice.CreateConfirmedMessageUplink("1234", fcnt: payloadFcnt).Rxpk[0];
            var confirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk);

            Assert.NotNull(confirmedMessageResult);

            loRaDeviceClient.Verify(x => x.ReceiveAsync(It.IsAny <TimeSpan>()), Times.Never());

            loRaDeviceClient.VerifyAll();
            loRaDeviceApi.VerifyAll();
        }
        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;
            var payload1        = simulatedDevice.CreateUnconfirmedDataUpMessage("1");

            payload1.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey);

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

            var destinationDictionary = new DevEUIToLoRaDeviceDictionary();
            var finished = new SemaphoreSlim(0);
            var target   = new DeviceLoaderSynchronizer(
                devAddr,
                apiService.Object,
                deviceFactory.Object,
                destinationDictionary,
                null,
                this.serverConfiguration,
                (_, l) => { finished.Release(); },
                (d) => destinationDictionary.TryAdd(d.DevEUI, d));

            var req1 = new WaitableLoRaRequest(payload1);

            target.Queue(req1);

            await finished.WaitAsync();

            Assert.True(await req1.WaitCompleteAsync());
            Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByDevAddr, req1.ProcessingFailedReason);

            var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2");

            payload2.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey);
            var req2 = new WaitableLoRaRequest(payload2);

            target.Queue(req2);

            Assert.True(await req2.WaitCompleteAsync());
            Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByDevAddr, req2.ProcessingFailedReason);

            // Device was searched by DevAddr
            apiService.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();
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Creates a <see cref="IMemoryCache"/> containing the <paramref name="loRaDevice"/> already available.
        /// </summary>
        public IMemoryCache NewNonEmptyCache(LoRaDevice loRaDevice)
        {
            var cache = new MemoryCache(new MemoryCacheOptions());

            // add by dev addr
            var dictionary = new DevEUIToLoRaDeviceDictionary();

            dictionary.TryAdd(loRaDevice.DevEUI, loRaDevice);
            cache.Set(loRaDevice.DevAddr, dictionary);

            // add device by deveui
            cache.Set(LoRaDeviceRegistry.CacheKeyForDevEUIDevice(loRaDevice.DevEUI), loRaDevice);

            return(cache);
        }
        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();
        }
Ejemplo n.º 11
0
        public async Task When_Multiple_Devices_With_Same_DevAddr_Are_Cached_Should_Find_Matching_By_Mic(string deviceGatewayID)
        {
            var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));
            var loraDevice1      = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null);

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

            simulatedDevice2.LoRaDevice.DeviceID = "00000002";
            simulatedDevice2.LoRaDevice.NwkSKey  = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
            var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, null);

            var existingCache = new DevEUIToLoRaDeviceDictionary();

            this.cache.Set <DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache);
            existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1);
            existingCache.TryAdd(loraDevice2.DevEUI, loraDevice2);

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

            payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey);

            var apiService = new Mock <LoRaDeviceAPIServiceBase>();

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

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

            var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object);

            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();
        }
Ejemplo n.º 12
0
 internal DeviceLoaderSynchronizer(
     string devAddr,
     LoRaDeviceAPIServiceBase loRaDeviceAPIService,
     ILoRaDeviceFactory deviceFactory,
     DevEUIToLoRaDeviceDictionary destinationDictionary,
     HashSet <ILoRaDeviceInitializer> initializers,
     NetworkServerConfiguration configuration,
     Action <Task, DeviceLoaderSynchronizer> continuationAction,
     Action <LoRaDevice> registerDeviceAction)
 {
     this.loRaDeviceAPIService = loRaDeviceAPIService;
     this.deviceFactory        = deviceFactory;
     this.devAddr              = devAddr;
     this.existingDevices      = destinationDictionary;
     this.initializers         = initializers;
     this.configuration        = configuration;
     this.registerDeviceAction = registerDeviceAction;
     this.state = LoaderState.QueryingDevices;
     this.loadingDevicesFailed = false;
     this.queueLock            = new object();
     this.queuedRequests       = new List <LoRaRequest>();
     this.loading = Task.Run(() => this.Load().ContinueWith((t) => continuationAction(t, this), TaskContinuationOptions.ExecuteSynchronously));
 }
Ejemplo n.º 13
0
        public async Task When_Multiple_Devices_With_Same_DevAddr_Are_Cached_Should_Find_Matching_By_Mic(string deviceGatewayID)
        {
            var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));
            var loraDevice1      = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null);

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

            simulatedDevice2.LoRaDevice.DeviceID = "00000002";
            simulatedDevice2.LoRaDevice.NwkSKey  = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
            var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, null);

            var existingCache = new DevEUIToLoRaDeviceDictionary();

            this.cache.Set <DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache);
            existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1);
            existingCache.TryAdd(loraDevice2.DevEUI, loraDevice2);

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

            payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey);

            var apiService = new Mock <LoRaDeviceAPIServiceBase>();

            var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object);

            var actual = await target.GetDeviceForPayloadAsync(payload);

            Assert.NotNull(actual);
            Assert.Same(loraDevice1, actual);
            Assert.True(actual.IsOurDevice);

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

            // Device was created by factory
            this.loraDeviceFactoryMock.VerifyAll();
        }
Ejemplo n.º 14
0
        public async Task When_Getting_C2D_Message_Fails_To_Resolve_Fcnt_Down_Should_Drop_Message_And_Return_Null()
        {
            const int initialFcntDown = 5;
            const int initialFcntUp   = 21;
            const int payloadFcnt     = 23;

            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: null));

            simulatedDevice.FrmCntUp   = initialFcntUp;
            simulatedDevice.FrmCntDown = initialFcntDown;

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

            var cloudToDeviceMessage = new Message();

            cloudToDeviceMessage.Properties.Add("fport", "1");
            // C2D message will be retrieved
            loRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>()))
            .ReturnsAsync(cloudToDeviceMessage);

            // C2D message will be abandonned
            loRaDeviceClient.Setup(x => x.AbandonAsync(cloudToDeviceMessage))
            .ReturnsAsync(true);

            // Lora device api
            var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            // getting the fcnt down will return 0!
            loRaDeviceApi.Setup(x => x.NextFCntDownAsync(devEUI, initialFcntDown, payloadFcnt, this.ServerConfiguration.GatewayID))
            .ReturnsAsync((ushort)0);

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

            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("hello", fcnt: payloadFcnt);
            var rxpk = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0];
            var unconfirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk);

            Assert.Null(unconfirmedMessageResult);

            var cachedDevices = deviceRegistry.InternalGetCachedDevicesForDevAddr(simulatedDevice.DevAddr);

            Assert.True(cachedDevices.TryGetValue(devEUI, out var loRaDevice));
            // fcnt down did not change
            Assert.Equal(initialFcntDown, loRaDevice.FCntDown);

            // fcnt up changed
            Assert.Equal(unconfirmedMessagePayload.GetFcnt(), loRaDevice.FCntUp);

            loRaDeviceClient.Verify(x => x.ReceiveAsync(It.IsAny <TimeSpan>()), Times.Once());
            loRaDeviceClient.Verify(x => x.AbandonAsync(It.IsAny <Message>()), Times.Once());

            loRaDeviceClient.VerifyAll();
            loRaDeviceApi.VerifyAll();
        }