TheThingsNetwork / lorawan-stack

The Things Stack, an Open Source LoRaWAN Network Server
https://www.thethingsindustries.com/stack/
Apache License 2.0
960 stars 302 forks source link

Support multiple LoRa standard channels on device #6526

Open virtualguy opened 1 year ago

virtualguy commented 1 year ago

Summary

Gateways with multiple concentrators (i.e. a 16ch gateway) can listen on more than one LoRa standard channel but this is not supported in the frequency plan definitions

lora-standard-channel: 
  frequency: 915900000
  data-rate: 6
  radio: 0

Current Situation

Only a single LoRa standard channel is configurable. A previous work around to specify the extra channels as normal uplink-channels with only a single data rate is no longer supported due to #6182

Why do we need this? Who uses it, and when?

Devices wanting to use more than one sub band for uplinks and wide channels

Proposed Implementation

Change lora-standard-channels to a list and then support added to the stack

lora-standard-channels: 
  - frequency: 915900000
  data-rate: 6
  radio: 0
  - frequency: 917500000
  data-rate: 6
  radio: 0

Alternatively allow a device to support multiple frequency plans like a gateway (frequency_plan_ids) and set the desired channels to the full set of channels across the plans

Contributing

Code of Conduct

virtualguy commented 1 year ago

@adriansmares, i'm happy to have a go at this if you can give a steer on which direction is preferred

adriansmares commented 1 year ago

A previous work around to specify the extra channels as normal uplink-channels with only a single data rate is no longer supported due to #6182

Could you please give more details on how #6182 affected the workaround ?

Also, which bands do you intend to use this with/were using before ?

onizmx commented 1 year ago

Hi @adriansmares. Yes we are somewhat affected by https://github.com/TheThingsNetwork/lorawan-stack/pull/6182.

We've explicitly defined 917500000, 919100000 within the list of uplink-channels, where we pull from custom frequency plan files via S3 fetcher. This change was working when we were running on 3.18.1.

And we've updated our system to 3.27.0 about two weeks ago, and figured (from the PR above) that DeviceDesiredChannels function in utils.go is not doing anything other than setting EnableUplink to true when fp has a matching channel with defaultChs for US & AU where CF List Type is ttnpb.CFListType_CHANNEL_MASKS.

We are mostly using AU_915_928_FSB_2_AND_FSB_3, or AU FSB 2 / AU FSB 1 but not limited to if that's what you are asking.

We've found two workarounds so far.

  1. Updating NS end device's mac_state.desired_parameters.channels by providing channel configurations that we want. This is not very scalable and prone to break on other changes in future.
  2. Changed these lines https://github.com/halter-corp/lorawan-stack/blob/3d826f5fd91db838c3bffcc6c89d5165b5202f07/pkg/networkserver/mac/utils.go#L639, so at least we can define data rate indices for a single lora standard channel which is related to another ticket that @virtualguy has opened (https://github.com/TheThingsNetwork/lorawan-stack/issues/6527)
adriansmares commented 1 year ago

So you guys were ahead of your times, sort of, and this issue (#6526) is just a symptom of your real problem (#6527).

For pretty much the whole existence of the LoRaWAN specification, the fixed channel plans were, as the name implies, fixed. This means that both the frequencies and the data rate indices were fixed - NewChannelReq/DlChannelReq were undefined for these regions - the L2 specification is very explicit about this:

image

This is why our desired channel generation loop does not edit the actual data rate indices for the fixed channel plans - it does not make sense to edit them, as they cannot be updated with NewChannelReq. If your end device firmware supported this, it was custom behavior and not compliant.

I am not entirely sure how future RP2/TS01 specifications will change this behavior, but for now pretty much all of the published LoRaWAN versions ban the use of NewChannelReq in the fixed channel plans.


If you would like to get back the old behavior, there are a couple of places which you need to edit back in your fork:

After you have done these two changes, it should be possible to use your old solution (define the standard channels in the normal channel list of the frequency plan).

virtualguy commented 1 year ago

@adriansmares indeed we are working outside the fixed band plan intended limits. We don't specifically need the NS to send down NewChannelReq however if an uplink arrives to the NS on a channel not in a devices band plan its dropped. Perhaps that would be a better place for us to allow these uplinks? Is there a strong reason to drop them?

adriansmares commented 1 year ago

@adriansmares indeed we are working outside the fixed band plan intended limits. We don't specifically need the NS to send down NewChannelReq however if an uplink arrives to the NS on a channel not in a devices band plan its dropped.

This is not correct. The channels for an AU915 device are as follows:

```json [ { "uplink_frequency": "915200000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "915400000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "915600000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "915800000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "916000000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "916200000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "916400000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "916600000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "916800000", "downlink_frequency": "923300000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "917000000", "downlink_frequency": "923900000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "917200000", "downlink_frequency": "924500000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "917400000", "downlink_frequency": "925100000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "917600000", "downlink_frequency": "925700000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "917800000", "downlink_frequency": "926300000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "918000000", "downlink_frequency": "926900000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "918200000", "downlink_frequency": "927500000", "max_data_rate_index": 5, "enable_uplink": true }, { "uplink_frequency": "918400000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "918600000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "918800000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "919000000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "919200000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "919400000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "919600000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "919800000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "920000000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "920200000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "920400000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "920600000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "920800000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "921000000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "921200000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "921400000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "921600000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "921800000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "922000000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "922200000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "922400000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "922600000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "922800000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "923000000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "923200000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "923400000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "923600000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "923800000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "924000000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "924200000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "924400000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "924600000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "924800000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "925000000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "925200000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "925400000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "925600000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "925800000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "926000000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "926200000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "926400000", "downlink_frequency": "923300000", "max_data_rate_index": 5 }, { "uplink_frequency": "926600000", "downlink_frequency": "923900000", "max_data_rate_index": 5 }, { "uplink_frequency": "926800000", "downlink_frequency": "924500000", "max_data_rate_index": 5 }, { "uplink_frequency": "927000000", "downlink_frequency": "925100000", "max_data_rate_index": 5 }, { "uplink_frequency": "927200000", "downlink_frequency": "925700000", "max_data_rate_index": 5 }, { "uplink_frequency": "927400000", "downlink_frequency": "926300000", "max_data_rate_index": 5 }, { "uplink_frequency": "927600000", "downlink_frequency": "926900000", "max_data_rate_index": 5 }, { "uplink_frequency": "927800000", "downlink_frequency": "927500000", "max_data_rate_index": 5 }, { "uplink_frequency": "915900000", "downlink_frequency": "923300000", "min_data_rate_index": 6, "max_data_rate_index": 6 }, { "uplink_frequency": "917500000", "downlink_frequency": "923900000", "min_data_rate_index": 6, "max_data_rate_index": 6, "enable_uplink": true }, { "uplink_frequency": "919100000", "downlink_frequency": "924500000", "min_data_rate_index": 6, "max_data_rate_index": 6 }, { "uplink_frequency": "920700000", "downlink_frequency": "925100000", "min_data_rate_index": 6, "max_data_rate_index": 6 }, { "uplink_frequency": "922300000", "downlink_frequency": "925700000", "min_data_rate_index": 6, "max_data_rate_index": 6 }, { "uplink_frequency": "923900000", "downlink_frequency": "926300000", "min_data_rate_index": 6, "max_data_rate_index": 6 }, { "uplink_frequency": "925500000", "downlink_frequency": "926900000", "min_data_rate_index": 6, "max_data_rate_index": 6 }, { "uplink_frequency": "927100000", "downlink_frequency": "927500000", "min_data_rate_index": 6, "max_data_rate_index": 6 } ] ```

Notice that both 915900000 and 917500000 are defined - sure, they are not enabled, because I generated this using FSB2, but the Network Server won't drop them. Your custom plan which defines them in the uplink-channels section should actually have them marked as enabled. The check that you are probably thinking of is the following:

https://github.com/TheThingsNetwork/lorawan-stack/blob/36a71355ed0f8f53c59b83d03684098245788982/pkg/networkserver/grpc_gsns.go#L647-L651

Which expands to:

https://github.com/TheThingsNetwork/lorawan-stack/blob/36a71355ed0f8f53c59b83d03684098245788982/pkg/networkserver/utils.go#L37-L48

Notice that the enabled status of the channel is not checked - this is intentional, as a last resort measure for the end device is to re-enable all of the channels in a fixed plan when it fails to receive any traffic from the Network Server, even if the Network Server has disabled some channels.


If the data rates are not relevant, I would like to understand what your real problem is when you leave the two standard channels as part of the uplink-channels section of the frequency plan - the current code, with no changes, should just mark them as enabled with min and max data rate index 6.

virtualguy commented 1 year ago

@adriansmares I see. I think the catch is we want use a custom data rate for those channel, i.e. #6527

adriansmares commented 1 year ago

In that case the two proposed changes in https://github.com/TheThingsNetwork/lorawan-stack/issues/6526#issuecomment-1715115005 should suffice - please let me know if that is not the case.

virtualguy commented 1 year ago

sounds good, i presume this isnt of any use to other TTS users so we can close this issue. Hopefully this kind of flexibility comes in future LoRaWAN specifications :pray: