internal static LoRaDevice CreateFromSimulatedDevice(
            SimulatedDevice simulatedDevice,
            ILoRaDeviceClient loRaDeviceClient,
            DefaultLoRaDataRequestHandler requestHandler         = null,
            ILoRaDeviceClientConnectionManager connectionManager = null)
        {
            var result = new LoRaDevice(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DeviceID, connectionManager ?? new SingleDeviceConnectionManager(loRaDeviceClient))
            {
                AppEUI        = simulatedDevice.LoRaDevice.AppEUI,
                AppKey        = simulatedDevice.LoRaDevice.AppKey,
                SensorDecoder = simulatedDevice.LoRaDevice.SensorDecoder,
                AppSKey       = simulatedDevice.LoRaDevice.AppSKey,
                NwkSKey       = simulatedDevice.LoRaDevice.NwkSKey,
                GatewayID     = simulatedDevice.LoRaDevice.GatewayID,
                IsOurDevice   = true,
                ClassType     = (simulatedDevice.ClassType == 'C' || simulatedDevice.ClassType == 'c') ? LoRaDeviceClassType.C : LoRaDeviceClassType.A,
            };

            result.SetFcntDown(simulatedDevice.FrmCntDown);
            result.SetFcntUp(simulatedDevice.FrmCntUp);
            result.AcceptFrameCountChanges();

            if (requestHandler != null)
            {
                result.SetRequestHandler(requestHandler);
            }

            return(result);
        }
        public async Task When_Device_Has_Up_To_9_Changes_In_Fcnt_Down_Should_Not_Save_Changes(uint startFcntDown)
        {
            var target = new MultiGatewayFrameCounterUpdateStrategy(this.gatewayID, this.deviceApi.Object);

            var device = new LoRaDevice("1", "2", new SingleDeviceConnectionManager(this.deviceClient.Object));

            device.SetFcntDown(startFcntDown);
            device.AcceptFrameCountChanges();

            this.deviceApi.Setup(x => x.NextFCntDownAsync(device.DevEUI, It.IsAny <uint>(), It.IsAny <uint>(), this.gatewayID))
            .Returns <string, uint, uint, string>((devEUI, fcntDown, payloadFcnt, gatewayID) =>
            {
                return(Task.FromResult(fcntDown + 1));
            });

            for (var i = 1; i <= 9; ++i)
            {
                await target.NextFcntDown(device, 10);

                await target.SaveChangesAsync(device);
            }

            this.deviceApi.VerifyAll();
            this.deviceClient.VerifyAll();
        }
Esempio n. 3
0
        public async Task When_Device_FcntDown_Change_Is_10_Or_More_Should_Save_Changes(uint startingFcntDown, uint startingFcntUp)
        {
            var target = new SingleGatewayFrameCounterUpdateStrategy();

            this.deviceClient.Setup(x => x.UpdateReportedPropertiesAsync(It.IsNotNull <TwinCollection>()))
            .ReturnsAsync(true)
            .Callback <TwinCollection>(t =>
            {
                Assert.Equal(startingFcntDown + 10, (uint)t[TwinProperty.FCntDown]);
                Assert.Equal(startingFcntUp, (uint)t[TwinProperty.FCntUp]);
            });

            var device = new LoRaDevice("1", "2", new SingleDeviceConnectionManager(this.deviceClient.Object));

            device.SetFcntUp(startingFcntUp);
            device.SetFcntDown(startingFcntDown);
            device.AcceptFrameCountChanges();

            for (var i = 1; i <= 15; i++)
            {
                await target.NextFcntDown(device, startingFcntUp + 1);

                await target.SaveChangesAsync(device);
            }

            this.deviceClient.VerifyAll();
        }
        public void When_Missed_Both_Windows_Should_Resolve_Window_0(int delayInMs)
        {
            var target     = new LoRaOperationTimeWatcher(RegionFactory.CreateEU868Region(), DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("31312", "312321321", null);

            Assert.Equal(0, target.ResolveReceiveWindowToUse(loRaDevice));
        }
Esempio n. 5
0
        public void After_3_Resubmits_Should_Not_Be_Valid_To_Resend_Ack()
        {
            var target = new LoRaDevice("1231", "12312", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));

            // 1st time
            target.SetFcntUp(12);

            // 1st resubmit
            target.SetFcntUp(12);
            Assert.True(target.ValidateConfirmResubmit(12));

            // 2nd resubmit
            target.SetFcntUp(12);
            Assert.True(target.ValidateConfirmResubmit(12));

            // 3rd resubmit
            target.SetFcntUp(12);
            Assert.True(target.ValidateConfirmResubmit(12));

            // 4rd resubmit
            target.SetFcntUp(12);
            Assert.False(target.ValidateConfirmResubmit(12));

            // new fcnt up
            target.SetFcntUp(13);

            Assert.False(target.ValidateConfirmResubmit(12), "Should not be valid to resubmit old fcntUp");

            // resubmit new fcnt up
            target.SetFcntUp(13);
            Assert.True(target.ValidateConfirmResubmit(13));

            Assert.False(target.ValidateConfirmResubmit(12), "Should not be valid to resubmit old fcntUp");
        }
Esempio n. 6
0
        public async Task When_Downlink_Is_Enabled_In_Twin_Should_Have_DownlinkEnabled_Equals_True(object downlinkTwinPropertyValue)
        {
            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "NwkSKey", "ABC02000000000000000000000000009ABC02000000000000000000000000009" },
                { "AppSKey", "ABCD2000000000000000000000000009ABC02000000000000000000000000009" },
                { "DevAddr", "0000AABB" },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { TwinProperty.DownlinkEnabled, downlinkTwinPropertyValue },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", "ABC02000000000000000000000000009ABC02000000000000000000000000009" },
                { "AppSKey", "ABCD2000000000000000000000000009ABC02000000000000000000000000009" },
                { "DevAddr", "0000AABB" },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync())
            .ReturnsAsync(twin);

            var loRaDevice = new LoRaDevice("00000001", "ABC0200000000009", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));
            await loRaDevice.InitializeAsync();

            Assert.True(loRaDevice.DownlinkEnabled);
        }
Esempio n. 7
0
        public void When_ResetFcnt_In_NonZero_FcntUp_Or_FcntDown_Should_Have_HasFrameCountChanges_True()
        {
            // Non zero fcnt up
            var target = new LoRaDevice("1231", "12312", this.loRaDeviceClient.Object);

            target.SetFcntUp(1);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0, target.FCntUp);
            Assert.Equal(0, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);

            // Non zero fcnt down
            target = new LoRaDevice("1231", "12312", this.loRaDeviceClient.Object);
            target.SetFcntDown(1);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0, target.FCntUp);
            Assert.Equal(0, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);

            // Non zero fcnt down and up
            target = new LoRaDevice("1231", "12312", this.loRaDeviceClient.Object);
            target.SetFcntDown(1);
            target.SetFcntDown(2);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0, target.FCntUp);
            Assert.Equal(0, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);
        }
Esempio n. 8
0
        public async Task When_Initialized_New_OTAA_Device_Should_Have_All_Properties()
        {
            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "AppEUI", "ABC0200000000009" },
                { "AppKey", "ABC02000000000000000000000000009" },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync())
            .ReturnsAsync(twin);

            var loRaDevice = new LoRaDevice(string.Empty, "ABC0200000000009", this.loRaDeviceClient.Object);
            await loRaDevice.InitializeAsync();

            Assert.Equal("ABC0200000000009", loRaDevice.AppEUI);
            Assert.Equal("ABC02000000000000000000000000009", loRaDevice.AppKey);
            Assert.Equal("mygateway", loRaDevice.GatewayID);
            Assert.Equal("DecoderValueSensor", loRaDevice.SensorDecoder);
            Assert.Empty(loRaDevice.AppSKey ?? string.Empty);
            Assert.Empty(loRaDevice.NwkSKey ?? string.Empty);
            Assert.Empty(loRaDevice.DevAddr ?? string.Empty);
            Assert.Empty(loRaDevice.DevNonce ?? string.Empty);
            Assert.Empty(loRaDevice.NetID ?? string.Empty);
            Assert.False(loRaDevice.IsABP);
            Assert.False(loRaDevice.IsOurDevice);
        }
        public void When_Out_Of_Time_For_Join_Accept_Second_Window_Should_Resolve_Window_0(int delayInMs)
        {
            var target     = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("31312", "312321321", null);

            Assert.Equal(0, target.ResolveJoinAcceptWindowToUse(loRaDevice));
        }
        public void When_Needed_Should_Reconnect_Client()
        {
            var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict);
            var cache        = new MemoryCache(new MemoryCacheOptions());
            var manager      = new LoRaDeviceClientConnectionManager(cache);
            var device       = new LoRaDevice("00000000", "0123456789", manager);

            device.KeepAliveTimeout = 60;
            manager.Register(device, deviceClient.Object);

            deviceClient.Setup(x => x.EnsureConnected())
            .Returns(true);

            deviceClient.Setup(x => x.Disconnect())
            .Returns(true);

            using (var activity1 = device.BeginDeviceClientConnectionActivity())
            {
                Assert.NotNull(activity1);
            }

            Assert.True(device.TryDisconnect());

            using (var activity2 = device.BeginDeviceClientConnectionActivity())
            {
                Assert.NotNull(activity2);

                Assert.False(device.TryDisconnect());
            }

            Assert.True(device.TryDisconnect());

            deviceClient.Verify(x => x.EnsureConnected(), Times.Exactly(2));
            deviceClient.Verify(x => x.Disconnect(), Times.Exactly(2));
        }
Esempio n. 11
0
        public void When_ResetFcnt_In_Device_With_Pending_Changes_Should_Have_HasFrameCountChanges_True()
        {
            var devAddr = new DevAddr(0x1231);

            // Non zero fcnt up
            using var target = CreateDefaultDevice();
            target.SetFcntUp(1);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0U, target.FCntUp);
            Assert.Equal(0U, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);

            // Non zero fcnt down
            using var secondConnectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object);
            using var secondTarget            = new LoRaDevice(devAddr, new DevEui(0x12312), secondConnectionManager);
            secondTarget.SetFcntDown(1);
            secondTarget.AcceptFrameCountChanges();
            secondTarget.ResetFcnt();
            Assert.Equal(0U, secondTarget.FCntUp);
            Assert.Equal(0U, secondTarget.FCntDown);
            Assert.True(secondTarget.HasFrameCountChanges);

            // Non zero fcnt down and up
            using var thirdConnectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object);
            using var thirdTarget            = new LoRaDevice(devAddr, new DevEui(0x12312), thirdConnectionManager);
            thirdTarget.SetFcntDown(1);
            thirdTarget.SetFcntDown(2);
            thirdTarget.AcceptFrameCountChanges();
            thirdTarget.ResetFcnt();
            Assert.Equal(0U, thirdTarget.FCntUp);
            Assert.Equal(0U, thirdTarget.FCntDown);
            Assert.True(thirdTarget.HasFrameCountChanges);
        }
        public void When_Missed_Both_Windows_Should_Resolve_Window_0(int delayInMs)
        {
            var target     = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("31312", "312321321", null);

            Assert.Equal(Constants.INVALID_RECEIVE_WINDOW, target.ResolveReceiveWindowToUse(loRaDevice));
        }
Esempio n. 13
0
        public async Task When_PreferredWindow_Is_Not_Define_In_Twin_Should_Have_Window1_As_Preferred()
        {
            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "NwkSKey", "ABC02000000000000000000000000009ABC02000000000000000000000000009" },
                { "AppSKey", "ABCD2000000000000000000000000009ABC02000000000000000000000000009" },
                { "DevAddr", "0000AABB" },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", "ABC02000000000000000000000000009ABC02000000000000000000000000009" },
                { "AppSKey", "ABCD2000000000000000000000000009ABC02000000000000000000000000009" },
                { "DevAddr", "0000AABB" },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync())
            .ReturnsAsync(twin);

            var loRaDevice = new LoRaDevice("00000001", "ABC0200000000009", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));
            await loRaDevice.InitializeAsync();

            Assert.Equal(1, loRaDevice.PreferredWindow);
        }
Esempio n. 14
0
        public void When_ResetFcnt_In_Device_With_Pending_Changes_Should_Have_HasFrameCountChanges_True()
        {
            // Non zero fcnt up
            var target = new LoRaDevice("1231", "12312", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));

            target.SetFcntUp(1);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0U, target.FCntUp);
            Assert.Equal(0U, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);

            // Non zero fcnt down
            target = new LoRaDevice("1231", "12312", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));
            target.SetFcntDown(1);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0U, target.FCntUp);
            Assert.Equal(0U, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);

            // Non zero fcnt down and up
            target = new LoRaDevice("1231", "12312", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));
            target.SetFcntDown(1);
            target.SetFcntDown(2);
            target.AcceptFrameCountChanges();
            target.ResetFcnt();
            Assert.Equal(0U, target.FCntUp);
            Assert.Equal(0U, target.FCntDown);
            Assert.True(target.HasFrameCountChanges);
        }
Esempio n. 15
0
        public async Task When_Initialized_With_Keep_Alive_Should_Read_Value_From_Twin(object keepAliveTimeoutValue, int expectedKeepAliveTimeout)
        {
            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "NwkSKey", "ABC02000000000000000000000000009ABC02000000000000000000000000009" },
                { "AppSKey", "ABCD2000000000000000000000000009ABC02000000000000000000000000009" },
                { "DevAddr", "0000AABB" },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "KeepAliveTimeout", keepAliveTimeoutValue },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", "ABC02000000000000000000000000009ABC02000000000000000000000000009" },
                { "AppSKey", "ABCD2000000000000000000000000009ABC02000000000000000000000000009" },
                { "DevAddr", "0000AABB" }
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync())
            .ReturnsAsync(twin);

            var loRaDevice = new LoRaDevice("00000001", "ABC0200000000009", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));
            await loRaDevice.InitializeAsync();

            Assert.Equal(expectedKeepAliveTimeout, loRaDevice.KeepAliveTimeout);
        }
        public void When_In_Time_For_Join_Accept_First_Window_Should_Resolve_Window_1(int delayInMs)
        {
            var target     = new LoRaOperationTimeWatcher(RegionFactory.CreateEU868Region(), DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("31312", "312321321", null);

            Assert.Equal(1, target.ResolveJoinAcceptWindowToUse(loRaDevice));
        }
Esempio n. 17
0
        public void When_Out_Of_Time_For_Join_Accept_Second_Window_Should_Resolve_Window_0(int delayInMs)
        {
            var target = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));

            using var loRaDevice = new LoRaDevice(new DevAddr(0x31312), new DevEui(0x312321321), ConnectionManager);

            Assert.Null(target.ResolveJoinAcceptWindowToUse());
        }
Esempio n. 18
0
        public override void NotifySucceeded(LoRaDevice loRaDevice, DownlinkPktFwdMessage downlink)
        {
            base.NotifySucceeded(loRaDevice, downlink);

            this.ResponseDownlink    = downlink;
            this.ProcessingSucceeded = true;
            this.complete.Release();
        }
Esempio n. 19
0
        public LoRaCloudToDeviceMessageWrapperTest()
        {
            var connectionManager = TestUtils.CreateConnectionManager();

            this.sampleDevice = new LoRaDevice("123131", "1231231232132", connectionManager);

            connectionManager.Register(this.sampleDevice, new Mock <ILoRaDeviceClient>().Object);
        }
Esempio n. 20
0
        public void When_ResetFcnt_In_New_Instance_Should_Have_HasFrameCountChanges_False()
        {
            var target = new LoRaDevice("1231", "12312", this.loRaDeviceClient.Object);

            // Setting from 0 to 0 should not trigger changes
            target.ResetFcnt();
            Assert.False(target.HasFrameCountChanges);
        }
        public void When_Device_PreferredWindow1_In_Time_For_First_Window_Should_Get_Check_C2D_Avaible_Time_Correctly(int delayInMs, int expectedMinMs, int expectedMaxMs)
        {
            var target     = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("1111", "2222", null);

            // Will be around 1000 - delay - 400
            Assert.InRange(target.GetAvailableTimeToCheckCloudToDeviceMessage(loRaDevice), TimeSpan.FromMilliseconds(expectedMinMs), TimeSpan.FromMilliseconds(expectedMaxMs));
        }
Esempio n. 22
0
        public void When_In_Time_For_Second_Window_Should_Resolve_Window_2(int delayInMs)
        {
            var target = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));

            using var loRaDevice = new LoRaDevice(new DevAddr(0x31312), new DevEui(0x312321321), ConnectionManager);

            Assert.Equal(ReceiveWindow2, target.ResolveReceiveWindowToUse(loRaDevice));
        }
Esempio n. 23
0
 public MultiGatewayFrameCounterUpdateStrategyTest()
 {
     this.deviceClient      = new Mock <ILoRaDeviceClient>();
     this.deviceApi         = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);
     this.gatewayID         = "test-gateway";
     this.connectionManager = new SingleDeviceConnectionManager(this.deviceClient.Object);
     this.device            = new LoRaDevice(new DevAddr(1), new DevEui(2), connectionManager);
 }
Esempio n. 24
0
        public async Task <bool> SaveChangesAsync(LoRaDevice loRaDevice)
        {
            if (loRaDevice.FCntUp % 10 == 0)
            {
                return(await loRaDevice.SaveFrameCountChangesAsync());
            }

            return(true);
        }
Esempio n. 25
0
            internal ScopedDeviceClientConnection(LoRaDevice loRaDevice)
            {
                if (loRaDevice.KeepAliveTimeout == 0)
                {
                    throw new InvalidOperationException("Scoped device client connection can be created only for devices with a connection timeout");
                }

                this.loRaDevice = loRaDevice;
            }
Esempio n. 26
0
        public async Task When_Incrementing_FcntDown_Should_Save_Frame_Counter()
        {
            var target = new LoRaDevice("1231", "12312", this.loRaDeviceClient.Object);

            this.loRaDeviceClient.Setup(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>()))
            .ReturnsAsync(true);

            Assert.Equal(10, target.IncrementFcntDown(10));
            await target.SaveFrameCountChangesAsync();
        }
        public void When_Device_Out_Of_Time_For_C2D_Receive_Should_Return_TimeSpan_Zero(int delayInMs, int devicePreferredReceiveWindow)
        {
            var target     = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("1111", "2222", null)
            {
                PreferredWindow = devicePreferredReceiveWindow,
            };

            Assert.Equal(TimeSpan.Zero, target.GetAvailableTimeToCheckCloudToDeviceMessage(loRaDevice));
        }
Esempio n. 28
0
        public void When_ResetFcnt_In_New_Instance_Should_Have_HasFrameCountChanges_False()
        {
            var target = new LoRaDevice("1231", "12312", new SingleDeviceConnectionManager(this.loRaDeviceClient.Object));

            // Setting from 0 to 0 should not trigger changes
            target.ResetFcnt();
            Assert.False(target.HasFrameCountChanges);
            Assert.Equal(0U, target.LastSavedFCntDown);
            Assert.Equal(0U, target.LastSavedFCntUp);
        }
        public void When_In_Time_For_First_Window_But_Device_Preferes_Seconds_Should_Resolve_Window_2(int delayInMs)
        {
            var target     = new LoRaOperationTimeWatcher(RegionManager.EU868, DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMilliseconds(delayInMs)));
            var loRaDevice = new LoRaDevice("31312", "312321321", null)
            {
                PreferredWindow = Constants.RECEIVE_WINDOW_2,
            };

            Assert.Equal(Constants.RECEIVE_WINDOW_2, target.ResolveReceiveWindowToUse(loRaDevice));
        }
        public void When_Registering_Existing_Connection_Throws()
        {
            // arrange
            using var cache             = new MemoryCache(new MemoryCacheOptions());
            using var connectionManager = new LoRaDeviceClientConnectionManager(cache, NullLogger <LoRaDeviceClientConnectionManager> .Instance);

            using var loraDevice = new LoRaDevice(null, new DevEui(0), null);
            connectionManager.Register(loraDevice, new Mock <ILoRaDeviceClient>().Object);
            Assert.Throws <InvalidOperationException>(() => connectionManager.Register(loraDevice, new Mock <ILoRaDeviceClient>().Object));
        }