This commit fixes the issue reported in #7285.
If the radio is unable to transmit, its a fatal error and can happen
both while joining or sending a normal packet. In the case of such
a catastrophy we ought to tell the application that this happened.
A fix for the radio driver will also be patched.
receive(uint32_t) API in the LoRaRadio class (base class for the radio drivers) should
not take any argument as we decided to take hardware timers for RX timeout interrupts
instead of software timers. It is being refactored to receive(void).
This is an API change, but as it is not an application interface, we will not put a
deprecation notice. Only user of this API is our stack (LoRaPHY layer) which has been updated
accordingly.
Actual driver comes out of the tree and a PR is open there to update the drivers:
https://github.com/ARMmbed/mbed-semtech-lora-rf-drivers/pull/22
In addition to this an internal API belonging to LoRaPHY class is refactored.
set_rx_window(parameters) is refactored to handle_receive(void) which is more consistent with
handle_send().
If the automatic uplink is sent directly the call-stack becomes larger than 1K
which may cause serious problems in debug builds. Just to have a respite between
RX and TX we queue an event for the automatic uplink rather than directly undergoing
an automatic uplink.
RX1 and 2 delays needed to be more precise and aggregate tx time was
drifiting because of timing difference between actual tx interrupt and
our processing of that interrupt ever so slightly.
We now take a timestamp of the tx interrupt and take a time diff while
instantiating delay timers. The timestamp is then used to update the aggregate
tx time.
Two new methods are introduced in the LoRaMac class which provide current
timing and current receive slot. These functions are used by LoRaWANStack
for its processing.
If the value is an integer, the 4th bit is used for sign, so you can store
values upto 7 only whereas the datarate values could go upto 15. That's why
we need to turn this to an unsigned integer so that the last bit can also be used.
Travis astyle check pointed out some of the style mismatches in the code.
Not all of them are worth changing as they make the code unreadable and
some of them are semantically wrong.
So in this commit, we have attempted to pick the most important style
mismatches and rectify.
General stability improvements are performed.
A flag is added if a Class C RX2 window is open.
We shouldn't open it again if its already opened.
TX_CRYPTO_ERROR is renamed to CRYPTO_ERROR.
Keeping TX_CRYPTO_ERROR for backwards compatibility.
In Class C, rx timeout does not take place for RX2 windows, so if we have
not received anything, we would be retrying but if the no. of retries are
maxed out, and we have not recieved anything yet, we need a mechanism to
tell the upper layer that this has happened.
rx_abort() was sort of dead code as it was doing essentially nothing.
It might have actually meddled with the state machine if it was hit by
invoking on_ack_timeout_timer_event().
State machine and corresponding processors now take care of the ack timeout,
retries and all other bits, so we don't need abort_rx().
MCPS confirmation should be filled with the current number of retries
if the ack is not recieved for a CONFIRMED message.
Ack retry number needs to be incremented after the retry is made not before
that.
A few traces are added at the crucial junctions of the code just to tally with
the conceptual flow for debug purposes.
Application can use cancel_sending() API to stop any outstanding, outgoing
transmission (a TX which is not already queued for transmission). This can
potentially enable use cases where the application could cancel a transmission
and go to sleep if the backoff period is long enough rather than waiting for
the transmission to happen.
This API enables the application to get hold of remaining time after which
the transmission will take place. User can query the backoff time whenever
there is a packet in the TX pipe. If the event for the backoff expiry is
already queued, the stack does not provide backoff metadata.
An API is added to fetch any meta-data available after a succesful
transmission. The stack will make the meta data available after the
TX interrupt is processed. User can get the tx meta data after receiving
TX_DONE event.
In the reception data path, we needed to check the MCPS CONFIRMATION type
not the MCPS INDICATION type. Indication message type is for downlink message type
which can be UNCONFIRMED even if we have sent a CONFIRMED one, e.g., an ACK.
Application can give battery_level callback method what Lora stack
uses to query battery level for DevStatusReq MAC command response.
The problem was that this callback was never called.
This commit fixes this problem and if application does not set
battery_level callback at all, value 255 (= The end-device was not able to
measure the battery level.) will be returned to lora gateway.
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.
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.
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 #6783.
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.
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.
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.
If Lora stack is built with incorrect mbedtls settings, crypto methods
should assert and return error value. This fixes MBED_ASSERTs to
work correctly.
band_t structure in phy parameters was not being filled in properly
and we were spilling over the array boundary for bands.
In addition to that two utility functions are added to perform safety
checking taking in the frequency and filling out band information plus
boundry value checks.
In LoRa TX power value 0 means the maximum allowed TX power and values >0
are limiting the allowed TX power to lower.
tx_config was incorrectly checking the power level and causing the maximum
TX power to be always used. Lora gateway can request node to use lower TX
power with LinkAdrReq MAC command.
In order to have smaller and better testable methods, instead of having a big
switch-case -style add_mac_command(), each MAC command is now separated to an
own method.
Currently lora stack will automatically send an empty uplink message to lora gateway in case of:
- Node received message with pending bit set.
- Node received MAC command which requires instant response (sticky MAC command)
- Node received confirmed message in class C mode
This commit makes this configurable via config item
"automatic-uplink-message": {
"help": "In case of pending bit, class c confirmed message or sticky MAC command, stack will automatically send empty uplink message",
"value": true
}
Default value is true. If sending an empty message fails, stack will send event AUTOMATIC_UPLINK_ERROR application.
If automatic uplink sending is disabled, stack will send application UPLINK_REQUIRED -event to indicate
application should issue a new uplink to gateway as soon as possible.
Any data structure used in LoRaWANBase class should be available
in a separate header in order to make the code easy to port and
easy to read as the developer doesn't need to know about all the
internal data structures being used in Mbed LoRaWAN stack.
Bug was reported by @tpet93 and it was correctly diagnosed that channels
were not being set in the phy_params structure. This commit fixes the bug
and sets up channels correctly.
This is a fix for issue #6389.
Currently when application receives RX_DONE event from stack, it has to provide the correct port
value to receive method in order to read the received message. The problem is that current
API does not provide any way to know in to which port message was received.
This commit introduces a new receive() method, which instead of checking these values, will return
them to application.
Fix compilation of compilance test and at the same time refactor compliance
test handler. Renamed mcps_request as test_request as it is only used for
compliance test. Also fixed a bug with null buffer in send_compliance_test_frame_to_mac.
- This is internal change, no functionality has been changed
- LoRaWanInterface cleaned up and code moved to LoRaMacStack
- Compliance code in LoRaMacStack moved to EOF
- Green tea tests have been run manually
- Doxygen updated accordingly
LoRA: reorder class members
This API can be used to runtime change device class.
Please note that only class A and C are supported at the moment.
Trying to set class B will return LORAWAN_STATUS_UNSUPPORTED.
Fix set_device_class documentation
fix documentation
1. Do not stop the 2nd window timer, as it is not running.
2. Wait for the OnAckTimeout event, before setting MacDone
3. Process for class c also the 2nd window timeout part, as we do
not have a 2nd window timer.
Removed the while loop checking the return value from set_next_channel
(GitHub Issue https://github.com/Lora-net/LoRaMac-node/issues/357)
The new return values are:
LORAWAN_STATUS_OK : A channel has been found.
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND : No free channel has been found (AS923 and KR920 regions)
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED : No channel found due to the duty-cycle or JoinReq back-off restrictions. Trial must be delayed.
LORAWAN_STATUS_NO_CHANNEL_FOUND : No channel has been found. Re-enabled the default channels.
- Internal changes only
- reset function is created to LoRaPHY to reset LoRaMAC parameters with default values
- Doxygen updates for newly created functions