Commit Graph

48 Commits (0da589e6e725c3757c6b3ecbf973732e48879ceb)

Author SHA1 Message Date
Kevin Bracey 87396e0bf6 Assembler atomics
Reimplement atomic code in inline assembly. This can improve
optimisation, and avoids potential architectural problems with using
LDREX/STREX intrinsics.

API further extended:
* Bitwise operations (fetch_and/fetch_or/fetch_xor)
* fetch_add and fetch_sub (like incr/decr, but returning old value -
  aligning with C++11)
* compare_exchange_weak
* Explicit memory order specification
* Basic freestanding template overloads for C++

This gives our existing C implementation essentially all the functionality
needed by C++11.

An actual Atomic<T> template based upon these C functions could follow.
2019-04-26 13:12:35 +03:00
Martin Kojtal d030c04a60
Merge pull request #9219 from hasnainvirk/lorawanbase_migration
LoRaWAN: Retiring LoRaWANBase class
2019-02-21 13:55:11 +01:00
Kevin Bracey 6f757a5824 LoRAWAN: volatile bool -> atomic_flag
Now we have a proper atomic flag API, use it rather than a volatile
cheat.
2019-01-14 11:59:25 +02:00
Hasnain Virk 5fb383c27a Doxygen corrections
Adding group identidier so that LoRaWANInterface class goes to the class
hierarchy section rather than data-structures.

Adding missing documentation for a couple of public functions.

Adding \code and \endcode modifiers for the example code in the
documentation.

Adding compile time NO_DOXYGEN flag for the implementations of the
LoRaPHY Class.

Adding documentation for some of the private structures.
2019-01-10 16:14:19 +02:00
Hasnain Virk d5ce0cc96f Adding QOS handling and fixing bugs for Class C
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.
2018-10-16 12:23:21 +03:00
Cruz Monrreal II dd8e9bb954 Revert "Merge pull request #8183 from hasnainvirk/QOS_impl"
This reverts commit 5c675d3688, reversing
changes made to 2b04a02eb2.
2018-10-11 16:51:46 -05:00
Hasnain Virk 94eb4c0bc0 Adding QOS handling and fixing bugs for Class C
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.
2018-09-21 15:55:30 +03:00
Hasnain Virk e110856941 LoRaWAN: Refactoring compliance test code
While performing compliance tests with an industry tester, we realized
that there was no need for any extra handling code for the compliance
tests. The tests would run fine, if we only have a handling application.
However, in normal operation we wouldn't like the network to send us any
traffic on compliance testing port. To mitigate that, on the reception
path we filter out any traffic on compliance testing port if compliance
testing is not underway. User should define LORAWAN_COMPLIANCE_TEST macro
in mbed_app.json to enable traffic on compliance test port.
2018-09-11 11:26:31 +03:00
Hasnain Virk b07c3e791f Reporting scheduling failures
It is quite possible that the user request for scheduling an uplink is deferred because of backoff or if it was a CONFIRMED message, a retry may take place on a different datarate and different channel.
We didn't have a hook for such deferred scheduling, telling the user whether the async rescheduling worked or not. This commit adds that capability and now we can tell the application if a scheduling failure took place after the original schedule request was accepted.
2018-08-01 16:28:00 +03:00
Cruz Monrreal c5ba97fbe0
Merge pull request #7445 from hasnainvirk/issue_7230
LoRaWAN: Remedy for issue #7230
2018-07-13 11:48:13 -05:00
Hasnain Virk f0844b4cfc Streamlining connect() API with posix like retcodes
For ABP: First call to connect() or connect(params) will return LORAWAN_STATUS_OK
         and a CONNECTED event will be sent. Any subsequent call will return
         LORAWAN_STATUS_ALREADY_CONNECTED (posix EISCONN) and no event is generated.

FOR OTAA: First call to connect() or connect(params) will return LORAWAN_STATUS_CONNECT_IN_PROGRESS
          and a CONNECTED event will be sent whenever the JoinAccept is received. If the application
          calls connect again before receiving the CONNECTED event, LORAWAN_STATUS_BUSY will be returned.
          After the CONNECTED event is dispatched, any subsequent call to connect() or connect(params) API
          will be returned with LORWAN_STATUS_ALREADY_CONNECTED.

No new parameters are accepted after the first call. The application must disconnect before making
a connect() call with new parameters.
2018-07-10 13:31:50 +03:00
Hasnain Virk 24db1c81ec Updating docs
API documentation is updated to clear how the connection related return codes will
work from now on.
2018-07-09 13:00:01 +03:00
Kimmo Vaisanen 0397b0b292 Lora: Support user provided LoRaPHY object
To support custom PHY object, a new LoRaWANInterface constructor was
added.
2018-07-06 15:11:10 +03:00
Hasnain Virk 828815c7e3 Adding precise timing for receive delays
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.
2018-06-12 12:32:13 +03:00
Hasnain Virk 9ac7f21140 Style changes only
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.
2018-06-01 12:41:09 +03:00
Hasnain Virk 3020d658bf Travis astyle corrections
The scope of style corrections is local to this PR only.
2018-05-24 15:54:32 +03:00
Hasnain Virk 2bc8e4e847 Adding ack expiry handling for class C
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.
2018-05-24 15:54:32 +03:00
Hasnain Virk 26b28f78af Adding ability to cancel outgoing transmission
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.
2018-05-24 15:54:32 +03:00
Hasnain Virk 8363311c7a Adding acquisition of backoff time value
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.
2018-05-24 15:54:32 +03:00
Hasnain Virk 387f56c738 Adding acquisition of RX meta data
User can now inquire about any RX meta data available after a
successful reception.
2018-05-24 15:54:32 +03:00
Hasnain Virk 555d945a42 Adding acquisition of TX Meta-data
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.
2018-05-24 15:54:32 +03:00
Hasnain Virk 9f36baab1b State Machine rework
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.
2018-05-08 16:45:18 +03:00
Hasnain Virk a75af9799e Adding thread safety
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.
2018-05-08 16:24:34 +03:00
Kimmo Vaisanen 2b2ce300ea Lora: Remove singleton construction of LoRaWANStack
After changing LoRaMacCrypto as C++ class, we no longer have static variables
in LoRa implementation. Therefore singleton pattern can be removed.
2018-04-20 16:01:55 +03:00
Kimmo Vaisanen d336ceeee8 Lora: Make automatic uplink message configurable
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.
2018-04-18 09:29:20 +03:00
Cruz Monrreal 94103f9306
Merge pull request #6586 from kivaisan/new_receive_method
Lora: Introduce new receive API which returns port and flags
2018-04-12 18:32:12 -05:00
Antti Kauppila 67157fc3bd LoRa: Internal include paths corrected 2018-04-10 14:04:18 +03:00
Kimmo Vaisanen 19883f12f8 Lora: Introduce new receive API which returns port and flags
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.
2018-04-10 13:04:23 +03:00
Antti Kauppila db167af3c1 LoRa: Fixed doxygen error, enabled commented out code 2018-04-09 11:48:03 +03:00
Antti Kauppila fa062fff76 LoRa: Moved connect logic from LoRaWANStack to LoRaMac class
- Internal change only
2018-04-09 11:10:40 +03:00
Kimmo Vaisanen c1983570b4 Fix compilance test compilation
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.
2018-03-21 14:39:18 +02:00
Antti Kauppila 6b54478af4 LoRaWANStack is made independent of MAC sublayers
- Only internal changes, no API has been broke.
- Tested by manually running Green tea tests
2018-03-21 08:54:42 +02:00
Antti Kauppila b63c98e103 LoRa: LoRaPHY dependency removed from LoRaMacStack
- 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
2018-03-21 08:54:42 +02:00
Kimmo Vaisanen a26fca8bf5 Add set_device_class API to change active device class
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
2018-03-21 08:54:42 +02:00
Antti Kauppila a294aa028d LoRa: LoRaWANInterface refactored.
- Only internal changes, no functionality changes
- Some minor improvements to LoRaWanStack
2018-03-21 08:54:42 +02:00
Antti Kauppila 32257858d0 Added missing mac_cmd_buf_idx_to_repeat to LoRaMacCommand class
- Reordered LoRaWANStack internal variables for more compact code
2018-03-16 18:00:02 +02:00
Antti Kauppila 488cf03d1e LoRA: Code cleanup + doxygen updates
- Internal changes only
- reset function is created to LoRaPHY to reset LoRaMAC parameters with default values
- Doxygen updates for newly created functions
2018-03-16 18:00:02 +02:00
Antti Kauppila 2ac73a6cac LoRa: LoRaMacMcps refactored to remove dependency to LoRaMac.
- This is internal logic only and there are no functionality changes
- Some compliance test stuff have been moved to end of files
- Some internal data structures removed as useless after refactor
2018-03-16 18:00:02 +02:00
Kimmo Vaisanen 5d98839092 Improve error handling & robustness
This commit also introduces API change for disconnect(). disconnect() will
now return LORAWAN_STATUS_DEVICE_OFF for successfull disconnect.

 * LoRaWANStack::handle_tx() can be called with NULL buffer when length is 0.
   This commit fixes the case where user has provided NULL buffer and length
   is > max_possible_size.

handle_tx() now always returns LORAWAN_STATUS_PARAMETER_INVALID if given
buffer is NULL pointer and length > 0.

General error checking is added and some asserts are added for events.
2018-02-11 00:31:47 +02:00
Hasnain Virk c02774343a [IOTCELL-282] Code cleanup/simplification and rules
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.
2018-02-11 00:31:47 +02:00
Kimmo Vaisanen e18d76aa7e Change LoRaWANTimer to a C++ class
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.
2018-02-11 00:31:47 +02:00
Hasnain Virk b634ca49dd Architecture rework, bug fixing & missing features
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.
2018-02-11 00:31:47 +02:00
Kimmo Vaisanen b0889f7d21 Move all compliance test code inside compilation flag
All compliance test related codes are now inside LORAWAN_COMPLIANCE_TEST
build flag. This will reduce memory usage in when compliance test codes
are not needed.
2018-02-09 11:00:56 -06:00
Hasnain Virk 97f1680586 [IOTCELL-270] Detaching TxNextPacketTimer
TxNextPacketTimer callback was being used for testing only (compliance testing to be precise).
Now there are independent methods and direct calls to automatic timers for the
compliance testing so there is no particular need for this timer anymore.
2018-02-09 11:00:56 -06:00
Hasnain Virk 05e2d29238 Reworking callback API
Application should be able to add some optional callbacks if it needs to.
Ofcourse there is a penalty of 8-12 bytes per callback, but there can be
certain needs of the application that needs to be met for example setting
up a link check request etc.

We have introduced a structure that contains callbacks for the application use.

 - 'events' callback is mandatory, user must assign it. Because this callback brings
   state changes for the application. We cannot segregate this into individual handlers
   because of RAM penalty.
- Other calbacks (none of them are implemented yet are optional).

Example of using the API is provided with doxygen
2018-02-09 11:00:56 -06:00
Hasnain Virk e60227cf4d Receive API typo fix
Receive API should return the length of data written to the user buffer
as the Posix APIs suggest rather than sending the pending length of data
back.
That has actually been a typo mistake which actually wnt in even with doicumentation :)
2018-02-09 11:00:56 -06:00
Hasnain Virk 6281073d8b [IOTCELL-279] Using Application provided EventQueue
The EventQueue thread in LoRaMac.cpp is disbanded and the LoRaWAN
protocol is redesigned to store a pointer for an application
provided EventQueue. It means that now the stack runs in the
same thread as application. Application provided EventQueue is used
to defer ISRs from radio driver and timer callbacks as well as the
application events are queued to the same event loop.
2018-02-09 11:00:56 -06:00
Hasnain Virk 2f860d2be5 Adding LoRaWANStack class to control MAC and PHY
LoRaWANStack class is our controller layer on top of our
current MAC and PHY layer. It provides services to an implementation
of LoRaWANBase class.

It is a singleton class owing to the fact that the mac layer underneath
is not a class object. Instead, it uses the MAC via setting mib, mlme, mcps
requests and getting responses back from the mac layer using confirmations and
indications.

In essense this class is a special handle for
mac layer underneath which is predominantly reference design based.
In future we may refactor the LoRaMac.cpp code to make it object oriented
and cleaner.

At one end, it binds the application selected radio driver with the PHY layer
and at the other end it provides services to upper layers handling the mac via
well defined APIs.

For proper selection of a PHY layer, user must use Mbed config system.
For this purpose an mbed_lib.json is provided which can be overriden by the
user defined mbed_app.json. By default the EU868 band is selected as a PHY layer.
User must set relevant keys for the selected connection mechanism.
2018-02-09 11:00:56 -06:00