Skip to content

Commit c5ba97f

Browse files
author
Cruz Monrreal
authored
Merge pull request #7445 from hasnainvirk/issue_7230
LoRaWAN: Remedy for issue #7230
2 parents 531ee3c + f0844b4 commit c5ba97f

File tree

6 files changed

+82
-93
lines changed

6 files changed

+82
-93
lines changed

features/lorawan/LoRaWANBase.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,14 @@ class LoRaWANBase {
4141
* Connect by Over The Air Activation or Activation By Personalization.
4242
* The connection type is selected at the setup.
4343
*
44-
* @return LORAWAN_STATUS_OK on success, a negative error code on
45-
* failure.
44+
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
45+
* a 'CONNECTED' event. Otherwise a negative error code is returned.
46+
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
47+
*
48+
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
49+
* Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
50+
* is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
51+
* A 'CONNECTED' event is sent to the application when the JoinAccept is received.
4652
*/
4753
virtual lorawan_status_t connect() = 0;
4854

@@ -53,8 +59,15 @@ class LoRaWANBase {
5359
* You need to define the parameters in the main application.
5460
*
5561
* @param connect Options how end-device will connect to gateway
56-
* @return LORAWAN_STATUS_OK on success, negative error code
57-
* on failure
62+
*
63+
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
64+
* a 'CONNECTED' event. Otherwise a negative error code is returned.
65+
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
66+
*
67+
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
68+
* Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
69+
* is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
70+
* A 'CONNECTED' event is sent to the application when the JoinAccept is received.
5871
*/
5972
virtual lorawan_status_t connect(const lorawan_connect_t &connect) = 0;
6073

features/lorawan/LoRaWANInterface.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class LoRaWANInterface: public LoRaWANBase {
7373
* all user-configured channels except the Join/Default channels. A CF-List can
7474
* configure a maximum of five channels other than the default channels.
7575
*
76-
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
7776
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
7877
* By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions
7978
* on these channels are severe and you may experience long delays or even failures in the confirmed traffic.
@@ -92,8 +91,14 @@ class LoRaWANInterface: public LoRaWANBase {
9291
* is important, at least for ABP. That's why we try to restore frame counters from
9392
* session information after a disconnection.
9493
*
95-
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS
96-
* on success, or a negative error code on failure.
94+
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
95+
* a 'CONNECTED' event. Otherwise a negative error code is returned.
96+
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
97+
*
98+
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
99+
* Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
100+
* is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
101+
* A 'CONNECTED' event is sent to the application when the JoinAccept is received.
97102
*/
98103
virtual lorawan_status_t connect();
99104

@@ -109,7 +114,6 @@ class LoRaWANInterface: public LoRaWANBase {
109114
* all user-configured channels except the Join/Default channels. A CF-List can
110115
* configure a maximum of five channels other than the default channels.
111116
*
112-
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
113117
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
114118
* By default, the PHY layers configure only the mandatory Join
115119
* channels. The retransmission back-off restrictions on these channels
@@ -132,8 +136,14 @@ class LoRaWANInterface: public LoRaWANBase {
132136
*
133137
* @param connect Options for an end device connection to the gateway.
134138
*
135-
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
136-
* a negative error code on failure.
139+
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
140+
* a 'CONNECTED' event. Otherwise a negative error code is returned.
141+
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
142+
*
143+
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
144+
* Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
145+
* is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
146+
* A 'CONNECTED' event is sent to the application when the JoinAccept is received.
137147
*/
138148
virtual lorawan_status_t connect(const lorawan_connect_t &connect);
139149

features/lorawan/LoRaWANStack.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ SPDX-License-Identifier: BSD-3-Clause
4444
#define CONNECTED_FLAG 0x00000004
4545
#define USING_OTAA_FLAG 0x00000008
4646
#define TX_DONE_FLAG 0x00000010
47+
#define CONN_IN_PROGRESS_FLAG 0x00000020
4748

4849
using namespace mbed;
4950
using namespace events;
@@ -156,6 +157,14 @@ lorawan_status_t LoRaWANStack::connect()
156157
return LORAWAN_STATUS_NOT_INITIALIZED;
157158
}
158159

160+
if (_ctrl_flags & CONN_IN_PROGRESS_FLAG) {
161+
return LORAWAN_STATUS_BUSY;
162+
}
163+
164+
if (_ctrl_flags & CONNECTED_FLAG) {
165+
return LORAWAN_STATUS_ALREADY_CONNECTED;
166+
}
167+
159168
lorawan_status_t status = _loramac.prepare_join(NULL, MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);
160169

161170
if (LORAWAN_STATUS_OK != status) {
@@ -171,6 +180,14 @@ lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
171180
return LORAWAN_STATUS_NOT_INITIALIZED;
172181
}
173182

183+
if (_ctrl_flags & CONN_IN_PROGRESS_FLAG) {
184+
return LORAWAN_STATUS_BUSY;
185+
}
186+
187+
if (_ctrl_flags & CONNECTED_FLAG) {
188+
return LORAWAN_STATUS_ALREADY_CONNECTED;
189+
}
190+
174191
if (!(connect.connect_type == LORAWAN_CONNECTION_OTAA)
175192
&& !(connect.connect_type == LORAWAN_CONNECTION_ABP)) {
176193
return LORAWAN_STATUS_PARAMETER_INVALID;
@@ -825,6 +842,8 @@ int LoRaWANStack::convert_to_msg_flag(const mcps_type_t type)
825842

826843
lorawan_status_t LoRaWANStack::handle_connect(bool is_otaa)
827844
{
845+
_ctrl_flags |= CONN_IN_PROGRESS_FLAG;
846+
828847
if (is_otaa) {
829848
tr_debug("Initiating OTAA");
830849

@@ -1150,30 +1169,23 @@ void LoRaWANStack::process_joining_state(lorawan_status_t &op_status)
11501169

11511170
void LoRaWANStack::process_connected_state()
11521171
{
1172+
_ctrl_flags |= CONNECTED_FLAG;
1173+
_ctrl_flags &= ~CONN_IN_PROGRESS_FLAG;
1174+
11531175
if (_ctrl_flags & USING_OTAA_FLAG) {
11541176
tr_debug("OTAA Connection OK!");
11551177
}
11561178

11571179
_lw_session.active = true;
11581180
send_event_to_application(CONNECTED);
1159-
_ctrl_flags |= CONNECTED_FLAG;
11601181

11611182
_device_current_state = DEVICE_STATE_IDLE;
11621183
}
11631184

11641185
void LoRaWANStack::process_connecting_state(lorawan_status_t &op_status)
11651186
{
1166-
if (_device_current_state != DEVICE_STATE_IDLE
1167-
&& _device_current_state != DEVICE_STATE_SHUTDOWN) {
1168-
op_status = LORAWAN_STATUS_BUSY;
1169-
return;
1170-
}
1171-
1172-
if (_ctrl_flags & CONNECTED_FLAG) {
1173-
tr_debug("Already connected");
1174-
op_status = LORAWAN_STATUS_OK;
1175-
return;
1176-
}
1187+
MBED_ASSERT(_device_current_state == DEVICE_STATE_IDLE ||
1188+
_device_current_state == DEVICE_STATE_SHUTDOWN);
11771189

11781190
_device_current_state = DEVICE_STATE_CONNECTING;
11791191

features/lorawan/LoRaWANStack.h

Lines changed: 16 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -88,78 +88,29 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
8888

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

126102
/** Connect OTAA or ABP with parameters
127-
*
128-
* All connection parameters are chosen by the user and provided in the
129-
* data structure passed down.
130-
*
131-
* When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
132-
* However, this is not a real error. It tells you that connection is in progress and you will
133-
* be notified of completion via an event. By default, after Join Accept message
134-
* is received, base stations may provide the node with a CF-List which replaces
135-
* all user-configured channels except the Join/Default channels. A CF-List can
136-
* configure a maximum of five channels other than the default channels.
137-
*
138-
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
139-
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
140-
* By default, the PHY layers configure only the mandatory Join
141-
* channels. The retransmission back-off restrictions on these channels
142-
* are severe and you may experience long delays or even
143-
* failures in the confirmed traffic. If you add more channels, the aggregated duty
144-
* cycle becomes much more relaxed as compared to the Join (default) channels only.
145-
*
146-
* **NOTES ON RECONNECTION:**
147-
* Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
148-
* memory storage. Therefore, the state and frame counters cannot be restored after
149-
* a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
150-
* protocol, the state and frame counters are saved. Connecting again would try to
151-
* restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
152-
* to zero for OTAA and a new Join request lets the network server know
153-
* that the counters need a reset. The same is said about the ABP but there
154-
* is no way to convey this information to the network server. For a network
155-
* server, an ABP device is always connected. That's why storing the frame counters
156-
* is important, at least for ABP. That's why we try to restore frame counters from
157-
* session information after a disconnection.
158103
*
159104
* @param connect Options for an end device connection to the gateway.
160105
*
161-
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
162-
* a negative error code on failure.
106+
* @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
107+
* a 'CONNECTED' event. Otherwise a negative error code is returned.
108+
* Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
109+
*
110+
* For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
111+
* Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
112+
* is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
113+
* A 'CONNECTED' event is sent to the application when the JoinAccept is received.
163114
*/
164115
lorawan_status_t connect(const lorawan_connect_t &connect);
165116

features/lorawan/lorastack/mac/LoRaMac.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,9 +814,11 @@ lorawan_status_t LoRaMac::send_join_request()
814814
status = prepare_frame(&mac_hdr, &fctrl, 0, NULL, 0);
815815

816816
if (status == LORAWAN_STATUS_OK) {
817-
status = schedule_tx();
817+
if (schedule_tx() == LORAWAN_STATUS_OK) {
818+
status = LORAWAN_STATUS_CONNECT_IN_PROGRESS;
819+
}
818820
} else {
819-
tr_error("Retransmission: error %d", status);
821+
tr_error("Couldn't send a JoinRequest: error %d", status);
820822
}
821823

822824
return status;

features/lorawan/lorawan_types.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,11 @@ typedef enum lorawan_status {
9898
#if defined(LORAWAN_COMPLIANCE_TEST)
9999
LORAWAN_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */
100100
#endif
101-
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020,
102-
LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021,
103-
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022,
104-
LORAWAN_STATUS_METADATA_NOT_AVAILABLE = -1023
101+
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020, /**< Transmission will continue after duty cycle backoff*/
102+
LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021, /**< None of the channels is enabled at the moment*/
103+
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022, /**< None of the enabled channels is ready for another TX (duty cycle limited)*/
104+
LORAWAN_STATUS_METADATA_NOT_AVAILABLE = -1023, /**< Meta-data after an RX or TX is stale*/
105+
LORAWAN_STATUS_ALREADY_CONNECTED = -1024 /**< The device has already joined a network*/
105106
} lorawan_status_t;
106107

107108
/** The lorawan_connect_otaa structure.

0 commit comments

Comments
 (0)