示例#1
0
 public LoRaPayloadJoinRequest(JoinEui joinEui, DevEui devEui, DevNonce devNonce, Mic mic)
 {
     MHdr     = new MacHeader(MacMessageType.JoinRequest);
     AppEui   = joinEui;
     DevEUI   = devEui;
     DevNonce = devNonce;
     Mic      = mic;
 }
示例#2
0
 public JoinRequestFrame(MacHeader mHdr, JoinEui joinEui, DevEui devEui, DevNonce devNonce, Mic mic, RadioMetadata radioMetadata)
 {
     MacHeader     = mHdr;
     JoinEui       = joinEui;
     DevEui        = devEui;
     DevNonce      = devNonce;
     Mic           = mic;
     RadioMetadata = radioMetadata;
 }
示例#3
0
        public async Task When_Initialized_Joined_OTAA_Device_Should_Have_All_Properties()
        {
            var appKey            = TestKeys.CreateAppKey(0xABC0200000000000, 0x09);
            var networkSessionKey = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var appSessionKey     = TestKeys.CreateAppSessionKey(0xABCD200000000000, 0x09);
            var joinEui           = new JoinEui(0xABC0200000000009);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "AppEUI", joinEui.ToString() },
                { "AppKey", appKey.ToString() },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevNonce", "0123" },
                { "DevAddr", "0000AABB" },
            });

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

            using var loRaDevice = CreateDefaultDevice();

            await loRaDevice.InitializeAsync(this.configuration);

            Assert.Equal(joinEui, loRaDevice.AppEui);
            Assert.Equal(appKey, loRaDevice.AppKey);
            Assert.Equal("mygateway", loRaDevice.GatewayID);
            Assert.Equal("DecoderValueSensor", loRaDevice.SensorDecoder);
            Assert.False(loRaDevice.IsABP);
            Assert.False(loRaDevice.IsOurDevice);
            Assert.Equal(networkSessionKey, loRaDevice.NwkSKey);
            Assert.Equal(appSessionKey, loRaDevice.AppSKey);
            Assert.Equal(new DevNonce(123), loRaDevice.DevNonce);
            Assert.Equal(new DevAddr(0x0000aabb), loRaDevice.DevAddr);
            Assert.Null(loRaDevice.ReportedDwellTimeSetting);
        }
示例#4
0
        public async Task When_Initialized_New_OTAA_Device_Should_Have_All_Properties()
        {
            var appKey  = TestKeys.CreateAppKey(0xABC0200000000000, 0x09);
            var joinEui = new JoinEui(0xABC0200000000009);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "AppEUI", joinEui.ToString() },
                { "AppKey", appKey.ToString() },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
            });

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

            using var connectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object);
            using var loRaDevice        = new LoRaDevice(null, new DevEui(0xabc0200000000009), connectionManager);
            await loRaDevice.InitializeAsync(this.configuration);

            Assert.Equal(joinEui, loRaDevice.AppEui);
            Assert.Equal(appKey, loRaDevice.AppKey);
            Assert.Equal("mygateway", loRaDevice.GatewayID);
            Assert.Equal("DecoderValueSensor", loRaDevice.SensorDecoder);
            Assert.Equal(0U, loRaDevice.FCntDown);
            Assert.Equal(0U, loRaDevice.LastSavedFCntDown);
            Assert.Equal(0U, loRaDevice.FCntUp);
            Assert.Equal(0U, loRaDevice.LastSavedFCntUp);
            Assert.False(loRaDevice.HasFrameCountChanges);
            Assert.Null(loRaDevice.AppSKey);
            Assert.Null(loRaDevice.NwkSKey);
            Assert.Null(loRaDevice.DevAddr);
            Assert.Null(loRaDevice.DevNonce);
            Assert.Null(loRaDevice.NetId);
            Assert.False(loRaDevice.IsABP);
            Assert.False(loRaDevice.IsOurDevice);
            Assert.Null(loRaDevice.ReportedDwellTimeSetting);
        }
示例#5
0
        public async Task OTAA_Join_With_Wrong_AppEUI_Fails()
        {
            var device = TestFixtureCi.Device13_OTAA;

            LogTestStart(device);

            var appEUIToUse = new JoinEui(0xFF7A00000000FCE3);

            Assert.NotEqual(appEUIToUse, device.AppEui);
            await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA);

            await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, appEUIToUse);

            await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey);

            await ArduinoDevice.SetupLora(TestFixtureCi.Configuration);

            var joinSucceeded = await ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 3);

            Assert.False(joinSucceeded, "Join suceeded for invalid AppKey");

            await ArduinoDevice.WaitForIdleAsync();
        }
示例#6
0
        public override void SetupTestDevices()
        {
            var gatewayID = Environment.GetEnvironmentVariable("IOTEDGE_DEVICEID") ?? Configuration.LeafDeviceGatewayID;

            // Simulated devices start at 1000

            // Device1001_Simulated_ABP: used for ABP simulator
            Device1001_Simulated_ABP = new TestDeviceInfo()
            {
                DeviceID       = "0000000000001001",
                GatewayID      = gatewayID,
                SensorDecoder  = "DecoderValueSensor",
                IsIoTHubDevice = true,
                AppSKey        = GetAppSessionKey(1001),
                NwkSKey        = GetNetworkSessionKey(1001),
                DevAddr        = new DevAddr(0x00001001),
            };

            // Device1002_Simulated_OTAA: used for simulator
            Device1002_Simulated_OTAA = new TestDeviceInfo()
            {
                DeviceID       = "0000000000001002",
                AppEui         = JoinEui.Parse("0000000000001002"),
                AppKey         = GetAppKey(1002),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
                SensorDecoder  = "DecoderValueSensor",
            };

            var fileName   = "EU863.json";
            var jsonString = File.ReadAllText(fileName);

            for (var deviceID = 5000; deviceID < 5000 + Configuration.NumberOfLoadTestConcentrators; deviceID++)
            {
                this.deviceRange5000_BasicsStationSimulators.Add(new TestDeviceInfo
                {
                    DeviceID       = deviceID.ToString("0000000000000000", CultureInfo.InvariantCulture),
                    RouterConfig   = JObject.Parse(jsonString),
                    IsIoTHubDevice = true,
                });
            }

            for (var deviceId = 1100; deviceId < 1105; deviceId++)
            {
                this.deviceRange1000_ABP.Add(CreateAbpDevice(deviceId));
            }

            for (var deviceId = 2000; deviceId < 2000 + Configuration.NumberOfLoadTestDevices; deviceId++)
            {
                this.deviceRange2000_ABP_FullLoad.Add(CreateAbpDevice(deviceId));
            }

            for (var deviceId = 3000; deviceId < 3000 + Configuration.NumberOfLoadTestDevices; deviceId++)
            {
                this.deviceRange3000_OTAA_FullLoad.Add(CreateOtaaDevice(deviceId));
            }

            for (var deviceId = 4000; deviceId < 4000 + Configuration.NumberOfLoadTestDevices; deviceId++)
            {
                this.deviceRange4000_OTAA_FullLoad.Add(CreateOtaaDevice(deviceId));
            }

            DeviceRange6000_OTAA_FullLoad =
                Enumerable.Range(6000, Configuration.NumberOfLoadTestDevices)
                .Select(deviceId => CreateOtaaDevice(deviceId))
                .ToList();

            DeviceRange9000_OTAA_FullLoad_DuplicationDrop =
                Enumerable.Range(9000, Configuration.NumberOfLoadTestDevices)
                .Select(deviceId => CreateOtaaDevice(deviceId, deduplicationMode: DeduplicationMode.Drop))
                .ToList();

            TestDeviceInfo CreateAbpDevice(int deviceId) =>
            new TestDeviceInfo
            {
                DeviceID       = deviceId.ToString("0000000000000000", CultureInfo.InvariantCulture),
                AppEui         = JoinEui.Parse(deviceId.ToString("0000000000000000", CultureInfo.InvariantCulture)),
                AppKey         = GetAppKey(deviceId),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
                SensorDecoder  = "DecoderValueSensor",
                AppSKey        = GetAppSessionKey(deviceId),
                NwkSKey        = GetNetworkSessionKey(deviceId),
                DevAddr        = DevAddr.Parse(deviceId.ToString("00000000", CultureInfo.InvariantCulture)),
            };

            TestDeviceInfo CreateOtaaDevice(int deviceId, DeduplicationMode deduplicationMode = DeduplicationMode.None) =>
            new TestDeviceInfo
            {
                DeviceID       = deviceId.ToString("0000000000000000", CultureInfo.InvariantCulture),
                AppEui         = JoinEui.Parse(deviceId.ToString("0000000000000000", CultureInfo.InvariantCulture)),
                AppKey         = GetAppKey(deviceId),
                IsIoTHubDevice = true,
                SensorDecoder  = "DecoderValueSensor",
                Deduplication  = deduplicationMode
            };
        }
示例#7
0
        public static bool TryRead <T>(this TwinCollection twinCollection, string property, ILogger?logger, [NotNullWhen(true)] out T?value)
        {
            _ = twinCollection ?? throw new ArgumentNullException(nameof(twinCollection));

            value = default;

            if (!twinCollection.Contains(property))
            {
                return(false);
            }

            // cast to object to avoid dynamic code to be generated
            var some = (object)twinCollection[property];

            // quick path for values that can be directly converted
            if (some is Newtonsoft.Json.Linq.JValue someJValue)
            {
                if (someJValue.Value is T someT)
                {
                    value = someT;
                    return(true);
                }
            }

            try
            {
                var t      = typeof(T);
                var tPrime = Nullable.GetUnderlyingType(t) ?? t;

                // For 100% case coverage we should handle the case where type T is nullable and the token is null.
                // Since this is not possible in IoT hub, we do not handle the null cases exhaustively.

                if (tPrime == StationEuiType)
                {
                    value = (T)(object)StationEui.Parse(some.ToString());
                }
                else if (tPrime == DevNonceType)
                {
                    value = (T)(object)new DevNonce(Convert.ToUInt16(some, CultureInfo.InvariantCulture));
                }
                else if (tPrime == DevAddrType)
                {
                    value = (T)(object)DevAddr.Parse(some.ToString());
                }
                else if (tPrime == AppSessionKeyType)
                {
                    value = (T)(object)AppSessionKey.Parse(some.ToString());
                }
                else if (tPrime == AppKeyType)
                {
                    value = (T)(object)AppKey.Parse(some.ToString());
                }
                else if (tPrime == NetworkSessionKeyType)
                {
                    value = (T)(object)NetworkSessionKey.Parse(some.ToString());
                }
                else if (tPrime == JoinEuiType)
                {
                    value = (T)(object)JoinEui.Parse(some.ToString());
                }
                else if (tPrime == NetIdType)
                {
                    value = (T)(object)NetId.Parse(some.ToString());
                }
                else
                {
                    value = (T)Convert.ChangeType(some, t, CultureInfo.InvariantCulture);
                }
                if (t.IsEnum && !t.IsEnumDefined(value))
                {
                    LogParsingError(logger, property, some);
                    return(false);
                }
            }
            catch (Exception ex) when(ex is ArgumentException
                                      or InvalidCastException
                                      or FormatException
                                      or OverflowException
                                      or Newtonsoft.Json.JsonSerializationException)
            {
                LogParsingError(logger, property, some, ex);
                return(false);
            }
            return(true);
        }
        public override void SetupTestDevices()
        {
            var gatewayID = Environment.GetEnvironmentVariable("IOTEDGE_DEVICEID") ?? Configuration.LeafDeviceGatewayID;

            // Device1_OTAA: used for join test only
            Device1_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(1),
                AppEui         = GetJoinEui(1),
                AppKey         = GetAppKey(1),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device2_OTAA: used for failed join (wrong devEUI)
            Device2_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(2),
                AppEui         = GetJoinEui(2),
                AppKey         = GetAppKey(2),
                GatewayID      = gatewayID,
                IsIoTHubDevice = false,
            };

            // Device3_OTAA: used for failed join (wrong appKey)
            Device3_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(3),
                AppEui         = GetJoinEui(3),
                AppKey         = GetAppKey(3),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device4_OTAA: used for OTAA confirmed & unconfirmed messaging
            Device4_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(4),
                AppEui         = GetJoinEui(4),
                AppKey         = GetAppKey(4),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
                RX1DROffset    = 1
            };

            Device4_OTAA_MultiGw = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(4, true),
                AppEui         = GetJoinEui(4, true),
                AppKey         = GetAppKey(4, true),
                IsIoTHubDevice = true,
                RX1DROffset    = 1
            };

            // Device5_ABP: used for ABP confirmed & unconfirmed messaging
            Device5_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(5),
                AppSKey        = GetAppSessionKey(5),
                NwkSKey        = GetNetworkSessionKey(5),
                DevAddr        = new DevAddr(0x0028b1b0),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            Device5_ABP_MultiGw = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(5, true),
                AppSKey        = GetAppSessionKey(5, true),
                NwkSKey        = GetNetworkSessionKey(5, true),
                DevAddr        = new DevAddr(0x0028b1b0),
                IsIoTHubDevice = true,
            };

            // Device6_ABP: used for ABP wrong devaddr
            Device6_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(6),
                AppSKey        = GetAppSessionKey(6),
                NwkSKey        = GetNetworkSessionKey(6),
                DevAddr        = new DevAddr(0x00000006),
                GatewayID      = gatewayID,
                IsIoTHubDevice = false,
            };

            // Device7_ABP: used for ABP wrong nwkskey
            Device7_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(7),
                AppSKey        = GetAppSessionKey(7),
                NwkSKey        = GetNetworkSessionKey(7),
                DevAddr        = new DevAddr(0x00000007),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device8_ABP: used for ABP invalid nwkskey (mic fails)
            Device8_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(8),
                AppSKey        = GetAppSessionKey(8),
                NwkSKey        = GetNetworkSessionKey(8),
                DevAddr        = new DevAddr(0x00000008),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device9_OTAA: used for confirmed message & C2D
            Device9_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(9),
                AppEui         = GetJoinEui(9),
                AppKey         = GetAppKey(9),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
                RXDelay        = 2
            };

            // Device10_OTAA: used for unconfirmed message & C2D
            Device10_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(10),
                AppEui         = GetJoinEui(10),
                AppKey         = GetAppKey(10),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device11_OTAA: used for http decoder
            Device11_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(11),
                AppEui         = GetJoinEui(11),
                AppKey         = GetAppKey(11),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
                SensorDecoder  = "http://sensordecodermodule/api/DecoderValueSensor",
            };

            // Device12_OTAA: used for reflection based decoder
            Device12_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(12),
                AppEui         = GetJoinEui(12),
                AppKey         = GetAppKey(12),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device13_OTAA: used for Join with wrong AppEUI
            Device13_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(13),
                AppEui         = GetJoinEui(13),
                AppKey         = GetAppKey(13),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device14_OTAA: used for Confirmed C2D message
            Device14_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(14),
                AppEui         = GetJoinEui(14),
                AppKey         = GetAppKey(14),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            Device14_OTAA_MultiGw = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(14, true),
                AppEui         = GetJoinEui(14, true),
                AppKey         = GetAppKey(14, true),
                IsIoTHubDevice = true,
            };

            // Device15_OTAA: used for the Fport test
            Device15_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(15),
                AppEui         = GetJoinEui(15),
                AppKey         = GetAppKey(15),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            Device15_OTAA_MultiGw = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(15, true),
                AppEui         = GetJoinEui(15, true),
                AppKey         = GetAppKey(15, true),
                IsIoTHubDevice = true,
            };
            // Device16_ABP: used for same DevAddr test
            Device16_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(16),
                AppSKey        = GetAppSessionKey(16),
                NwkSKey        = GetNetworkSessionKey(16),
                DevAddr        = new DevAddr(0x00000016),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device17_ABP: used for same DevAddr test
            Device17_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(17),
                AppSKey        = GetAppSessionKey(17),
                NwkSKey        = GetNetworkSessionKey(17),
                DevAddr        = Device16_ABP.DevAddr, // MUST match DevAddr from Device16
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device18_ABP: used for C2D invalid fport testing
            Device18_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(18),
                AppSKey        = GetAppSessionKey(18),
                NwkSKey        = GetNetworkSessionKey(18),
                DevAddr        = new DevAddr(0x00000018),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true
            };

            // Device19_ABP: used for C2D invalid fport testing
            Device19_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(19),
                AppSKey        = GetAppSessionKey(19),
                NwkSKey        = GetNetworkSessionKey(19),
                DevAddr        = new DevAddr(0x00000019),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true
            };

            // Device20_OTAA: used for join and rejoin test
            Device20_OTAA = new TestDeviceInfo()
            {
                DeviceID        = GetKey16(20),
                AppEui          = GetJoinEui(20),
                AppKey          = GetAppKey(20),
                GatewayID       = gatewayID,
                IsIoTHubDevice  = true,
                RX2DataRate     = 3,
                PreferredWindow = ReceiveWindow2
            };

            Device20_OTAA_MultiGw = new TestDeviceInfo()
            {
                DeviceID        = GetKey16(20, true),
                AppEui          = GetJoinEui(20, true),
                AppKey          = GetAppKey(20, true),
                IsIoTHubDevice  = true,
                RX2DataRate     = 3,
                PreferredWindow = ReceiveWindow2
            };

            // Device21_ABP: Preferred 2nd window
            Device21_ABP = new TestDeviceInfo()
            {
                DeviceID        = GetKey16(21),
                AppSKey         = GetAppSessionKey(21),
                NwkSKey         = GetNetworkSessionKey(21),
                DevAddr         = new DevAddr(0x00000021),
                GatewayID       = gatewayID,
                IsIoTHubDevice  = true,
                PreferredWindow = ReceiveWindow2
            };

            // Device22_ABP: used for mac Command testing
            Device22_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(22),
                AppSKey        = GetAppSessionKey(22),
                NwkSKey        = GetNetworkSessionKey(22),
                DevAddr        = new DevAddr(0x00000022),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            // Device23_OTAA: used for C2D mac Command testing
            Device23_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(23),
                AppEui         = GetJoinEui(23),
                AppKey         = GetAppKey(23),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true,
            };

            Device23_OTAA_MultiGw = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(23, true),
                AppEui         = GetJoinEui(23, true),
                AppKey         = GetAppKey(23, true),
                IsIoTHubDevice = true
            };

            // Device24_OTAA: used for C2D mac Command testing
            Device24_ABP = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(24),
                AppSKey        = GetAppSessionKey(24),
                NwkSKey        = GetNetworkSessionKey(24),
                DevAddr        = new DevAddr(0x00000024),
                IsIoTHubDevice = true,
                ClassType      = 'C',
            };

            // Device25_ABP: Connection timeout
            Device25_ABP = new TestDeviceInfo()
            {
                DeviceID         = "0000000000000025",
                AppSKey          = GetAppSessionKey(25),
                NwkSKey          = GetNetworkSessionKey(25),
                DevAddr          = new DevAddr(0x00000025),
                GatewayID        = gatewayID,
                IsIoTHubDevice   = true,
                KeepAliveTimeout = 60
            };

            // Device26_ABP: Connection timeout
            Device26_ABP = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000026",
                AppSKey        = GetAppSessionKey(26),
                NwkSKey        = GetNetworkSessionKey(26),
                DevAddr        = new DevAddr(0x00000026),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true
            };

            Device27_OTAA = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000027",
                AppEui         = JoinEui.Parse("0000000000000027"),
                AppKey         = GetAppKey(27),
                IsIoTHubDevice = true
            };

            Device28_ABP = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000028",
                AppSKey        = GetAppSessionKey(28),
                NwkSKey        = GetNetworkSessionKey(28),
                DevAddr        = new DevAddr(0x00000027),
                IsIoTHubDevice = true,
                Deduplication  = DeduplicationMode.Drop
            };

            Device29_ABP = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000029",
                AppSKey        = GetAppSessionKey(29),
                NwkSKey        = GetNetworkSessionKey(29),
                DevAddr        = new DevAddr(0x00000029),
                IsIoTHubDevice = true,
                Deduplication  = DeduplicationMode.Mark
            };

            Device30_OTAA = new TestDeviceInfo()
            {
                DeviceID       = GetKey16(30),
                AppEui         = GetJoinEui(30),
                AppKey         = GetAppKey(30),
                IsIoTHubDevice = true
            };

            Device31_OTAA = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000031",
                AppEui         = JoinEui.Parse("0000000000000031"),
                AppKey         = GetAppKey(31),
                IsIoTHubDevice = true,
                Deduplication  = DeduplicationMode.Drop
            };

            Device32_ABP = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000032",
                AppSKey        = GetAppSessionKey(32),
                NwkSKey        = GetNetworkSessionKey(32),
                DevAddr        = new DevAddr(0x00000032),
                GatewayID      = gatewayID,
                IsIoTHubDevice = true
            };

            Device33_OTAA = new TestDeviceInfo()
            {
                DeviceID       = "0000000000000033",
                AppEui         = JoinEui.Parse("0000000000000033"),
                AppKey         = GetAppKey(33),
                IsIoTHubDevice = true
            };
        }
 public JoinEui GetJoinEui(int deviceId, bool multiGw = false) =>
 JoinEui.Parse(GetKey16(deviceId, multiGw));
 internal sealed record JoinMessageKey(JoinEui JoinEui, DevEui DevEui, DevNonce DevNonce);