Rak3172 retransimit

I am interfering with the acknowledgement of uplink frames at a certain frequency, causing the terminal to not receive the correct acknowledgement frame, when the terminal should choose a time to retransmit.
But my code will make the terminal only retransmit uplink frames with the same load in the uplink_routine function, but for the gateway, these frames are just the same load with different frame numbers. Is this a retransmission?
If not, how should my code be modified to add so that my terminal can automatically retransmit outside of uplink_routine.
Also, what is the maximum number of retransmissions the rak3172 can do? How do I set the value of rety?
I have the following code:

  // This example shows LoRaWan protocol joining the network in OTAA mode, class A, region CN470.
   //  Device will send uplink every 30 seconds.
  
  #define OTAA_PERIOD   (30000)
  /*************************************
  
     LoRaWAN band setting:
       RAK_REGION_EU433
       RAK_REGION_CN470
       RAK_REGION_RU864
       RAK_REGION_IN865
       RAK_REGION_EU868
       RAK_REGION_US915
       RAK_REGION_AU915
       RAK_REGION_KR920
       RAK_REGION_AS923
  
   *************************************/
  #define OTAA_BAND     (RAK_REGION_CN470)
  #define OTAA_DEVEUI   {---}
  #define OTAA_APPEUI   {---}
  #define OTAA_APPKEY  {---}
  
  /** Packet buffer for sending */
  uint8_t collected_data[64] = { 0 };
  uint16_t packet_id = 0;      // id number from 0
  
  void recvCallback(SERVICE_LORA_RECEIVE_T * data)
  {
      if (data->BufferSize > 0) {
          Serial.println("Something received!");
          for (int i = 0; i < data->BufferSize; i++) {
              Serial.printf("%x", data->Buffer[i]);
          }
          Serial.print("\r\n");
      }
  }
  
  void joinCallback(int32_t status)
  {
      Serial.printf("Join status: %d\r\n", status);
  }
  
  /*************************************
   * enum type for LoRa Event
      RAK_LORAMAC_STATUS_OK = 0,
      RAK_LORAMAC_STATUS_ERROR,
      RAK_LORAMAC_STATUS_TX_TIMEOUT,
      RAK_LORAMAC_STATUS_RX1_TIMEOUT,
      RAK_LORAMAC_STATUS_RX2_TIMEOUT,
      RAK_LORAMAC_STATUS_RX1_ERROR,
      RAK_LORAMAC_STATUS_RX2_ERROR,
      RAK_LORAMAC_STATUS_JOIN_FAIL,
      RAK_LORAMAC_STATUS_DOWNLINK_REPEATED,
      RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,
      RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,
      RAK_LORAMAC_STATUS_ADDRESS_FAIL,
      RAK_LORAMAC_STATUS_MIC_FAIL,
      RAK_LORAMAC_STATUS_MULTICAST_FAIL,
      RAK_LORAMAC_STATUS_BEACON_LOCKED,
      RAK_LORAMAC_STATUS_BEACON_LOST,
      RAK_LORAMAC_STATUS_BEACON_NOT_FOUND,
   *************************************/
  
  void sendCallback(int32_t status)
  {
      if (status == RAK_LORAMAC_STATUS_OK) {
          Serial.println("Successfully sent");
      } else {
          Serial.println("Sending failed");
      }
  }
  void setup()
  {
      Serial.begin(115200, RAK_AT_MODE);
      delay(2000);
    
      Serial.println("RAKwireless LoRaWan OTAA Example");
      Serial.println("------------------------------------------------------");
    
      if(api.lorawan.nwm.get() != 1)
      {
          Serial.printf("Set Node device work mode %s\r\n",
              api.lorawan.nwm.set() ? "Success" : "Fail");
          api.system.reboot();
      }
  
      // OTAA Device EUI MSB first
      uint8_t node_device_eui[8] = OTAA_DEVEUI;
      // OTAA Application EUI MSB first
      uint8_t node_app_eui[8] = OTAA_APPEUI;
      // OTAA Application Key MSB first
      uint8_t node_app_key[16] = OTAA_APPKEY;
    
      if (!api.lorawan.appeui.set(node_app_eui, 8)) {
          Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.appkey.set(node_app_key, 16)) {
          Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.deui.set(node_device_eui, 8)) {
          Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n");
          return;
      }
    
      if (!api.lorawan.band.set(OTAA_BAND)) {
          Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
          Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.njm.set(RAK_LORA_OTAA))	// Set the network join mode to OTAA
      {
          Serial.printf("LoRaWan OTAA - set network join mode is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.join())	// Join to Gateway
      {
          Serial.printf("LoRaWan OTAA - join fail! \r\n");
          return;
      }
    
      /** Wait for Join success */
      while (api.lorawan.njs.get() == 0) {
          Serial.print("Wait for LoRaWAN join...");
          api.lorawan.join();
          delay(10000);
      }
    
      if (!api.lorawan.adr.set(false)) {
          Serial.printf("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.rety.set(4)) {
          Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.cfm.set(1)) {
          Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n");
          return;
      }
      if (!api.lorawan.dr.set(0)) {   // dr=5,sf=7,bw=125kHz     dr=0,sf=12,bw=125
          Serial.printf("LoRaWan OTAA - set data rate is incorrect! \r\n");
          return;
      }
  
      /** Check LoRaWan Status*/
      Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF");	// Check Duty Cycle status
      Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED");	// Check Confirm status
      uint8_t assigned_dev_addr[4] = { 0 };
      api.lorawan.daddr.get(assigned_dev_addr, 4);
      Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);	// Check Device Address
      Serial.printf("Uplink period is %ums\r\n", OTAA_PERIOD);
      Serial.println("");
      api.lorawan.registerRecvCallback(recvCallback);
      api.lorawan.registerJoinCallback(joinCallback);
      api.lorawan.registerSendCallback(sendCallback);
  }
  
  void uplink_routine()
  {
      /** Payload of Uplink */
      uint8_t data_len = 0;
      collected_data[data_len++] = (uint8_t) 't';
      collected_data[data_len++] = (uint8_t) 'e';
      collected_data[data_len++] = (uint8_t) 's';
      collected_data[data_len++] = (uint8_t) 't';
      // 添加唯一编号
      collected_data[data_len++] = (uint8_t) ('0' + (packet_id % 10)); // Retain only single-digit numbers
  
      Serial.println("Data Packet:");
      for (int i = 0; i < data_len; i++) {
          Serial.printf("0x%02X ", collected_data[i]);
      }
      Serial.println("");
    
      /** Send the data package */
      if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {
          Serial.println("Sending is requested");
          delay(5000);
          Serial.printf("Send confirm %s\r\n", api.lorawan.cfs.get() ? "Success" : "Fail");
          if (api.lorawan.cfs.get()) {
              packet_id++;  // Incremental numbering upon receipt of confirmation
          }
      } else {
          Serial.println("Sending failed");
      }
  }
  
  void loop()
  {
      static uint64_t last = 0;
      static uint64_t elapsed;
    
      if ((elapsed = millis() - last) > OTAA_PERIOD) {
          last = millis();
          uplink_routine();
      }
  
      // //Serial.printf("Try sleep %ums..", OTAA_PERIOD);
      // api.system.sleep.all(OTAA_PERIOD);
      // //Serial.println("Wakeup..");
  }

Automatic retransmission with the same fCount is only possible if confirmed packet mode is enabled. You cannot re-transmit packages with the same fCount from the application.

Enable confirmed packet mode

api.lorawan.cfm.set(1);

Set number of retry if no ACK is received

api.lorawan.rety.set(2); // 2 re-transmission before giving up

My code has set cfm to 1 and rety to 4 in the setup function.
After jamming, ‘+EVT: SEND_CONFIRMED_FAILED’ appears, but the terminal doesn’t retransmit and only executes uplink_routine after 30 seconds.

is shown after all retransmission have already failed.

When you see this, it retried 4 times to send and never got an ACK.

I don’t see a change in current with 4 retransmissions using the power analyser, only with uplink_routine does the current change abruptly. Doesn’t this mean that no retransmission is happening?

/** Send the data package */
if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {
    Serial.println("Sending is requested");
    delay(5000);
    Serial.printf("Send confirm %s\r\n", api.lorawan.cfs.get() ? "Success" : "Fail");
    if (api.lorawan.cfs.get()) {
        packet_id++;  // Incremental numbering upon receipt of confirmation
    }
} else {
    Serial.println("Sending failed");
}

And the content of the load transmitted by the uplink_routine function remains the same, which means that no ack was received isn’t it?

There was no acknowledgment received, which should indicate a retransmission occurred. However, the analyzer shows no change in current, suggesting there was no retransmission. The contradiction between the two is confusing me.

Are you using the latest RUI3 version? V4.2.0?

I can confirm there is a problem in RUI3 V4.2.0 with confirmed packet retry sending.

RUI3 V4.1.1 works as expected.

Bug is reported to R&D team.

The version I’m using is V4.1.1.
image

You have a different problem in your code:

api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1);

The last parameter sets the retransmission number to 1.

See RUI3 documentation

It works for me in RUI3 V4.1.1:

But it does not retransmit in RUI3 V4.2.0:

Difference is that V4.1.1 uses LoRaMAC stack V1.0.3 while V4.2.0 is using LoRaMAC stack V1.0.4
We are trying to find out if there is a difference regarding retransmission. It could be a change in the LoRaWAN specifications.

If you see this in RUI3 V4.1.1, then you have a different problem. It does work for me.

Hello, I am using the RAK3172 with RUI3 V4.1.1 and I noticed that there is a 20-second delay between “send” and “failed” because I am using 5 retries. With version 4.2.0, the “failed” was instant after the “send”, regardless of the number of retries.

After this downgrade (to v4.1.1), I also noticed that ADR started working, which was not happening in version 4.2.0. Does this make sense?