public async Task Data_Rate_Is_Updated_When_C2D_With_LinkADRCmd_Received() { const int messagesToSend = 10; const int warmUpMessageCount = 2; var device = TestFixtureCi.Device32_ABP; LogTestStart(device); // Setup LoRa device properties await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEui); await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); // Setup protocol properties // Start with DR5 await ArduinoDevice.SetupLora(TestFixtureCi.Configuration.LoraRegion, LoRaArduinoSerial._data_rate_t.DR5, 4, true); await TestFixture.CleanupC2DDeviceQueueAsync(device.DeviceID); // Sends 2x unconfirmed messages for (var i = 1; i <= warmUpMessageCount; ++i) { var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", ArduinoDevice.SerialLogs); TestFixture.ClearLogs(); } var c2dMessage = new LoRaCloudToDeviceMessage() { Fport = FramePort.MacCommand, Payload = String.Empty, MacCommands = { new LinkADRRequest(datarate: 3, txPower: 4, chMask: 25, chMaskCntl: 0, nbTrans: 1) } // Update data rate to DR3 }; await TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); Log($"C2D Message sent to device, need to check if it receives"); var foundC2DMessage = false; var foundLinkADRCmd = false; var foundChangedDataRate = false; // Sends 8x unconfirmed messages, stopping if C2D message is found and data rate is updated for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i) { var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); // After transferPacket: Expectation from serial // +MSG: Done await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", ArduinoDevice.SerialLogs); // check if C2D message was found if (await SearchMessageAsync($"{device.DeviceID}: cloud to device MAC command LinkADRCmd received Type: LinkADRCmd Answer, datarate: 3")) { foundC2DMessage = true; } // check if LinkADRCmd MAC Command was detected if (await SearchMessageAsync("LinkADRCmd mac command detected in upstream payload: Type: LinkADRCmd Answer, power: changed, data rate: changed")) { foundLinkADRCmd = true; } // check if the data rate was changed to DR3 if (await SearchMessageAsync("\"datr\":\"SF9BW125\"")) { foundChangedDataRate = true; } async Task <bool> SearchMessageAsync(string message) { var searchResult = await TestFixtureCi.SearchNetworkServerModuleAsync(messageBody => messageBody.Contains(message, StringComparison.OrdinalIgnoreCase), new SearchLogOptions(message) { MaxAttempts = 1 }); return(searchResult.Found); } TestFixture.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); if (foundC2DMessage && foundLinkADRCmd && foundChangedDataRate) { break; } } Assert.True(foundC2DMessage, $"Could not find C2D message with MAC command LinkADRCmd in LNS log"); Assert.True(foundLinkADRCmd, $"Could not find LinkADRCmd MAC Command in LNS log"); Assert.True(foundChangedDataRate, $"Could not find updated data rate in LNS log"); }
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 = TestFixtureCi.Device21_ABP; LogTestStart(device); // Setup LoRa device properties await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP); await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEui); await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey); // Setup protocol properties await ArduinoDevice.SetupLora(TestFixture.Configuration); await TestFixture.CleanupC2DDeviceQueueAsync(device.DeviceID); // Sends 2x unconfirmed messages for (var i = 1; i <= warmUpMessageCount; ++i) { var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", ArduinoDevice.SerialLogs); TestFixture.ClearLogs(); } // sends C2D - between 10 and 99 var c2dMessageBody = (100 + random.Next(90)).ToString(CultureInfo.InvariantCulture); var msgId = Guid.NewGuid().ToString(); var c2dMessage = new LoRaCloudToDeviceMessage() { Payload = c2dMessageBody, Fport = FramePorts.App1, MessageId = msgId, Confirmed = true, }; await TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage); 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: \"{ToHexString(c2dMessageBody)}\""; var expectedRxSerial2 = $"+MSG: RXWIN2"; var expectedTcpMessageV1 = $"{device.DevAddr}: ConfirmedDataDown"; var expectedTcpMessageV2 = $"{device.DeviceID}: cloud to device message: {ToHexString(c2dMessageBody)}, id: {msgId}, fport: 1, confirmed: True"; Log($"Expected C2D received log is: {expectedRxSerial1} and {expectedRxSerial2}"); Log($"Expected TCP log starting with: {expectedTcpMessageV1} or {expectedTcpMessageV2}"); // Sends 8x confirmed messages, stopping if C2D message is found for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i) { var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture); Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}"); await ArduinoDevice.transferPacketAsync(msg, 10); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", ArduinoDevice.SerialLogs); // check if c2d message was found var searchResults = await TestFixture.SearchNetworkServerModuleAsync( (messageBody) => { return(messageBody.StartsWith(expectedTcpMessageV1, StringComparison.OrdinalIgnoreCase) || messageBody.StartsWith(expectedTcpMessageV2, StringComparison.OrdinalIgnoreCase)); }, new SearchLogOptions($"{expectedTcpMessageV1} or {expectedTcpMessageV2}") { MaxAttempts = 1, }); // We should only receive the message once if (searchResults.Found) { foundC2DMessageCount++; Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/{messagesToSend}) {foundC2DMessageCount} times"); EnsureNotSeenTooManyTimes(foundC2DMessageCount); } if (ArduinoDevice.SerialLogs.Contains(expectedRxSerial1)) { foundReceivePacketCount++; Log($"{device.DeviceID}: Found C2D message in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketCount} times"); EnsureNotSeenTooManyTimes(foundReceivePacketCount); } if (ArduinoDevice.SerialLogs.Any(x => x.StartsWith(expectedRxSerial2, StringComparison.OrdinalIgnoreCase))) { foundReceivePacketInRX2Count++; Log($"{device.DeviceID}: Found C2D message (rx2) in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketInRX2Count} times"); EnsureNotSeenTooManyTimes(foundReceivePacketInRX2Count); } if (foundReceivePacketCount > 0 && foundReceivePacketInRX2Count > 0 && foundC2DMessageCount > 0) { Log($"{device.DeviceID}: Found all messages in log (after sending {i}/{messagesToSend})"); break; } TestFixture.ClearLogs(); await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES); } Assert.True(foundC2DMessageCount > 0, $"Did not find {expectedTcpMessageV1} or {expectedTcpMessageV2} in logs"); // checks if serial received the message if (foundReceivePacketCount == 0) { if (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 (ArduinoDevice.SerialLogs.Any(x => x.StartsWith(expectedRxSerial2, StringComparison.OrdinalIgnoreCase))) { foundReceivePacketInRX2Count++; } } Assert.True(foundReceivePacketInRX2Count > 0, $"Could not find lora receiving message '{expectedRxSerial2}'"); }