public async Task Test_ABP_Device_With_Connection_Timeout() { this.LogTestStart(new TestDeviceInfo[] { this.TestFixtureCi.Device25_ABP, this.TestFixtureCi.Device26_ABP }); // Sends 1 message from device 25 var device25 = this.TestFixtureCi.Device25_ABP; await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device25.DevAddr, device25.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device25.NwkSKey, device25.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); await this.ArduinoDevice.transferPacketAsync(PayloadGenerator.Next().ToString(), 10); // wait 61 seconds await Task.Delay(TimeSpan.FromSeconds(120)); // Send 1 message from device 26 var device26 = this.TestFixtureCi.Device26_ABP; await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device26.DevAddr, device26.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device26.NwkSKey, device26.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); await this.ArduinoDevice.transferPacketAsync(PayloadGenerator.Next().ToString(), 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); this.TestFixtureCi.ClearLogs(); // Send 1 message from device 25 and check that connection was restablished await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device25.DevAddr, device25.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device25.NwkSKey, device25.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var expectedMessage = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(expectedMessage, 10); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device25.DeviceID}: message '{{\"value\":{expectedMessage}}}' sent to hub"); // "device client reconnected" await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device25.DeviceID}: device client reconnected"); }
private async Task SendABPMessages(int MESSAGES_COUNT, TestDeviceInfo device) { await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); // Sends 10x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { var msg = PayloadGenerator.Next().ToString(); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixture.ClearLogs(); } // Sends 10x confirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { var msg = PayloadGenerator.Next().ToString(); Log($"{device.DeviceID}: Sending confirmed '{msg}' {i + 1}/{MESSAGES_COUNT}"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixture.ClearLogs(); } }
public async Task Test_MultiGW_OTTA_Join_Single() { var device = this.TestFixtureCi.Device27_OTAA; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // validate that one GW refused the join const string joinRefusedMsg = "join refused"; var joinRefused = await this.TestFixtureCi.AssertNetworkServerModuleLogExistsAsync((s) => s.IndexOf(joinRefusedMsg) != -1, new SearchLogOptions(joinRefusedMsg)); Assert.True(joinRefused.Found); await this.TestFixtureCi.WaitForTwinSyncAfterJoinAsync(this.ArduinoDevice.SerialLogs, device.DeviceID); // expecting both gw to start picking up messages // and sending to IoT hub. var bothReported = false; for (var i = 0; i < 5; i++) { var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); bothReported = await this.TestFixtureCi.ValidateMultiGatewaySources((log) => log.StartsWith($"{device.DeviceID}: sending message", StringComparison.OrdinalIgnoreCase)); if (bothReported) { break; } } Assert.True(bothReported); }
public async Task Test_ABP_Mismatch_NwkSKey_And_AppSKey_Fails_Mic_Validation() { var device = this.TestFixture.Device7_ABP; LogTestStart(device); var appSKeyToUse = "000102030405060708090A0B0C0D0E0F"; var nwkSKeyToUse = "01020304050607080910111213141516"; Assert.NotEqual(appSKeyToUse, device.AppSKey); Assert.NotEqual(nwkSKeyToUse, device.NwkSKey); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(nwkSKeyToUse, appSKeyToUse, null); await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); await this.ArduinoDevice.transferPacketAsync(PayloadGenerator.Next().ToString(), 10); // wait for serial logs to be ready await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done //await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.lora.SerialLogs); // 0000000000000005: with devAddr 0028B1B0 check MIC failed. Device will be ignored from now on await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: with devAddr {device.DevAddr} check MIC failed. Device will be ignored from now on"); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); this.TestFixture.ClearLogs(); // Try with confirmed message await this.ArduinoDevice.transferPacketWithConfirmedAsync(PayloadGenerator.Next().ToString(), 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // 0000000000000005: with devAddr 0028B1B0 check MIC failed. Device will be ignored from now on await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: with devAddr {device.DevAddr} check MIC failed. Device will be ignored from now on"); // wait until arduino stops trying to send confirmed msg await this.ArduinoDevice.WaitForIdleAsync(); }
public async Task Test_ABP_Wrong_DevAddr_Is_Ignored() { var device = this.TestFixture.Device6_ABP; LogTestStart(device); var devAddrToUse = "05060708"; Assert.NotEqual(devAddrToUse, device.DevAddr); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(devAddrToUse, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); await this.ArduinoDevice.transferPacketAsync(PayloadGenerator.Next().ToString(), 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 05060708: device is not our device, ignore message await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{devAddrToUse}: device is not our device, ignore message"); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); this.TestFixture.ClearLogs(); // Try with confirmed message await this.ArduinoDevice.transferPacketWithConfirmedAsync(PayloadGenerator.Next().ToString(), 10); // wait for serial logs to be ready await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received -- should not be there! Assert.DoesNotContain("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 05060708: device is not our device, ignore message await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{devAddrToUse}: device is not our device, ignore message"); }
public async Task Test_ABP_Invalid_NwkSKey_Fails_With_Mic_Error() { var device = this.TestFixture.Device8_ABP; LogTestStart(device); var nwkSKeyToUse = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; Assert.NotEqual(nwkSKeyToUse, device.NwkSKey); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(nwkSKeyToUse, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); await this.ArduinoDevice.transferPacketAsync(PayloadGenerator.Next().ToString(), 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000008: with devAddr 0028B1B3 check MIC failed. Device will be ignored from now on await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: with devAddr {device.DevAddr} check MIC failed. Device will be ignored from now on"); this.TestFixture.ClearLogs(); // Try with confirmed message await this.ArduinoDevice.transferPacketWithConfirmedAsync(PayloadGenerator.Next().ToString(), 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // 0000000000000008: with devAddr 0028B1B3 check MIC failed. await this.TestFixture.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: with devAddr {device.DevAddr} check MIC failed"); // Before starting new test, wait until Lora drivers stops sending/receiving data await this.ArduinoDevice.WaitForIdleAsync(); }
public async Task Test_OTAA_Confirmed_Receives_C2D_Message() { var device = this.TestFixture.Device9_OTAA; LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // Sends 2x confirmed messages for (var i = 1; i <= 2; ++i) { var msg = PayloadGenerator.Next().ToString(); Log($"{device.DeviceID}: Sending confirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); this.TestFixture.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); await this.TestFixture.SendCloudToDeviceMessage(device.DeviceID, c2dMessageBody, new Dictionary <string, string> { { FportPropertyName, "1" } }); Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var foundC2DMessage = false; var foundReceivePacket = false; var expectedRxSerial = $"+CMSG: PORT: 1; RX: \"{ToHexString(c2dMessageBody)}\""; Log($"Expected C2D received log is: {expectedRxSerial}"); // Sends 8x confirmed messages, stopping if C2D message is found for (var i = 3; i <= 10; ++i) { var msg = PayloadGenerator.Next().ToString(); Log($"{device.DeviceID}: Sending confirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(TimeSpan.FromSeconds(5)); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // check if c2d message was found // 0000000000000009: C2D message: 58 var c2dLogMessage = $"{device.DeviceID}: C2D message: {c2dMessageBody}"; var searchResults = await this.TestFixture.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(c2dLogMessage)); }, new SearchLogOptions { Description = c2dLogMessage, MaxAttempts = 1 }); // We should only receive the message once if (searchResults.Found) { Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/10) ? {foundC2DMessage}"); Assert.False(foundC2DMessage, "Cloud to Device message should have been detected in Network Service module only once"); foundC2DMessage = true; } var localFoundCloudToDeviceInSerial = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial); if (localFoundCloudToDeviceInSerial) { Assert.False(foundReceivePacket, "Cloud to device message should have been received only once"); foundReceivePacket = true; } this.TestFixture.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessage, $"Did not find '{device.DeviceID}: C2D message: {c2dMessageBody}' in logs"); // checks if log arrived if (!foundReceivePacket) { foundReceivePacket = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial); } Assert.True(foundReceivePacket, $"Could not find lora receiving message '{expectedRxSerial}'"); }
public async Task Test_OTAA_Join_Send_And_Rejoin_With_Custom_RX2_DR(string devicePropertyName) { var device = this.TestFixtureCi.GetDeviceByPropertyName(devicePropertyName); this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); if (device.IsMultiGw) { await this.TestFixtureCi.WaitForTwinSyncAfterJoinAsync(this.ArduinoDevice.SerialLogs, device.DeviceID); } // Sends 1x unconfirmed messages this.TestFixtureCi.ClearLogs(); var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000004: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Ensure device payload is available // Data: {"value": 51} var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); this.TestFixtureCi.ClearLogs(); msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // Checking than the communication occurs on DR 4 and RX2 as part of preferred windows RX2 and custom RX2 DR await AssertUtils.ContainsWithRetriesAsync(x => x.StartsWith("+CMSG: RXWIN2"), this.ArduinoDevice.SerialLogs); await this.TestFixtureCi.AssertNetworkServerModuleLogExistsAsync(x => x.Contains($"\"datr\":\"SF9BW125\""), null); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Ensure device payload is available // Data: {"value": 51} expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // rejoin await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded2 = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded2, "Rejoin failed"); if (device.IsMultiGw) { const string joinRefusedMsg = "join refused"; var joinRefused = await this.TestFixtureCi.AssertNetworkServerModuleLogExistsAsync((s) => s.IndexOf(joinRefusedMsg) != -1, new SearchLogOptions(joinRefusedMsg)); Assert.True(joinRefused.Found); } }
public async Task Test_OTAA_Unconfirmed_Receives_Confirmed_C2D_Message() { var device = this.TestFixtureCi.Device14_OTAA; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // Sends 2x unconfirmed messages for (var i = 1; i <= 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); this.TestFixtureCi.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); var msgId = Guid.NewGuid().ToString(); var c2dMessage = new LoRaCloudToDeviceMessage() { Payload = c2dMessageBody, Fport = 1, MessageId = msgId, Confirmed = true, }; await this.TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); this.Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var foundC2DMessage = false; var foundReceivePacket = false; var expectedRxSerial = $"+MSG: PORT: 1; RX: \"{this.ToHexString(c2dMessageBody)}\""; var expectedUDPMessageV1 = $"{device.DevAddr}: ConfirmedDataDown"; var expectedUDPMessageV2 = $"{device.DeviceID}: cloud to device message: {this.ToHexString(c2dMessageBody)}, id: {msgId}, fport: 1, confirmed: True"; this.Log($"Expected C2D received log is: {expectedRxSerial}"); this.Log($"Expected UDP log starting with: {expectedUDPMessageV1} or {expectedUDPMessageV2}"); // Sends 8x confirmed messages, stopping if C2D message is found for (var i = 3; i <= 10; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // check if c2d message was found var searchResults = await this.TestFixtureCi.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(expectedUDPMessageV1) || messageBody.StartsWith(expectedUDPMessageV2)); }, new SearchLogOptions { Description = $"{expectedUDPMessageV1} or {expectedUDPMessageV2}", MaxAttempts = 1 }); // We should only receive the message once if (searchResults.Found) { this.Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/10) ? {foundC2DMessage}"); Assert.False(foundC2DMessage, "Cloud to Device message should have been detected in Network Service module only once"); foundC2DMessage = true; } var localFoundCloudToDeviceInSerial = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial); if (localFoundCloudToDeviceInSerial) { Assert.False(foundReceivePacket, "Cloud to device message should have been received only once"); foundReceivePacket = true; } this.TestFixtureCi.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessage, $"Did not find {expectedUDPMessageV1} or {expectedUDPMessageV2} in logs"); // checks if log arrived if (!foundReceivePacket) { foundReceivePacket = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial); } Assert.True(foundReceivePacket, $"Could not find lora receiving message '{expectedRxSerial}'"); }
public async Task Test_Deduplication_Strategies(string devicePropertyName, string strategy) { var device = this.TestFixtureCi.GetDeviceByPropertyName(devicePropertyName); this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); for (int i = 0; i < 10; i++) { var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); var allGwGotIt = await this.TestFixtureCi.ValidateMultiGatewaySources((log) => log.IndexOf($"deduplication Strategy: {strategy}", StringComparison.OrdinalIgnoreCase) != -1); if (allGwGotIt) { var notDuplicate = "\"IsDuplicate\":false"; var isDuplicate = "\"IsDuplicate\":true"; var notDuplicateResult = await this.TestFixtureCi.SearchNetworkServerModuleAsync((s) => s.IndexOf(notDuplicate) != -1); var duplicateResult = await this.TestFixtureCi.SearchNetworkServerModuleAsync((s) => s.IndexOf(isDuplicate) != -1); Assert.NotNull(notDuplicateResult.MatchedEvent); Assert.NotNull(duplicateResult.MatchedEvent); Assert.NotEqual(duplicateResult.MatchedEvent.SourceId, notDuplicateResult.MatchedEvent.SourceId); switch (strategy) { case "Mark": await this.TestFixture.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, "dupmsg", "true"); break; case "Drop": var logMsg = $"{device.DeviceID}: duplication strategy indicated to not process message"; var droppedLog = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(logMsg), new SearchLogOptions { Description = logMsg, SourceIdFilter = duplicateResult.MatchedEvent.SourceId }); Assert.NotNull(droppedLog.MatchedEvent); var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); break; } } this.TestFixtureCi.ClearLogs(); } }
public async Task Test_OTAA_Confirmed_And_Unconfirmed_Message_With_Custom_RX1_DR_Offset() { const int MESSAGES_COUNT = 10; var device = this.TestFixtureCi.Device4_OTAA; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // Sends 10x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { Console.WriteLine($"Starting sending OTAA unconfirmed message {i + 1}/{MESSAGES_COUNT}"); this.TestFixtureCi.ClearLogs(); var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000004: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Ensure device payload is available // Data: {"value": 51} var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } // Sends 10x confirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { Console.WriteLine($"Starting sending OTAA confirmed message {i + 1}/{MESSAGES_COUNT}"); this.TestFixtureCi.ClearLogs(); var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Expect that the response is done on DR4 as the RX1 offset is 1 on this device. await this.TestFixtureCi.AssertNetworkServerModuleLogExistsAsync(log => log.Contains("\"datr\":\"SF8BW125\""), null); // Ensure device payload is available // Data: {"value": 51} var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } }
public async Task Test_OTAA_Join_Send_And_Rejoin() { var device = this.TestFixtureCi.Device20_OTAA; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // Sends 10x unconfirmed messages this.TestFixtureCi.ClearLogs(); var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000004: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Ensure device payload is available // Data: {"value": 51} var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); this.TestFixtureCi.ClearLogs(); msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Ensure device payload is available // Data: {"value": 51} expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded2 = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded2, "Rejoin failed"); }
public async Task Test_OTAA_Confirmed_And_Unconfirmed_Message_With_Custom_RX1_DR_Offset(string devicePropertyName) { var device = this.TestFixtureCi.GetDeviceByPropertyName(devicePropertyName); const int MESSAGES_COUNT = 10; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); if (device.IsMultiGw) { await this.TestFixtureCi.WaitForTwinSyncAfterJoinAsync(this.ArduinoDevice.SerialLogs, device.DeviceID); } // Sends 10x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { Console.WriteLine($"Starting sending OTAA unconfirmed message {i + 1}/{MESSAGES_COUNT}"); this.TestFixtureCi.ClearLogs(); var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000004: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); // Ensure device payload is available // Data: {"value": 51} var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } // Sends 10x confirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { Console.WriteLine($"Starting sending OTAA confirmed message {i + 1}/{MESSAGES_COUNT}"); this.TestFixtureCi.ClearLogs(); var msg = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); if (device.IsMultiGw) { // multi gw, make sure one ignored the message var searchTokenSending = $"{device.DeviceID}: sending a downstream message"; var sending = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenSending, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(sending.MatchedEvent); var searchTokenAlreadySent = $"{device.DeviceID}: another gateway has already sent ack or downlink msg"; var ignored = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenAlreadySent, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(ignored.MatchedEvent); Assert.NotEqual(sending.MatchedEvent.SourceId, ignored.MatchedEvent.SourceId); } // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs, maxAttempts : 5, interval : TimeSpan.FromSeconds(10)); // 0000000000000004: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000004: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); if (this.ArduinoDevice.SerialLogs.Where(x => x.StartsWith("+CMSG: RXWIN1")).Count() > 0) { // Expect that the response is done on DR4 as the RX1 offset is 1 on this device. await this.TestFixtureCi.AssertNetworkServerModuleLogExistsAsync(log => log.Contains("\"datr\":\"SF8BW125\""), null); } // Ensure device payload is available // Data: {"value": 51} var expectedPayload = $"{{\"value\":{msg}}}"; await this.TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } }
public async Task Test_OTAA_Confirmed_Receives_C2D_Message_With_RX_Delay_2() { const int messagesToSend = 10; const int warmUpMessageCount = 2; var device = this.TestFixtureCi.Device9_OTAA; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // find the gateway that accepted the join var joinAccept = await this.TestFixtureCi.SearchNetworkServerModuleAsync((s) => s.IndexOf("JoinAccept", StringComparison.OrdinalIgnoreCase) != -1); Assert.NotNull(joinAccept); Assert.NotNull(joinAccept.MatchedEvent); var targetGw = joinAccept.MatchedEvent.SourceId; Assert.Equal(device.GatewayID, targetGw); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); // Sends 2x confirmed messages for (var i = 1; i <= warmUpMessageCount; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending confirmed '{msg}' {i}/{messagesToSend}"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); this.TestFixtureCi.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); var c2dMessage = new LoRaCloudToDeviceMessage() { Payload = c2dMessageBody, Fport = 1, MessageId = Guid.NewGuid().ToString(), }; await this.TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); this.Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var foundC2DMessageCount = 0; var foundReceivePacketCount = 0; var expectedRxSerial = $"+CMSG: PORT: 1; RX: \"{this.ToHexString(c2dMessageBody)}\""; this.Log($"Expected C2D received log is: {expectedRxSerial}"); var c2dLogMessage = $"{device.DeviceID}: done completing cloud to device message, id: {c2dMessage.MessageId}"; this.Log($"Expected C2D network server log is: {expectedRxSerial}"); // Sends 8x confirmed messages, stopping if C2D message is found for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending confirmed '{msg}' {i}/{messagesToSend}"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(TimeSpan.FromSeconds(5)); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // Check that RXDelay was correctly used if (this.ArduinoDevice.SerialLogs.Where(x => x.StartsWith("+CMSG: RXWIN1", StringComparison.OrdinalIgnoreCase)).Count() > 0) { await this.TestFixtureCi.CheckAnswerTimingAsync(device.RXDelay *Constants.CONVERT_TO_PKT_FWD_TIME, false, device.GatewayID); } else if (this.ArduinoDevice.SerialLogs.Where(x => x.StartsWith("+CMSG: RXWIN2", StringComparison.OrdinalIgnoreCase)).Count() > 0) { await this.TestFixtureCi.CheckAnswerTimingAsync(device.RXDelay *Constants.CONVERT_TO_PKT_FWD_TIME, true, device.GatewayID); } else { Assert.True(false, "We were not able to determine in which windows the acknowledgement was submitted"); } // check if c2d message was found // 0000000000000009: C2D message: 58 var searchResults = await this.TestFixtureCi.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(c2dLogMessage, StringComparison.OrdinalIgnoreCase)); }, new SearchLogOptions { Description = c2dLogMessage, MaxAttempts = 1 }); // We should only receive the message once if (searchResults.Found) { foundC2DMessageCount++; this.Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/{messagesToSend}) {foundC2DMessageCount} times"); this.EnsureNotSeenTooManyTimes(foundC2DMessageCount); } var localFoundCloudToDeviceInSerial = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial); if (localFoundCloudToDeviceInSerial) { foundReceivePacketCount++; this.Log($"{device.DeviceID}: Found C2D message in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketCount} times"); this.EnsureNotSeenTooManyTimes(foundReceivePacketCount); } this.TestFixtureCi.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessageCount > 0, $"Did not find '{device.DeviceID}: C2D message: {c2dMessageBody}' in logs"); // checks if log arrived if (foundReceivePacketCount == 0) { if (this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial)) { foundReceivePacketCount++; } } Assert.True(foundReceivePacketCount > 0, $"Could not find lora receiving message '{expectedRxSerial}'"); }
[InlineData(224, nameof(IntegrationTestFixture.Device19_ABP))] // >= 224 is reserved public async Task C2D_Using_Invalid_FPort_Should_Be_Ignored(byte fport, string devicePropertyName) { var device = this.TestFixture.GetDeviceByPropertyName(devicePropertyName); LogTestStart(device); // Setup LoRa device properties await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); // Setup protocol properties await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); // Sends 2x unconfirmed messages for (var i = 1; i <= 2; ++i) { var msg = PayloadGenerator.Next().ToString(); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); this.TestFixture.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); var c2dMessage = new Message(Encoding.UTF8.GetBytes(c2dMessageBody)) { MessageId = Guid.NewGuid().ToString(), }; c2dMessage.Properties[FportPropertyName] = fport.ToString(); await this.TestFixture.SendCloudToDeviceMessage(device.DeviceID, c2dMessage); Log($"Message {c2dMessageBody} sent to device"); // Following log will be generated in case C2D message has invalid fport: // "<device-id>: invalid fport '<fport>' in C2D message '<message-id>' var foundC2DInvalidFPortMessage = false; // Serial port will print the following once the message is received var expectedRxSerial = $"RX: \"{ToHexString(c2dMessageBody)}\""; Log($"Expected C2D contains: {expectedRxSerial}"); // Sends 8x unconfirmed messages, stopping if C2D message is found for (var i = 3; i <= 10; ++i) { var msg = PayloadGenerator.Next().ToString(); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // ensure c2d message is not found // 0000000000000016: C2D message: 58 var c2dLogMessage = $"{device.DeviceID}: C2D message: {c2dMessageBody}"; var searchC2DMessageLogResult = await this.TestFixture.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(c2dLogMessage)); }, new SearchLogOptions { Description = c2dLogMessage, MaxAttempts = 1 } ); Assert.False(searchC2DMessageLogResult.Found, $"Message with fport {fport} should not be forwarded to device"); // ensure log with error is found if (!foundC2DInvalidFPortMessage) { var invalidFportLog = $"{device.DeviceID}: invalid fport '{fport}' in C2D message '{c2dMessage.MessageId}'"; var searchInvalidFportLog = await this.TestFixture.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(invalidFportLog)); }, new SearchLogOptions { Description = invalidFportLog, MaxAttempts = 1 } ); foundC2DInvalidFPortMessage = searchInvalidFportLog.Found; } // Should not contain in the serial the c2d message Assert.DoesNotContain(this.ArduinoDevice.SerialLogs, log => log.Contains(expectedRxSerial, StringComparison.InvariantCultureIgnoreCase)); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); this.TestFixture.ClearLogs(); } Assert.True(foundC2DInvalidFPortMessage, "Invalid fport message was not found in network server log"); }
// Verifies that ABP confirmed and unconfirmed messages are working // Uses Device5_ABP private async Task Test_ABP_Confirmed_And_Unconfirmed_Message_With_ADR(string devicePropertyName) { var device = this.TestFixtureCi.GetDeviceByPropertyName(devicePropertyName); if (device.IsMultiGw) { Assert.True(await LoRaAPIHelper.ResetADRCache(device.DeviceID)); } await this.ArduinoDevice.setDeviceDefaultAsync(); const int MESSAGES_COUNT = 10; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion, LoRaArduinoSerial._data_rate_t.DR3, 4, true); // for a reason I need to set DR twice otherwise it reverts to DR 0 // await this.ArduinoDevice.setDataRateAsync(LoRaArduinoSerial._data_rate_t.DR3, LoRaArduinoSerial._physical_type_t.EU868); // Sends 5x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT / 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Sends 5x confirmed messages for (var i = 0; i < MESSAGES_COUNT / 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending confirmed '{msg}' {i + 1}/{MESSAGES_COUNT / 2}"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(2 *Constants.DELAY_BETWEEN_MESSAGES); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); if (device.IsMultiGw) { var searchTokenSending = $"{device.DeviceID}: sending a downstream message"; var sending = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenSending, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(sending.MatchedEvent); var searchTokenAlreadySent = $"{device.DeviceID}: another gateway has already sent ack or downlink msg"; var ignored = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenAlreadySent, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(ignored.MatchedEvent); Assert.NotEqual(sending.MatchedEvent.SourceId, ignored.MatchedEvent.SourceId); } this.TestFixtureCi.ClearLogs(); } // Sends 10x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT / 2}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Starting ADR test protocol this.Log($"{device.DeviceID}: Starting ADR protocol"); for (var i = 0; i < 56; ++i) { var message = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(message, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); } await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: ADR ack request received"); var searchTokenADRRateAdaptation = $"{device.DeviceID}: performing a rate adaptation: DR"; var received = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenADRRateAdaptation, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(received.MatchedEvent); if (device.IsMultiGw) { var searchTokenADRAlreadySent = $"{device.DeviceID}: another gateway has already sent ack or downlink msg"; var ignored = await this.TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(searchTokenADRAlreadySent, StringComparison.OrdinalIgnoreCase)); Assert.NotNull(ignored.MatchedEvent); Assert.NotEqual(received.MatchedEvent.SourceId, ignored.MatchedEvent.SourceId); } // Check the messages are now sent on DR5 for (var i = 0; i < 2; ++i) { var message = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(message, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DevAddr}: LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: changed, data rate: changed,", $"{device.DevAddr}: LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: not changed, data rate: changed,"); } }
public async Task Test_ABP_Confirmed_And_Unconfirmed_Message_With_ADR() { await this.ArduinoDevice.setDeviceDefaultAsync(); const int MESSAGES_COUNT = 10; var device = this.TestFixtureCi.Device5_ABP; this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion, LoRaArduinoSerial._data_rate_t.DR3, 4, true); // for a reason I need to set DR twice otherwise it reverts to DR 0 // await this.ArduinoDevice.setDataRateAsync(LoRaArduinoSerial._data_rate_t.DR3, LoRaArduinoSerial._physical_type_t.EU868); // Sends 5x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT / 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Sends 5x confirmed messages for (var i = 0; i < MESSAGES_COUNT / 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending confirmed '{msg}' {i + 1}/{MESSAGES_COUNT / 2}"); await this.ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10); await Task.Delay(2 *Constants.DELAY_BETWEEN_MESSAGES); // After transferPacketWithConfirmed: Expectation from serial // +CMSG: ACK Received await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Sends 10x unconfirmed messages for (var i = 0; i < MESSAGES_COUNT; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i + 1}/{MESSAGES_COUNT / 2}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // 0000000000000005: valid frame counter, msg: 1 server: 0 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: valid frame counter, msg:"); // 0000000000000005: decoding with: DecoderValueSensor port: 8 await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: decoding with: {device.SensorDecoder} port:"); // 0000000000000005: message '{"value": 51}' sent to hub await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: message '{{\"value\":{msg}}}' sent to hub"); this.TestFixtureCi.ClearLogs(); } // Starting ADR test protocol this.Log($"{device.DeviceID}: Starting ADR protocol"); for (var i = 0; i < 56; ++i) { var message = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(message, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); } await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: ADR ack request received"); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DeviceID}: performing a rate adaptation: DR"); // Check the messages are now sent on DR5 for (var i = 0; i < 2; ++i) { var message = PayloadGenerator.Next().ToString(); await this.ArduinoDevice.transferPacketAsync(message, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); await this.TestFixtureCi.AssertNetworkServerModuleLogStartsWithAsync($"{device.DevAddr}: LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: changed, data rate: changed,", $"{device.DevAddr}: LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: not changed, data rate: changed,"); } }
// Ensures that C2D messages are received when working with unconfirmed messages // Uses Device10_OTAA private async Task Test_OTAA_Unconfirmed_Receives_Confirmed_C2D_Message(string devicePropertyName) { const int messagesToSend = 10; const int warmUpMessageCount = 2; var device = this.TestFixtureCi.GetDeviceByPropertyName(devicePropertyName); this.LogTestStart(device); await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); await this.ArduinoDevice.SetupLora(this.TestFixtureCi.Configuration.LoraRegion); var joinSucceeded = await this.ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5); Assert.True(joinSucceeded, "Join failed"); // wait 1 second after joined await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN); if (device.IsMultiGw) { await this.TestFixtureCi.WaitForTwinSyncAfterJoinAsync(this.ArduinoDevice.SerialLogs, device.DeviceID); } // Sends 2x unconfirmed messages for (var i = 1; i <= warmUpMessageCount; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); this.TestFixtureCi.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); var msgId = Guid.NewGuid().ToString(); var c2dMessage = new LoRaCloudToDeviceMessage() { Payload = c2dMessageBody, Fport = 1, MessageId = msgId, Confirmed = true, }; await this.TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); this.Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var foundC2DMessageCount = 0; var foundReceivePacketCount = 0; var expectedRxSerial = $"+MSG: PORT: 1; RX: \"{this.ToHexString(c2dMessageBody)}\""; var expectedUDPMessageV1 = $"{device.DevAddr}: ConfirmedDataDown"; var expectedUDPMessageV2 = $"{device.DeviceID}: cloud to device message: {this.ToHexString(c2dMessageBody)}, id: {msgId}, fport: 1, confirmed: True"; this.Log($"Expected C2D received log is: {expectedRxSerial}"); this.Log($"Expected UDP log starting with: {expectedUDPMessageV1} or {expectedUDPMessageV2}"); // Sends 8x unconfirmed messages, stopping if C2D message is found for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // check if c2d message was found var searchResults = await this.TestFixtureCi.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(expectedUDPMessageV1, StringComparison.OrdinalIgnoreCase) || messageBody.StartsWith(expectedUDPMessageV2, StringComparison.OrdinalIgnoreCase)); }, new SearchLogOptions { Description = $"{expectedUDPMessageV1} or {expectedUDPMessageV2}", MaxAttempts = 1 }); // We should only receive the message once if (searchResults.Found) { foundC2DMessageCount++; this.Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/{messagesToSend}) {foundC2DMessageCount} times"); this.EnsureNotSeenTooManyTimes(foundC2DMessageCount); } var localFoundCloudToDeviceInSerial = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial); if (localFoundCloudToDeviceInSerial) { foundReceivePacketCount++; this.Log($"{device.DeviceID}: Found C2D message in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketCount} times"); this.EnsureNotSeenTooManyTimes(foundReceivePacketCount); } this.TestFixtureCi.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessageCount > 0, $"Did not find {expectedUDPMessageV1} or {expectedUDPMessageV2} in logs"); // checks if log arrived if (foundReceivePacketCount == 0) { if (this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial)) { foundReceivePacketCount++; } } Assert.True(foundReceivePacketCount > 0, $"Could not find lora receiving message '{expectedRxSerial}'"); }
private async Task Test_OTAA_Unconfirmed_Send_And_Receive_C2D_Mac_CommandsImplAsync(TestDeviceInfo device, string c2dMessageBody) { const int MaxAttempts = 5; const int UnconfirmedMsgCount = 2; // Sends 2x unconfirmed messages for (var i = 1; i <= UnconfirmedMsgCount; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{UnconfirmedMsgCount}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); this.TestFixtureCi.ClearLogs(); } var c2dMessage = new LoRaCloudToDeviceMessage() { Fport = 1, Payload = c2dMessageBody, MacCommands = new MacCommand[] { new DevStatusRequest(), } }; await this.TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); this.Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var macCommandReceivedMsg = $"{device.DeviceID}: cloud to device MAC command DevStatusCmd received"; var foundMacCommandReceivedMsg = false; var deviceMacCommandResponseMsg = $": DevStatusCmd mac command detected in upstream payload: Type: DevStatusCmd Answer, Battery Level:"; var foundDeviceMacCommandResponseMsg = false; // Sends 5x unconfirmed messages, stopping if assertions succeeded for (var i = 1; i <= MaxAttempts; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{MaxAttempts}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // check if c2d message was found if (!foundMacCommandReceivedMsg) { var searchResults = await this.TestFixtureCi.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(macCommandReceivedMsg)); }, new SearchLogOptions { Description = macCommandReceivedMsg, MaxAttempts = 1 }); // We should only receive the message once if (searchResults.Found) { foundMacCommandReceivedMsg = true; this.Log($"{device.DeviceID}: Found Mac C2D message in log (after sending {i}/{MaxAttempts}) ? {foundMacCommandReceivedMsg}"); } } if (!foundDeviceMacCommandResponseMsg) { var macSearchResults = await this.TestFixtureCi.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.Contains(deviceMacCommandResponseMsg, StringComparison.InvariantCultureIgnoreCase)); }, new SearchLogOptions { Description = deviceMacCommandResponseMsg, MaxAttempts = 1 }); // We should only receive the message once if (macSearchResults.Found) { foundDeviceMacCommandResponseMsg = true; this.Log($"{device.DeviceID}: Found Mac Command reply in log (after sending {i}/{MaxAttempts}) ? {foundDeviceMacCommandResponseMsg}"); } } this.TestFixtureCi.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); if (foundDeviceMacCommandResponseMsg && foundMacCommandReceivedMsg) { break; } } Assert.True(foundMacCommandReceivedMsg, $"Did not find in network server logs: '{macCommandReceivedMsg}'"); Assert.True(foundDeviceMacCommandResponseMsg, $"Did not find in network server logs: '{deviceMacCommandResponseMsg}'"); }
public async Task C2D_When_Device_Has_Preferred_Windows_2_Should_Receive_In_2nd_Window_With_Custom_DR() { const int messagesToSend = 10; const int warmUpMessageCount = 2; var device = this.TestFixtureCi.Device21_ABP; this.LogTestStart(device); // Setup LoRa device properties await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); // Setup protocol properties await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); // Sends 2x unconfirmed messages for (var i = 1; i <= warmUpMessageCount; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); this.TestFixture.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); var msgId = Guid.NewGuid().ToString(); var c2dMessage = new LoRaCloudToDeviceMessage() { Payload = c2dMessageBody, Fport = 1, MessageId = msgId, Confirmed = true, }; await this.TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); this.Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var foundC2DMessageCount = 0; var foundReceivePacketCount = 0; var foundReceivePacketInRX2Count = 0; var expectedRxSerial1 = $"+MSG: PORT: 1; RX: \"{this.ToHexString(c2dMessageBody)}\""; var expectedRxSerial2 = $"+MSG: RXWIN2"; var expectedUDPMessageV1 = $"{device.DevAddr}: ConfirmedDataDown"; var expectedUDPMessageV2 = $"{device.DeviceID}: cloud to device message: {this.ToHexString(c2dMessageBody)}, id: {msgId}, fport: 1, confirmed: True"; this.Log($"Expected C2D received log is: {expectedRxSerial1} and {expectedRxSerial2}"); this.Log($"Expected UDP log starting with: {expectedUDPMessageV1} or {expectedUDPMessageV2}"); // Sends 8x confirmed messages, stopping if C2D message is found for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // check if c2d message was found var searchResults = await this.TestFixture.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(expectedUDPMessageV1, StringComparison.OrdinalIgnoreCase) || messageBody.StartsWith(expectedUDPMessageV2, StringComparison.OrdinalIgnoreCase)); }, new SearchLogOptions { Description = $"{expectedUDPMessageV1} or {expectedUDPMessageV2}", MaxAttempts = 1, }); // We should only receive the message once if (searchResults.Found) { foundC2DMessageCount++; this.Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/{messagesToSend}) {foundC2DMessageCount} times"); this.EnsureNotSeenTooManyTimes(foundC2DMessageCount); } if (this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial1)) { foundReceivePacketCount++; this.Log($"{device.DeviceID}: Found C2D message in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketCount} times"); this.EnsureNotSeenTooManyTimes(foundReceivePacketCount); } if (this.ArduinoDevice.SerialLogs.Any(x => x.StartsWith(expectedRxSerial2, StringComparison.OrdinalIgnoreCase))) { foundReceivePacketInRX2Count++; this.Log($"{device.DeviceID}: Found C2D message (rx2) in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketInRX2Count} times"); this.EnsureNotSeenTooManyTimes(foundReceivePacketInRX2Count); } if (foundReceivePacketCount > 0 && foundReceivePacketInRX2Count > 0 && foundC2DMessageCount > 0) { this.Log($"{device.DeviceID}: Found all messages in log (after sending {i}/{messagesToSend})"); break; } this.TestFixture.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessageCount > 0, $"Did not find {expectedUDPMessageV1} or {expectedUDPMessageV2} in logs"); // checks if serial received the message if (foundReceivePacketCount == 0) { if (this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial1)) { foundReceivePacketCount++; } } Assert.True(foundReceivePacketCount > 0, $"Could not find lora receiving message '{expectedRxSerial1}'"); // checks if serial received the message in RX2 if (foundReceivePacketInRX2Count == 0) { if (this.ArduinoDevice.SerialLogs.Any(x => x.StartsWith(expectedRxSerial2, StringComparison.OrdinalIgnoreCase))) { foundReceivePacketInRX2Count++; } } Assert.True(foundReceivePacketInRX2Count > 0, $"Could not find lora receiving message '{expectedRxSerial2}'"); }
public async Task C2D_When_Device_Has_Preferred_Windows_2_Should_Receive_In_2nd_Window() { var device = this.TestFixtureCi.Device21_ABP; this.LogTestStart(device); // Setup LoRa device properties await this.ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await this.ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEUI); await this.ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); // Setup protocol properties await this.ArduinoDevice.SetupLora(this.TestFixture.Configuration.LoraRegion); // Sends 2x unconfirmed messages for (var i = 1; i <= 2; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); this.TestFixture.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(); var msgId = Guid.NewGuid().ToString(); await this.TestFixtureCi.SendCloudToDeviceMessage(device.DeviceID, msgId, c2dMessageBody, new Dictionary <string, string>() { { FportPropertyName, "1" }, { ConfirmedPropertyName, "true" }, }); this.Log($"Message {c2dMessageBody} sent to device, need to check if it receives"); var foundC2DMessage = false; var foundReceivePacket = false; var foundReceivePacketInRX2 = false; var expectedRxSerial1 = $"+MSG: PORT: 1; RX: \"{this.ToHexString(c2dMessageBody)}\""; var expectedRxSerial2 = $"+MSG: RXWIN2"; var expectedUDPMessageV1 = $"{device.DevAddr}: ConfirmedDataDown"; var expectedUDPMessageV2 = $"{device.DeviceID}: C2D message: {c2dMessageBody}, id: {msgId}, fport: 1, confirmed: True"; this.Log($"Expected C2D received log is: {expectedRxSerial1} and {expectedRxSerial2}"); this.Log($"Expected UDP log starting with: {expectedUDPMessageV1} or {expectedUDPMessageV2}"); // Sends 8x confirmed messages, stopping if C2D message is found for (var i = 3; i <= 10; ++i) { var msg = PayloadGenerator.Next().ToString(); this.Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/10"); await this.ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", this.ArduinoDevice.SerialLogs); // check if c2d message was found if (!foundC2DMessage) { var searchResults = await this.TestFixture.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(expectedUDPMessageV1) || messageBody.StartsWith(expectedUDPMessageV2)); }, new SearchLogOptions { Description = $"{expectedUDPMessageV1} or {expectedUDPMessageV2}", MaxAttempts = 1, }); // We should only receive the message once if (searchResults.Found) { this.Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/10)"); foundC2DMessage = true; } } if (!foundReceivePacket) { if (this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial1)) { this.Log($"{device.DeviceID}: Found serial log message {expectedRxSerial1} in log (after sending {i}/10)"); foundReceivePacket = true; } } if (!foundReceivePacketInRX2) { if (this.ArduinoDevice.SerialLogs.Any(x => x.StartsWith(expectedRxSerial2))) { this.Log($"{device.DeviceID}: Found serial log message {expectedRxSerial2} in log (after sending {i}/10)"); foundReceivePacketInRX2 = true; } } if (foundReceivePacket && foundReceivePacketInRX2 && foundC2DMessage) { this.Log($"{device.DeviceID}: Found all messages in log (after sending {i}/10)"); break; } this.TestFixture.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessage, $"Did not find {expectedUDPMessageV1} or {expectedUDPMessageV2} in logs"); // checks if serial received the message if (!foundReceivePacket) { foundReceivePacket = this.ArduinoDevice.SerialLogs.Contains(expectedRxSerial1); } Assert.True(foundReceivePacket, $"Could not find lora receiving message '{expectedRxSerial1}'"); // checks if serial received the message in RX2 if (!foundReceivePacketInRX2) { foundReceivePacketInRX2 = this.ArduinoDevice.SerialLogs.Any(x => x.StartsWith(expectedRxSerial2)); } Assert.True(foundReceivePacketInRX2, $"Could not find lora receiving message '{expectedRxSerial2}'"); }