helium / router

router combines a LoRaWAN Network Server with an API for console, and provides a proxy to the Helium blockchain
Apache License 2.0
70 stars 31 forks source link

LinkADRReq/LinkADRAns Looping #791

Closed lytzV closed 2 years ago

lytzV commented 2 years ago

Describe the bug When ADR is enabled, the LNS sends LINK_ADR_REQ after 20 uplinks, and the device responds with LINK_ADR_ANS. However, this exchange continues indefinitely because CHANNEL_MASK_ACK = 0, which rejects the LINK_ADR_REQ. There are really two questions here

  1. Is there any fall back for failed LINK_ADR_REQ? Or does it keep on trying until success?
  2. As you can see below in the two screenshots, two devices of the same make react differently to the same LINK_ADR_REQ. What could be the reason behind that?
Screen Shot 2022-06-09 at 12 59 39 PM

Buggy Device Info (please complete the following information):

Expected behavior If the Tx power, Channel Mask and Data Rate are valid, then the exchange should only happen once with all the ACK bit set to 1.

Screen Shot 2022-06-09 at 12 51 22 PM

Correct Device Info (please complete the following information):

Additional context

eikaramba commented 2 years ago

yeah quite annoying indeed. happens for most devices that i produce as well. not sure if the reason is the same but i observe the same loop of 20-30x join-req & join-akg before the join actually happens. maybe also a duplicate or related to this: https://github.com/helium/router/issues/818

vkynchev commented 2 years ago

@eikaramba are you using MCCI LMIC on those devices? I've encountered same issue and did fix it by enabling all channels for EU868 after JOIN event. By default only the first 3 channels are enabled (might also cause packet loss due to rf noise when only these 3 channels are used by a lot of devices).

#if defined(CFG_eu868)
    // enable all channels for EU868
    LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI);      // g-band
    LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
    LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK,  DR_FSK),  BAND_MILLI);      // g2-band
#endif

The reason for CHANNEL_MASK_ACK = 0 is that the mask requested by LINK_ADR_REQ is not valid when all channels are not configured/enabled in LMIC...

eikaramba commented 2 years ago

@vkynchev honestly i don't know as i am using heltecs cubecell boards where you basically just do

LoRaWAN.join();

however i see this configuration variable in the settings file

/*LoraWan channelsmask, default channels 0-7*/ 
uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };

wondering if that can be adapted maybe. i am out of my water here to actually understand the inner mechanics of the library used by heltec https://github.com/HelTecAutomation/CubeCell-Arduino

netbc commented 2 years ago

Server does not send optional CFList in the Join Accept message. When optional channels are not set the device will answer Channel Mask Ack 0 to Channel Mask 255 and LINK_ADR_REQ fails.