LacunaSpace / basicmac

BasicMAC LoRaWAN stack that supports (but is not limited to) Arduino
Other
79 stars 18 forks source link

Simultaneous multi-band? #27

Open Bwooce opened 3 years ago

Bwooce commented 3 years ago

Hi team,

I'm starting to implement an AS923/AU915 TTN Mapper application using your stack. It's made me ask basic LoRaWAN questions, and I suspect you've already solved some of them.

Basically, is a device that's on two bands two devices? It looks like there's a tight binding in LoRaWAN between the frequency of the device and it's connection as the MAC commands allow the network to instruct the device where to go, but I'm not 100% sure. If it's true then I'm doubly-confused by the sharing of some counters in your stack e.g. framecounts which makes me think I'm wrong. It's possible that the Lacuna side makes this work and that's your secret sauce, but for TTN this won't be the case.

Do you have any guidance? I can abstract the LMIC portion further to make one entire stack per band, it's just more work than I was planning on :-)

/Bruce

matthijskooijman commented 3 years ago

AFAIU, BasicMac does allow selecting multiple frequency plans at compiletime and selecting one to use at runtime. I haven't tested this at all, though. And I think it cannot have two sessions active on both bands at the same time, though, if that's what you need? I heard @mkuyper say he had been working on a version of LMIC in the past that does not have singleton global state (passing pointers to state where needed), which could probably support this, but I don't think that was more than an experiment.

As for the Lacuna secret sauce: This repo contains just a straight up port of BasicMAC to Arduino, we haven't published any Lacuna/LoRa-E modifications (yet).

Bwooce commented 3 years ago

Thanks for your help @matthijskooijman

And I think it cannot have two sessions active on both bands at the same time, though, if that's what you need?

Yes ideally so I can send a packet to TTNMapper on two different bands every n seconds, but it's mental gymnastics to see if this is permissible by the standard as I don't think they ever considered it (I'll ask). I could re-init the stack and use ABP for each packet as an easy alternative although it's not very elegant. The LMIC version without global state would certainly be an option if it exists, although (thinking it through more) I probably want the radio side to be common state since it's the same radio after all. Not an easy path.

I think I can use it as it stands, I'm also planning to use it more generally to unify coverage in Australia/NZ/others where the LoRa bandplan is fractured e.g. OTAA on one band and if it fails try the other.

Bwooce commented 3 years ago

Okay, so I've got this working and some advice from the TTN forum folk, so I thought I should write up a small design proposal before slogging on any further into OTAA/a decent Pull Request. The TTN Mapper use case isn't normal with the need to be active on multiple bands, and I'm concerned you / @mkuyper might not want to go this far, as there is a complexity/memory cost. I did think could be useful if say you were a satellite company and wanted to quickly swap backwards and forwards between terrestrial and non-terrestrial but...I wouldn't know anyone like that.

So, requirements are that I need to store the stack state per band (as I'm intending to use multiple bands) and use different identities per band (since simultaneous use of the same device on different bands looks like it'll confuse the back-end).

I've implemented a static array of lmic_t[REGIONS_COUNT]'s and move LMIC to point the current band. The band-specific limic_t gets initialised only once, when used/reset_ex to, but the radio gets reset every switch. The switch should probably be guarded so it only happens at idle-time e.g. TX_COMPLETE. This worked well for ABP, as yet untested for OTAA but I can't see why it wouldn't. I was pleasantly surprised it was that easy, thanks for doing the hard work to separate the state.

To resolve the identities issue, especially for OTAA, I'd propose adding a bandIdx parameter to os_getJoin/DevEUI and os_getNwkKey() [all three?] and similarly turn both the ABP and OTAA key parameters into multi-dimensional arrays to store them.

Thoughts? Objections? This level of complexity (and memory usage) isn't required if you only one to use one band exclusively at a time, and that'd be a more normal use case e.g. trying two bands and seeing which one had coverage, then sticking to that one.

Also, of course, I've not run the internal tests across this approach. I'm not sure how the budha and simul stuff even works.

Bwooce commented 3 years ago

This is working now, I'll need to unpick it a bit to turn it into a series of commits. Do you want it here now, or as a delta on @mkuyper / basicmac?