Skip to content
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

LoRaWAN: Remedy for issue #7230 #7445

Merged
merged 3 commits into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions features/lorawan/LoRaWANBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ class LoRaWANBase {
* Connect by Over The Air Activation or Activation By Personalization.
* The connection type is selected at the setup.
*
* @return LORAWAN_STATUS_OK on success, a negative error code on
* failure.
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
* a 'CONNECTED' event. Otherwise a negative error code.
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
*
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned followed by
* a 'CONNECTED' event when the JoinAccept is received. Otherwise a negative error code
* is returned. Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no
* event follows.
*/
virtual lorawan_status_t connect() = 0;

Expand All @@ -53,8 +59,15 @@ class LoRaWANBase {
* You need to define the parameters in the main application.
*
* @param connect Options how end-device will connect to gateway
* @return LORAWAN_STATUS_OK on success, negative error code
* on failure
*
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
* a 'CONNECTED' event. Otherwise a negative error code.
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
*
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned followed by
* a 'CONNECTED' event when the JoinAccept is received. Otherwise a negative error code
* is returned. Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no
* event follows.
*/
virtual lorawan_status_t connect(const lorawan_connect_t &connect) = 0;

Expand Down
22 changes: 16 additions & 6 deletions features/lorawan/LoRaWANInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class LoRaWANInterface: public LoRaWANBase {
* all user-configured channels except the Join/Default channels. A CF-List can
* configure a maximum of five channels other than the default channels.
*
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
* By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions
* on these channels are severe and you may experience long delays or even failures in the confirmed traffic.
Expand All @@ -80,8 +79,14 @@ class LoRaWANInterface: public LoRaWANBase {
* is important, at least for ABP. That's why we try to restore frame counters from
* session information after a disconnection.
*
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS
* on success, or a negative error code on failure.
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
* a 'CONNECTED' event. Otherwise a negative error code.
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
*
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned followed by
* a 'CONNECTED' event when the JoinAccept is received. Otherwise a negative error code
* is returned. Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no
* event follows.
*/
virtual lorawan_status_t connect();

Expand All @@ -97,7 +102,6 @@ class LoRaWANInterface: public LoRaWANBase {
* all user-configured channels except the Join/Default channels. A CF-List can
* configure a maximum of five channels other than the default channels.
*
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
* By default, the PHY layers configure only the mandatory Join
* channels. The retransmission back-off restrictions on these channels
Expand All @@ -120,8 +124,14 @@ class LoRaWANInterface: public LoRaWANBase {
*
* @param connect Options for an end device connection to the gateway.
*
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
* a negative error code on failure.
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
* a 'CONNECTED' event. Otherwise a negative error code.
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
*
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned followed by
* a 'CONNECTED' event when the JoinAccept is received. Otherwise a negative error code
* is returned. Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no
* event follows.
*/
virtual lorawan_status_t connect(const lorawan_connect_t &connect);

Expand Down
10 changes: 9 additions & 1 deletion features/lorawan/LoRaWANStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ lorawan_status_t LoRaWANStack::connect()
return LORAWAN_STATUS_NOT_INITIALIZED;
}

if (_loramac.nwk_joined()) {
return LORAWAN_STATUS_ALREADY_CONNECTED;
}

lorawan_status_t status = _loramac.prepare_join(NULL, MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);

if (LORAWAN_STATUS_OK != status) {
Expand All @@ -170,6 +174,10 @@ lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
return LORAWAN_STATUS_NOT_INITIALIZED;
}

if (_loramac.nwk_joined()) {
return LORAWAN_STATUS_ALREADY_CONNECTED;
}

if (!(connect.connect_type == LORAWAN_CONNECTION_OTAA)
&& !(connect.connect_type == LORAWAN_CONNECTION_ABP)) {
return LORAWAN_STATUS_PARAMETER_INVALID;
Expand Down Expand Up @@ -1170,7 +1178,7 @@ void LoRaWANStack::process_connecting_state(lorawan_status_t &op_status)

if (_ctrl_flags & CONNECTED_FLAG) {
tr_debug("Already connected");
op_status = LORAWAN_STATUS_OK;
op_status = LORAWAN_STATUS_ALREADY_CONNECTED;
return;
}

Expand Down
81 changes: 16 additions & 65 deletions features/lorawan/LoRaWANStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,78 +84,29 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {

/** Connect OTAA or ABP using Mbed-OS config system
*
* Connect by Over The Air Activation or Activation By Personalization.
* You need to configure the connection properly via the Mbed OS configuration
* system.
*
* When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
* However, this is not a real error. It tells you that the connection is in progress and you will
* be notified of the completion via an event. By default, after the Join Accept message
* is received, base stations may provide the node with a CF-List that replaces
* all user-configured channels except the Join/Default channels. A CF-List can
* configure a maximum of five channels other than the default channels.
*
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
* By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions
* on these channels are severe and you may experience long delays or even failures in the confirmed traffic.
* If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only.
*
* **NOTES ON RECONNECTION:**
* Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
* memory storage. Therefore, the state and frame counters cannot be restored after
* a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
* protocol, the state and frame counters are saved. Connecting again would try to
* restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
* to zero for OTAA and a new Join request lets the network server know
* that the counters need a reset. The same is said about the ABP but there
* is no way to convey this information to the network server. For a network
* server, an ABP device is always connected. That's why storing the frame counters
* is important, at least for ABP. That's why we try to restore frame counters from
* session information after a disconnection.
*
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS
* on success, or a negative error code on failure.
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
* a 'CONNECTED' event. Otherwise a negative error code.
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
*
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned followed by
* a 'CONNECTED' event when the JoinAccept is received. Otherwise a negative error code
* is returned. Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no
* event follows.
*/
lorawan_status_t connect();

/** Connect OTAA or ABP with parameters
*
* All connection parameters are chosen by the user and provided in the
* data structure passed down.
*
* When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
* However, this is not a real error. It tells you that connection is in progress and you will
* be notified of completion via an event. By default, after Join Accept message
* is received, base stations may provide the node with a CF-List which replaces
* all user-configured channels except the Join/Default channels. A CF-List can
* configure a maximum of five channels other than the default channels.
*
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
* By default, the PHY layers configure only the mandatory Join
* channels. The retransmission back-off restrictions on these channels
* are severe and you may experience long delays or even
* failures in the confirmed traffic. If you add more channels, the aggregated duty
* cycle becomes much more relaxed as compared to the Join (default) channels only.
*
* **NOTES ON RECONNECTION:**
* Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
* memory storage. Therefore, the state and frame counters cannot be restored after
* a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
* protocol, the state and frame counters are saved. Connecting again would try to
* restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
* to zero for OTAA and a new Join request lets the network server know
* that the counters need a reset. The same is said about the ABP but there
* is no way to convey this information to the network server. For a network
* server, an ABP device is always connected. That's why storing the frame counters
* is important, at least for ABP. That's why we try to restore frame counters from
* session information after a disconnection.
*
* @param connect Options for an end device connection to the gateway.
*
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
* a negative error code on failure.
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
* a 'CONNECTED' event. Otherwise a negative error code.
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
*
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned followed by
* a 'CONNECTED' event when the JoinAccept is received. Otherwise a negative error code
* is returned. Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no
* event follows.
*/
lorawan_status_t connect(const lorawan_connect_t &connect);

Expand Down
6 changes: 4 additions & 2 deletions features/lorawan/lorastack/mac/LoRaMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,9 +814,11 @@ lorawan_status_t LoRaMac::send_join_request()
status = prepare_frame(&mac_hdr, &fctrl, 0, NULL, 0);

if (status == LORAWAN_STATUS_OK) {
status = schedule_tx();
if (schedule_tx() == LORAWAN_STATUS_OK) {
status = LORAWAN_STATUS_CONNECT_IN_PROGRESS;
}
} else {
tr_error("Retransmission: error %d", status);
tr_error("Couldn't send a JoinRequest: error %d", status);
}

return status;
Expand Down
9 changes: 5 additions & 4 deletions features/lorawan/lorawan_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ typedef enum lorawan_status {
#if defined(LORAWAN_COMPLIANCE_TEST)
LORAWAN_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */
#endif
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020,
LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021,
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022,
LORAWAN_STATUS_METADATA_NOT_AVAILABLE = -1023
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020, /**< Transmission will continue after duty cycle backoff*/
LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021, /**< None of the channels is enabled at the moment*/
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022, /**< None of the enabled channels is ready for another TX (duty cycle limited)*/
LORAWAN_STATUS_METADATA_NOT_AVAILABLE = -1023, /**< Meta-data after an RX or TX is stale*/
LORAWAN_STATUS_ALREADY_CONNECTED = -1024 /**< The device has already joined a network*/
} lorawan_status_t;

/** The lorawan_connect_otaa structure.
Expand Down