-
Notifications
You must be signed in to change notification settings - Fork 3k
LoRa: State machine work #6808
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
LoRa: State machine work #6808
Conversation
@kjbracey-arm @AnttiKauppila @kivaisan @0xc0170 @cmonr Please review. |
e66ce12
to
745bc7a
Compare
LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler); | ||
LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler); | ||
LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler); | ||
LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add initialization of _tx_msg and _rx_payload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's really no need to be initialising buffers (or there shouldn't be). But anyway, don't forget you can initialise arrays with _rx_msg()
in the initialiser list. Don't have to use memset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in constructor.
@@ -125,851 +119,698 @@ LoRaMac::LoRaMac() | |||
|
|||
_params.sys_params.adr_on = false; | |||
_params.sys_params.max_duty_cycle = 0; | |||
|
|||
mac_primitives = NULL; | |||
ev_queue = NULL; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add initialization of _mcps_indication, _mcps_confirmation, _mlme_indication and _mlme_confirmation
LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler); | ||
LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler); | ||
LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler); | ||
LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's really no need to be initialising buffers (or there shouldn't be). But anyway, don't forget you can initialise arrays with _rx_msg()
in the initialiser list. Don't have to use memset.
LORAMAC_BUSY = 0x00000004, | ||
LORAMAC_CONNECTED = 0x00000008, | ||
LORAMAC_USE_OTAA = 0x00000010, | ||
LORAMAC_TX_DONE = 0x00000020, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mixing flags and enums is always a bit questionable, and here you don't seem to be using them as flags at all - no combinations? But I see you clearing bits and setting bits.
If this is supposed to actually be an enum of states, then probably a good idea to not make it look like a bitfield - get rid of the values, and stop doing bit manipulations on it.
Or if it is supposed to be bits, get rid of the enum, and actually use a bitfield, as you are always manipulating bits individually, and don't need any tricky masking operations.
Maybe it's a mixture of a state and some flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit field, members of the bitfield are identified as an enum. Actual storage is as a 32 bit unsigned bitfield.
device_states_t _device_current_state; | ||
lorawan_app_callbacks_t _callbacks; | ||
lorawan_session_t _lw_session; | ||
loramac_tx_message_t _tx_msg; | ||
loramac_rx_message_t _rx_msg; | ||
uint8_t _num_retry; | ||
uint32_t _ctrl_flags; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so this isn't the enum? Because the compiler's correctly stopping you doing the bit manipulations, I guess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flags are now made Macros for clarity.
features/lorawan/LoRaWANStack.cpp
Outdated
mlme_indication_handler(); | ||
} | ||
|
||
memset(_rx_payload, 0, sizeof _rx_payload); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the memset? memsets are one of the most expensive things you can do - you don't want this sort of thing in data paths. Although I guess this isn't very high throughput...
features/lorawan/LoRaWANStack.cpp
Outdated
uint8_t pos = 0; | ||
mac_hdr.value = payload[pos++]; | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not really grasping why all this MAC functionality is being moved out of the MAC. This totally stops the MAC actually being, well, a MAC. You've now got two "stack" and "MAC" classes which actually form the MAC between them, and I'm not immediately seeing where the dividing line is conceptually.
Maybe there is no clear line, but in that case the MAC class could be eliminated and just merge with this.
This is also less robust and clear than the original MAC code it's replacing - this lost the switch
and is letting through reserved packets as a result.
5105862
to
f36492a
Compare
@kjbracey-arm @kivaisan Please review again. |
@0xc0170 This needs CI, previous cliapp build failed for some reason. |
I reviewed the log, restarted it |
|
||
_lora_time.start(_params.timers.mac_state_check_timer, 1); | ||
default: | ||
tr_error("Unsupported data frame type"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given lack of address filtering, might this be too verbose? You'd print this for every packet you overhear from another node talking to the access point. Maybe it's okay for current testing, and non-class-C.
features/lorawan/LoRaWANStack.cpp
Outdated
#define IDLE_FLAG 0x00000000 | ||
#define TX_ONGOING_FLAG 0x00000001 | ||
#define MSG_RECVD_FLAG 0x00000002 | ||
#define BUSY_FLAG 0x00000004 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUSY_FLAG bit is only set and cleared but never checked so I thinki this should be removed.
Received data buffer from radio driver should be immutable.
We went through an exercise of adding band information to any new channel being added. Default channels were looked over. This commits duly adds missing band information to default channels.
Channel plan datastructure already contains channel parameters. Extraction is not needed.
Making our LoRaWAN stack thread safe. If RTOS is not present, locks don't do anything. ScopedLock is used to automate the lock release on context expiry.
b6ec2c5
to
c48782d
Compare
@kjbracey-arm Can you please review again ? |
There had been essentially two state machines running in our stack which was too cumbersome and was not alligned in any symmetry. In this work we make sure that: * There are no callbacks from the MAC layer to Stack controller layer. * Primitives are made local to the mac layer and are presented as read-only to the stack controller layer. * Interrupt handling and processing is moved to the stack controller layer. * Reception is divided into smaller units, seperating handling of Join Accept and normal data frames. MIC gets its own unit. * Extraction of data and MAC commands from the payload is also being done now in its own method. * To ensure integrity of the stack, and sanctity of the radio payload, we copy the radio payload buffer immediately in the rx interrupt and hoist a flag that prevents another interrupt from happening for a short while when we are processing the previous packet. * If an automatic uplink is on going, we do not send a TX_DONE event to application anymore as that is logically incorrect. * state_controller() is the central engine for the state machine. To save code space and memory, we are not handling each and every state in the state_controller(). Some of the states which have no processing to be done, are explicitely set. * For all the states who need special processing, seperate methods are added. * Class A always run to completion to IDLE and CLass C always runs to completion as RECEIVING.
The asia pacific region supports custom channel planning and downlink channel request. By virtue of a mistake, this information was missing and hence a custom channel support was not working. Fixes issue ARMmbed#6783.
Message flags are used in the application so the logical place for them is in lorawan_types.h and not in lorawan_data_structures.h
While configuring RX parameters for the radio, we need to feed in rx windows 1 and 2 parameters which are computed when we do the transmission. We are actually setting the physical value of the data rate rather than data rate table index and the expectation was to set the data rate index.
If the frame length is not what we are expecting, it is found to be a good practise to actually continue with what we have received rather than aborting. As we have already demodulated the packet and RX slots are used up, ther is not so much benefit in dropping that packet.
849e667
to
be04a57
Compare
/morph build |
Build : SUCCESSBuild number : 1946 Triggering tests/morph test |
Test : SUCCESSBuild number : 1767 |
Exporter Build : SUCCESSBuild number : 1598 |
@0xc0170 This is ready to be merged |
Description
Major contribution of this PR is to rework the state machine for our LoRaWAN stack.
State machine diagrams can be found here [for internal people].
https://armh.sharepoint.com/:f:/r/sites/IoT-Connectivity/Shared%20Documents/LoRa/Mbed%20LoRaWAN%20Stack%20State%20Diagrams/Proposal-NewStateMachine?csf=1&e=PnvvkJ
Other commits either fix a discrepancy or improve integrity of the stack.
Target -> Mbed-OS 5.9
Pull request type