Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LoRaWAN channels for mask-type bands vs list-type bands #836

Closed
StevenCellist opened this issue Sep 25, 2023 · 5 comments
Closed

LoRaWAN channels for mask-type bands vs list-type bands #836

StevenCellist opened this issue Sep 25, 2023 · 5 comments
Labels
enhancement New feature or request resolved Issue was resolved (e.g. bug fixed, or feature implemented)

Comments

@StevenCellist
Copy link
Collaborator

Hi Jan,

As I'm looking to integrate ADR into LoRaWAN, I'm investigating your use of the so-called spans. While in itself a genius idea to tackle mask-type bands such as US902-928, things go wrong for list-type bands. Some list-type bands are even declared incorrectly (looking at CN780).
For list-type bands, the regional parameters define a minimum set of required channels; let's work with EU868. There are 3 that must be implemented: 868.1, .3 and .5. But then any LNS is free to specify extra channels using a CFList. Sure, these are added to a availableChannelsFreq frequency, but then the default ones aren't present here. Plus, the allowed DR range is not present in this structure, which may in theory be different for each frequency after NewChannelReq command.
And in case of mask-type bands, I am wondering if those bands always use fewer than or equal to 8 channels, even though there may be 72 or more defined? Because the availableChannelsFreq is just 8 channels long. But I don't have any US923 equipment, so can't check.

Maybe we can come up with a middle road that allows this efficient use of mask-type bands, but also permits irregular list-type bands.
Let's use this issue to propose ideas, and the best one will be implemented in some commit or PR in the near future :)

@jgromes
Copy link
Owner

jgromes commented Sep 25, 2023

The whole point behind the channel span structure is to save program space when defining the regional parameters, that's it. It's based on ideas I had while reading the LoRaWAN standard as an outsider, and it shows. For example, the mapping between channel ID and allowed data rate is quite complex. So I'm more than happy to replace this approach completely if a better solution appears.

any LNS is free to specify extra channels using a CFList. Sure, these are added to a availableChannelsFreq frequency, but then the default ones aren't present here. Plus, the allowed DR range is not present in this structure, which may in theory be different for each frequency after NewChannelReq command

This could be addressed by saving the default channels in a structure that also includes data rates. Perhaps this structure could be populated dynamically from the spans/CFList during activation (for default channels), and then appended to when processing NewChannelReq?

I am wondering if those bands always use fewer than or equal to 8 channels, even though there may be 72 or more defined

As far as I can tell, the standard does not specify the maximu, at least not directly. The reason I just picked 8 and ran with it is that:

a) TTN requires you to select only 8 channels and
b) the standard does mention that when joining, it should be considered to probe channels in groups of 9 (0-7 + 64, 8 - 15 + 65 etc).

So I think this should cover most use cases.

@jgromes jgromes added the enhancement New feature or request label Sep 25, 2023
@StevenCellist
Copy link
Collaborator Author

Thanks for the clarifications!

I'm trying to summarize all my findings below.


A channel plan's default parameters are defined, and set to the following:

  • mask-type bands specify:
    • upstream span 1 with for all frequencies a common (range of) DR, BW and CR
    • (optionally) upstream span 2 with for all frequencies a common (range of) DR, BW and CR
    • downstream span with for all frequencies a common (range of) DR, BW and CR
  • list-type bands specify:
    • a set of join-request channels, with one common (range of) DR, BW and CR - from PHY document it is apparent that this can be from 2 up to 6 channels
    • a set of default frequencies, with one common (range of) DR, BW and CR - from PHY document it is apparent that there are at most 3 but can be fewer (AS923 only has 2)

A join-request is performed based on the channel plan's defaults:

  • mask-type bands should select randomly from each block of 8 from the first span, alternating with aligned blocks of 1 from the second span if it exists
  • list-type bands should select one of the channel plan's specified frequencies

Regarding CFList:

  • mask-type bands will use this as a mask to fill the available frequencies - there are no default frequencies present. The DR, BW and CR for each of the selected frequencies is known from the channel plan.
  • list-type bands will use this to specify 5 more channels. The DR, BW and CR is known from the channel plan and shared among all. The first channels are specified from channel plan's default.

Regarding MAC commands:

  • mask-type bands implements
    • LinkADRReq, which in that case is likely sent as a repeated contiguous block with effectively a new CFList and requests a certain DR/BW and TX Power
  • list-type bands implements
    • LinkADRReq, which functions as a channel-ID mask to the currently available frequencies, and requests a certain DR/BW and TX power
    • NewChannelReq, which adds or modifies a channel based on its ID, and sets a frequency as well as DR-min and DR-max
    • DIChannelReq, which modifies the RX1 downlink frequency based on a channel ID.

So we should (dynamically) at least keep track of the following items (for each frequency, up to 9 may be required judging from here - although AS1 and AS2 even have 10 - and here):

  • channel ID (because of mask-type bands)
  • channel frequency
  • channel DR-min
  • channel DR-max
    And that is doubled for each downlink frequency (which in case of mask-type is uncoupled of uplink, but in case of list-type is coherent until DIChannelReq).

One question is yet unanswered:
How is the DR selected for the join-request? This does not seem to be actually specified.

  • This discussion does not really give a satisfying answer, but somewhat seems to prefer DR-max.

  • This link says:

We recommended that the DR should be varied randomly during the join process. If you use a fixed DR during joining, or if you send regular uplink messages with a “confirmed” frame, we suggest that you decrease the DR as the number of retries increases.

The Join-request message can be transmitted using any data rate and using one of the region-specific join channels. For example, in Europe an end device can transmit the Join-request message by randomly choosing among 868.10 MHz, 868.30 MHz, or 868.50 MHz. The Join-request message travels through one or more gateways to the Network Server.

A final note on all these parameters and NVM:

  • 9 channels uplink,
  • 9 channels downlink
  • a set of parameters is 5 bytes: 1 for channel index, 3 for frequency, 1 for DR-max << 4 | DR-min,
  • totalling for 925 = 90 bytes.

That's manageable - if we save all of this, we can remove the CFList from the table, which would then result in 192 bytes + 90 bytes = 282 bytes. So it would use just over half of the commonly seen 512 bytes.
However, officially up to 16 channels must be available, which would result in 16 * 2 * 5 = 160 bytes of available frequencies. I'm not really educated on memory management - is that OK or would you consider that problematic, i.e. worth it to limit ourselves to 10, 9 or 8?

Please - let me know if you spot a mistake, and what do you think about supporting the full 16 channels?

@StevenCellist
Copy link
Collaborator Author

@jgromes I've got this working mostly. What do you prefer - shove it into the existing PR, or make it a two-stage rocket?

@jgromes
Copy link
Owner

jgromes commented Oct 3, 2023

@StevenCellist sorry for being so far behind the curve on this one, I've been pretty busy lately. I don't see any issues on the high level.

Just one point regarding the NVM, I would very much like to keep it under 256 bytes. Failing to do that, I don't see much difference between 9 and 16 channels in terms of used storage. Since we're alredy past that limit, 16 would be preferrable for the sake of compliance.

Regarding integration to the upstream, please open a new PR for this.

@StevenCellist
Copy link
Collaborator Author

Closing this as it is fully integrated in #867

@jgromes jgromes added the resolved Issue was resolved (e.g. bug fixed, or feature implemented) label Nov 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request resolved Issue was resolved (e.g. bug fixed, or feature implemented)
Projects
None yet
Development

No branches or pull requests

2 participants