Previously, we weren't filling in RX1 frequecny in rx_window1_config
structure. However, everything worked as in LoRaPHY::rx_config() API
there was a check which filled in correct RX1 frequency.
Now we are filling in RX1 freq. properly while we are computing
parameters for RX1 window.
LinkADRReq mac command can be used by the network server to set a
certain level of QOS using NbTrans field which is applicable to
Unconfirmed traffic only for 1.0.2 spec.
This commit introduces mechanisms to facilitate this QOS. It means to
repeat an outgoing unconfirmed message NbTrans times without changing
its frame counter.
For class C, we have retired the ack_expiry_timer_for_class_c and have
replaced it with another timer which mimics the RX2 closure as in Class
A but doesn't actually close RX2 window. It's just a mechanism by which
the state machine is informed that the you can proceed forward, we have
not received anything in RX2 window either. This is needed as RX2
doesn't timeout in class C (i.e., the radio remains in continuous mode).
In addition to that we need to close any pending timers for Receive
windows after the MIC has passed and the Duplicate counter check has
also been passed.
- Duty cycle can be now only disabled with duty-cycle-on flag if region supports duty-cycle.
If region does not support duty-cycle, this flag has no effect and duty cycle is always
disabled.
- Also introduced a new flag (duty-cycle-on-join) to disable duty cycle for JOIN requests.
This flag can be used for testing only and is used to speed up JOIN request testing as
backoff times for JOIN request are really long (easily several minutes per attempt).
This flag works in conjunction with main duty cycle setting. Disabling duty-cycle-on-join
works only if duty-cycle-on is disabled (or region settings have duty cycle disabled).
In #b0b0261 we changed the RX2 data rate to start from the highest data rate
available for the PHY rather than standard defined DR.
This introduced a regression, i.e., even when somebody changed the default RX2 data
rate to something usable for their environment, it didn't take any effect. As in
reset_mac_params() we override the data rate with max value possible for that PHY.
This commit restores the original behaviour and we always use standard defined
values.
We had a bug especially in the reception path. Our recv window opening
delays were being calculated on the premise that the radio has to capture
5 preamble symbols out of 8 transmitted by the base station. However, in PHY
layer while setting radio rc settings, we were setting preamble length to be 8.
Preamble length register needs to be configured differently for Uplink and Downlink.
For uplink, we wish to transmit 8 preamble symbols whereas in the reception path we need
to receive 5 preamble symbols at least out of 8.
Alongwith that the maximum range of timing error may vary from platform to platform as it
is based upon the crystal in the chip. We have now made these parameters configurable and
have loaded them with the most optimal defaults.
The stack was trying to connect with default data rates which happened to be
the lowest data rates in a specific region. In the beginning device and NS do
not have agreed upon tx rx parameters and there can be synchronization issues.
When we use lower datarates, we may end up having a minute and a half long
transmissions that hnot only blocks the channel for a long time but also reduce
the chance of proper synch between device and NS. That's why we have decided to
begin with higher data rates and gradually decrease datarate if we do not hear
from the network server.
Instead of giving LoRaWANTimeHandler object as parameter for constructor,
object is now given via own initialize() method.
This change is needed for future refactoring where application can give own
PHY object for LoRa stack.
In rx_config(params) API we shouldn't check for radio state as radio may never get
idle for a class C device. That check made sense only for class A. As the PHY layer
have no conecpt of receive windows which is a MAC layer construct, we should remove the
state check.
The API will be changed later to void rx_config(params).
In addition to that another bug is fixed in the open_rx2_windows() API. We should set the rx slot
first before instantiating a test based on its value.
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().
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.
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.
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
- get_phy_params function was very heavy weight and needed to be refactored.
- switch-case clauses have been refactored to be functions now and the complexity of the usage has been improved a lot.
- There are no functional changes, this is internal only change
Datarate verification passed only if given datarate was a minimum
possible value. Instead datarate should be checked that it is less
than maximum value.
LoRaMacChannelPlan class provides APIs which are not usable for
PHY layer implementations who do not support custom channel plans.
So we had some code in APIs which was explicitely using magic numbers
for the channel mask. Although it turned out to be not a bug as a layer
down we were checking for custom channel support. However, we now
check for custom channel support before going deep into PHY layer that will
make the code run faster and we have done some cosmetics to the code for
readability.
Channel mask is manipulated with inline methods
The PHY layer had a lot of duplicated code in various geographic regions.
In this commit we have tried to concentrate all common functionaliy into
one single class which LoRaPHY that provides three kind of methods:
i) Non virtual base methods which are there for upper layer use, e.g.,
providing access to driver or generic PHY layer functionality which
needs to be exposed to upper layers.
ii) Virtual methods (no hard limit on implementation) that can be overriden
in derived classes. Some PHY implementations will need that as they may
come with very peculiar channel schemes, e.g., dynamic channel schemes
in US bands.
iii) Protected methods which are only available for the derived PHYs
We have adopted a mechanism for the dervied PHYs to announce their differenmtiating
parameters in their constructors by filling up a data structure known as lora_phy_params_t
which exists at base level. Access modifier for this data structure is protected so it can only be
used by the base or derived classes, i.e., no exposure to upper layers.
For extra functionality and differentiating controls, a derived PHY can override any virual method as necessary.
In addition to that we have adopted the Mbed-OS style guide and have changed data structures and code to reflect that.
Some data structures are removed.
* Algorithm to get alternate DR is modified. Current scheme, works as multiples of 6 as EU and EU like PHYs
provide 6 datarates. We make sure that we try a datarate at least once. If nuber of join retries is a multiple
of 6, we may try multiple times on each data rate.
* Most of the PHYs with dynamic channel plans, always override the above mentioned algorithm as the rules governing
this algorithm do not hild in their case.
* band_t data structure is enhanced with lower band frequency and higher band frequency. That enables us to validate
frequency based upon the band and hence we can have a single function for all PHYs to validate frequency.
* In some PHYs, there were some extra channel masks were defined which were not being used. Hence removed.
* EIRP table corrected in some PHYs based upon spec.
* PHY functions in response to Mac commands are renamed to reflect what they exactly do.
for example accept_rx_param_setup_req() because that's what they do. they can either accept
the mac command or reject it.# Please enter the commit message for your changes.
Baseline is changed to use a single set of data structures that simplifies the
code in the LoRaWANStack and Mac layer. We are now following certian rules for naming
data structures.
- All structures visible outside their domain are prefixed as 'lorawan_'
- All mac structures are prefixed as 'loramac_'
- All subsystem or module strucutures carry their name in prefix, like 'mcps_'
PHY layer still have legacy camel case data structures which will be entertained
later while we will be simplifying PHY layer.
Test cases are also updated with the new data structure naming conventions.
One major difference from the previous baseline is the removal of static buffer
from mcps indication. And we do not copy data from stack buffer to rx_msg buffer.
This saves at least 512 bytes.
It may look like now that if we have received something but the user have not read
from the buffer, then the buffer will be overwritten and we will lose previous frame.
Yes, we will. But the same will happen even if we would have copied the buffer into rx_msg
because then the rx_msg gets overwritten. So we decide to abandon copying the buffer at
multiple locations. We inform the user about reception, if the user doesn't read and
the data gets overwritten, then so be it.
LoRaWANTimer is now called as LoRaWANTimeHandler class as this class handles both
current time and timer functionalities.
Some refactoring on how LoRa objects are created was needed:
- LoRaWANTimeHandler object is created by LoRaWANStack and shares with LoRaMac and PHY.
- LoRaPHY object is now member of LoRaWANStack class instead of static variable in source file.
MAC layer is now a class rather than being a blob.
In addition to that Mac commands are now being handled in
a seperate subsystem (a class of its own). In future we
will do the same with othe sublayers of MAC like MLME, MCPS etc.
The drive behind this exercise is to make MAC and supporting layers
into an object oriented system.
Major bug fixes include:
- last join time inclusion in band parameters
- disabling rx2 window if we missed the slot already
- MLME uplink schdule hook
- nbRep according to spec
- maintaining datarate after successful joining
- suppressing MLME requests if MAC is in TX_DELAYED state
- Uplink dwell time verification
Some missing features are implemented. Details are as follows.
Support for LinkCheckRequet:
An application API is added, add_link_check_request() to delegate a
request for Link Check Request MAC command.
* Application provides a callback function that needs to be called on reception of
link check response.
* Mac command is piggybacked with data frames.
This API makes the sticky MAC command stick with the application payloads until/unless
the application un-sticks the said mac command using remove_link_check_request() API.
Handling fPending bit:
If in the Downlink, we get the fPending bit set in fctrl octet,
we attempt to send an empty message back to Network Server to
open additional Receive windows. This operation is independent
of the application. An RX_DONE event is queued bedore generating
the said empty message. Specification does not mention what can be the
type of that empty message. We have decided it to be of CONFIRMED
type as it gives us an added benefit of retries if the corresponding
RX slots are missed.
Radio event callbacks as Mbed callbacks:
radio_events_t structure has been carrying C-style callbacks which was
inherited from the legacy code. These callbacks has now been changed to
Mbed Callbacks that makes sure that we can be object oriented from now
on.
LoRaPHY is the abstract class for the LoRa PHY layer which governs
the LoRaRadio and provides some common functionality to all regional
implementations.
We support 10 regions and every region comes loaded with default parameters.
These parameters can be changed by the Mac layer or explicitely by the stack
controller layer using APIs provided. This layer in essence detaches Mac completely
from PHY and provides more modular approach to the entire system.
Apart from class structure, the internal functionality is directly deduced from
semtech reference implementation that's why most of the internal data structures are
used on 'as is' basis.
In addition to that, the PHY layer provides APIs to control the LoRaRadio layer, i.e.,
the lora radio driver, ensuring that the radio is accessed from a single entry point.
A seperate data structure file is added which is common to PHY layers only.