Mbed OS Reference
Loading...
Searching...
No Matches
LoRaWANStack.h
Go to the documentation of this file.
1/**
2 * \file LoRaWANStack.h
3 *
4 * \brief LoRaWAN stack layer implementation
5 *
6 * \copyright Revised BSD License, see LICENSE.TXT file include in the project
7 *
8 * \code
9 * ______ _
10 * / _____) _ | |
11 * ( (____ _____ ____ _| |_ _____ ____| |__
12 * \____ \| ___ | (_ _) ___ |/ ___) _ \
13 * _____) ) ____| | | || |_| ____( (___| | | |
14 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
15 * (C)2013 Semtech
16 *
17 * ___ _____ _ ___ _ _____ ___ ___ ___ ___
18 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
19 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
20 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
21 * embedded.connectivity.solutions===============
22 *
23 * \endcode
24 *
25 * \author Miguel Luis ( Semtech )
26 *
27 * \author Gregory Cristian ( Semtech )
28 *
29 * \author Daniel Jaeckle ( STACKFORCE )
30 *
31 * \addtogroup LoRaWAN
32 *
33 * License: Revised BSD License, see LICENSE.TXT file include in the project
34 *
35 * Copyright (c) 2017, Arm Limited and affiliates.
36 *
37 * SPDX-License-Identifier: BSD-3-Clause
38 */
39
40#ifndef LORAWANSTACK_H_
41#define LORAWANSTACK_H_
42
43#include <stdint.h>
44#include "events/EventQueue.h"
45#include "platform/mbed_atomic.h"
46#include "platform/Callback.h"
47#include "platform/NonCopyable.h"
48#include "platform/ScopedLock.h"
49
50#include "lorastack/mac/LoRaMac.h"
51#include "system/LoRaWANTimer.h"
53#include "LoRaRadio.h"
54
55class LoRaPHY;
56
57/** LoRaWANStack Class
58 * A controller layer for LoRaWAN MAC and PHY
59 */
60class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
61
62public:
64
65 /** Binds PHY layer and radio driver to stack.
66 *
67 * MAC layer is totally detached from the PHY layer so the stack layer
68 * needs to play the role of an arbitrator.
69 * This API sets the PHY layer object to stack and bind the radio driver
70 * object from the application to the PHY layer.
71 * Also initialises radio callback handles which the radio driver will
72 * use in order to report events.
73 *
74 * @param radio LoRaRadio object, i.e., the radio driver
75 * @param phy LoRaPHY object.
76 *
77 */
78 void bind_phy_and_radio_driver(LoRaRadio &radio, LoRaPHY &phy);
79
80 /** End device initialization.
81 * @param queue A pointer to an EventQueue passed from the application.
82 * @return LORAWAN_STATUS_OK on success, a negative error code on failure.
83 */
85
86 /** Sets all callbacks for the application.
87 *
88 * @param callbacks A pointer to the structure carrying callbacks.
89 * @return LORAWAN_STATUS_OK on success, a negative error code on failure.
90 */
92
93 /** Connect OTAA or ABP using Mbed-OS config system
94 *
95 * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
96 * a 'CONNECTED' event. Otherwise a negative error code is returned.
97 * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
98 *
99 * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
100 * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
101 * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
102 * A 'CONNECTED' event is sent to the application when the JoinAccept is received.
103 */
105
106 /** Connect OTAA or ABP with parameters
107 *
108 * @param connect Options for an end device connection to the gateway.
109 *
110 * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
111 * a 'CONNECTED' event. Otherwise a negative error code is returned.
112 * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
113 *
114 * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
115 * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
116 * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
117 * A 'CONNECTED' event is sent to the application when the JoinAccept is received.
118 */
120
121 /** Adds channels to use.
122 *
123 * You can provide a list of channels with appropriate parameters filled
124 * in. However, this list is not absolute. In some regions, a CF
125 * list gets implemented by default, which means that the network can overwrite your channel
126 * frequency settings right after receiving a Join Accept. You may try
127 * to set up any channel or channels after that and if the channel requested
128 * is already active, the request is silently ignored. A negative error
129 * code is returned if there is any problem with parameters.
130 *
131 * You need to ensure that the base station nearby supports the channel or channels being added.
132 *
133 * If your list includes a default channel (a channel where Join Requests
134 * are received) you cannot fully configure the channel parameters.
135 * Either leave the channel settings to default or check your
136 * corresponding PHY layer implementation. For example, LoRaPHYE868.
137 *
138 * @param channel_plan A list of channels or a single channel.
139 *
140 * @return LORAWAN_STATUS_OK on success, a negative error
141 * code on failure.
142 */
144
145 /** Removes a channel from the list.
146 *
147 * @param channel_id Index of the channel being removed
148 *
149 * @return LORAWAN_STATUS_OK on success, a negative error
150 * code on failure.
151 */
153
154 /** Removes a previously set channel plan.
155 *
156 * @return LORAWAN_STATUS_OK on success, a negative error
157 * code on failure.
158 */
160
161 /** Gets a list of currently enabled channels .
162 *
163 * @param channel_plan The channel plan structure to store final result.
164 *
165 * @return LORAWAN_STATUS_OK on success, a negative error
166 * code on failure.
167 */
169
170 /** Sets up a retry counter for confirmed messages.
171 *
172 * Valid only for confirmed messages. This API sets the number of times the
173 * stack will retry a CONFIRMED message before giving up and reporting an
174 * error.
175 *
176 * @param count The number of retries for confirmed messages.
177 *
178 * @return LORAWAN_STATUS_OK or a negative error code.
179 */
181
182 /** Sets up the data rate.
183 *
184 * `set_datarate()` first verifies whether the data rate given is valid or not.
185 * If it is valid, the system sets the given data rate to the channel.
186 *
187 * @param data_rate The intended data rate, for example DR_0 or DR_1.
188 * Note that the macro DR_* can mean different
189 * things in different regions.
190 *
191 * @return LORAWAN_STATUS_OK if everything goes well, otherwise
192 * a negative error code.
193 */
195
196 /** Enables ADR.
197 *
198 * @param adr_enabled 0 ADR disabled, 1 ADR enabled.
199 *
200 * @return LORAWAN_STATUS_OK on success, a negative error
201 * code on failure.
202 */
204
205 /** Send message to gateway
206 *
207 * @param port The application port number. Port numbers 0 and 224
208 * are reserved, whereas port numbers from 1 to 223
209 * (0x01 to 0xDF) are valid port numbers.
210 * Anything out of this range is illegal.
211 *
212 * @param data A pointer to the data being sent. The ownership of the
213 * buffer is not transferred. The data is copied to the
214 * internal buffers.
215 *
216 * @param length The size of data in bytes.
217 *
218 * @param flags A flag used to determine what type of
219 * message is being sent, for example:
220 *
221 * MSG_UNCONFIRMED_FLAG = 0x01
222 * MSG_CONFIRMED_FLAG = 0x02
223 * MSG_MULTICAST_FLAG = 0x04
224 * MSG_PROPRIETARY_FLAG = 0x08
225 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be
226 * used in conjunction with MSG_UNCONFIRMED_FLAG and
227 * MSG_CONFIRMED_FLAG depending on the intended use.
228 *
229 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set
230 * a confirmed message flag for a proprietary message.
231 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
232 * mutually exclusive.
233 *
234 * @param null_allowed Internal use only. Needed for sending empty packet
235 * having CONFIRMED bit on.
236 *
237 * @param allow_port_0 Internal use only. Needed for flushing MAC commands.
238 *
239 * @return The number of bytes sent, or
240 * LORAWAN_STATUS_WOULD_BLOCK if another TX is
241 * ongoing, or a negative error code on failure.
242 */
243 int16_t handle_tx(uint8_t port, const uint8_t *data,
244 uint16_t length, uint8_t flags,
245 bool null_allowed = false, bool allow_port_0 = false);
246
247 /** Receives a message from the Network Server.
248 *
249 * @param data A pointer to buffer where the received data will be
250 * stored.
251 *
252 * @param length The size of data in bytes
253 *
254 * @param port The application port number. Port numbers 0 and 224
255 * are reserved, whereas port numbers from 1 to 223
256 * (0x01 to 0xDF) are valid port numbers.
257 * Anything out of this range is illegal.
258 *
259 * In return will contain the number of port to which
260 * message was received.
261 *
262 * @param flags A flag is used to determine what type of
263 * message is being received, for example:
264 *
265 * MSG_UNCONFIRMED_FLAG = 0x01,
266 * MSG_CONFIRMED_FLAG = 0x02
267 * MSG_MULTICAST_FLAG = 0x04,
268 * MSG_PROPRIETARY_FLAG = 0x08
269 *
270 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be
271 * used in conjunction with MSG_UNCONFIRMED_FLAG and
272 * MSG_CONFIRMED_FLAG depending on the intended use.
273 *
274 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set
275 * a confirmed message flag for a proprietary message.
276 *
277 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
278 * not mutually exclusive, i.e., the user can subscribe to
279 * receive both CONFIRMED AND UNCONFIRMED messages at
280 * the same time.
281 *
282 * In return will contain the flags to determine what kind
283 * of message was received.
284 *
285 * @param validate_params If set to true, the given port and flags values will be checked
286 * against the values received with the message. If values do not
287 * match, LORAWAN_STATUS_WOULD_BLOCK will be returned.
288 *
289 * @return It could be one of these:
290 * i) 0 if there is nothing else to read.
291 * ii) Number of bytes written to user buffer.
292 * iii) LORAWAN_STATUS_WOULD_BLOCK if there is
293 * nothing available to read at the moment.
294 * iv) A negative error code on failure.
295 */
296 int16_t handle_rx(uint8_t *data, uint16_t length, uint8_t &port, int &flags, bool validate_params);
297
298 /** Send Link Check Request MAC command.
299 *
300 *
301 * This API schedules a Link Check Request command (LinkCheckReq) for the network
302 * server and once the response, i.e., LinkCheckAns MAC command is received
303 * from the Network Server, an event is generated.
304 *
305 * A callback function for the link check response must be set prior to using
306 * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown.
307 *
308 * @return LORAWAN_STATUS_OK on successfully queuing a request, or
309 * a negative error code on failure.
310 *
311 */
313
314 /** Removes link check request sticky MAC command.
315 *
316 * Any already queued request may still get entertained. However, no new
317 * requests will be made.
318 */
320
321 /** Shuts down the LoRaWAN protocol.
322 *
323 * In response to the user call for disconnection, the stack shuts down itself.
324 *
325 * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
326 */
328
329 /** Change device class
330 *
331 * Change current device class.
332 *
333 * @param device_class The device class
334 *
335 * @return LORAWAN_STATUS_OK on success,
336 * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported,
337 * or other negative error code if request failed.
338 */
340
341 /** Acquire TX meta-data
342 *
343 * Upon successful transmission, TX meta-data will be made available
344 *
345 * @param metadata A reference to the inbound structure which will be
346 * filled with any TX meta-data if available.
347 *
348 * @return LORAWAN_STATUS_OK if successful,
349 * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise
350 */
352
353 /** Acquire RX meta-data
354 *
355 * Upon successful reception, RX meta-data will be made available
356 *
357 * @param metadata A reference to the inbound structure which will be
358 * filled with any RX meta-data if available.
359 *
360 * @return LORAWAN_STATUS_OK if successful,
361 * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise
362 */
364
365 /** Acquire backoff meta-data
366 *
367 * Get hold of backoff time after which the transmission will take place.
368 *
369 * @param backoff A reference to the inbound integer which will be
370 * filled with any backoff meta-data if available.
371 *
372 * @return LORAWAN_STATUS_OK if successful,
373 * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise
374 */
376
377 /** Stops sending
378 *
379 * Stop sending any outstanding messages if they are not yet queued for
380 * transmission, i.e., if the backoff timer is nhot elapsed yet.
381 *
382 * @return LORAWAN_STATUS_OK if the transmission is cancelled.
383 * LORAWAN_STATUS_BUSY otherwise.
384 */
386
387 void lock(void)
388 {
389 _loramac.lock();
390 }
391 void unlock(void)
392 {
393 _loramac.unlock();
394 }
395
396private:
398 /**
399 * Checks if the user provided port is valid or not
400 */
401 bool is_port_valid(uint8_t port, bool allow_port_0 = false);
402
403 /**
404 * State machine for stack controller layer.
405 */
406 lorawan_status_t state_controller(device_states_t new_state);
407
408 /**
409 * Helpers for state controller
410 */
411 void process_uninitialized_state(lorawan_status_t &op_status);
412 void process_idle_state(lorawan_status_t &op_status);
413 void process_connected_state();
414 void process_connecting_state(lorawan_status_t &op_status);
415 void process_joining_state(lorawan_status_t &op_status);
416 void process_scheduling_state(lorawan_status_t &op_status);
417 void process_status_check_state();
418 void process_shutdown_state(lorawan_status_t &op_status);
419 void state_machine_run_to_completion(void);
420
421 /**
422 * Handles MLME indications
423 */
424 void mlme_indication_handler(void);
425
426 /**
427 * Handles an MLME confirmation
428 */
429 void mlme_confirm_handler(void);
430
431 /**
432 * Handles an MCPS confirmation
433 */
434 void mcps_confirm_handler(void);
435
436 /**
437 * Handles an MCPS indication
438 */
439 void mcps_indication_handler(void);
440
441 /**
442 * Sets up user application port
443 */
444 lorawan_status_t set_application_port(uint8_t port, bool allow_port_0 = false);
445
446 /**
447 * Handles connection internally
448 */
449 lorawan_status_t handle_connect(bool is_otaa);
450
451
452 /** Send event to application.
453 *
454 * @param event The event to be sent.
455 */
456 void send_event_to_application(const lorawan_event_t event) const;
457
458 /** Send empty uplink message to network.
459 *
460 * Sends an empty confirmed message to gateway.
461 *
462 * @param port The event to be sent.
463 */
464 void send_automatic_uplink_message(uint8_t port);
465
466 /**
467 * TX interrupt handlers and corresponding processors
468 */
469 void tx_interrupt_handler(void);
470 void tx_timeout_interrupt_handler(void);
471 void process_transmission(void);
472 void process_transmission_timeout(void);
473
474 /**
475 * RX interrupt handlers and corresponding processors
476 */
477 void rx_interrupt_handler(const uint8_t *payload, uint16_t size, int16_t rssi,
478 int8_t snr);
479 void rx_timeout_interrupt_handler(void);
480 void rx_error_interrupt_handler(void);
481 void process_reception(const uint8_t *payload, uint16_t size, int16_t rssi,
482 int8_t snr);
483 void process_reception_timeout(bool is_timeout);
484
485 int convert_to_msg_flag(const mcps_type_t type);
486
487 void make_tx_metadata_available(void);
488 void make_rx_metadata_available(void);
489
490 void handle_scheduling_failure(void);
491
492 void post_process_tx_with_reception(void);
493 void post_process_tx_no_reception(void);
494
495private:
496 LoRaMac _loramac;
498 device_states_t _device_current_state;
499 lorawan_app_callbacks_t _callbacks;
500 lorawan_session_t _lw_session;
501 loramac_tx_message_t _tx_msg;
502 loramac_rx_message_t _rx_msg;
503 lorawan_tx_metadata _tx_metadata;
504 lorawan_rx_metadata _rx_metadata;
505 uint8_t _num_retry;
506 uint8_t _qos_cnt;
507 uint32_t _ctrl_flags;
508 uint8_t _app_port;
509 bool _link_check_requested;
510 bool _automatic_uplink_ongoing;
511 core_util_atomic_flag _rx_payload_in_use;
512 uint8_t _rx_payload[LORAMAC_PHY_MAXPAYLOAD];
513 events::EventQueue *_queue;
514 lorawan_time_t _tx_timestamp;
515};
516
517#endif /* LORAWANSTACK_H_ */
Interface for the radios, containing the main functions that a radio needs, and five callback functio...
Definition: LoRaRadio.h:441
LoRaWANStack Class A controller layer for LoRaWAN MAC and PHY.
Definition: LoRaWANStack.h:60
lorawan_status_t stop_sending(void)
Stops sending.
lorawan_status_t remove_a_channel(uint8_t channel_id)
Removes a channel from the list.
lorawan_status_t drop_channel_list()
Removes a previously set channel plan.
lorawan_status_t set_channel_data_rate(uint8_t data_rate)
Sets up the data rate.
lorawan_status_t shutdown()
Shuts down the LoRaWAN protocol.
lorawan_status_t enable_adaptive_datarate(bool adr_enabled)
Enables ADR.
lorawan_status_t set_lora_callbacks(const lorawan_app_callbacks_t *callbacks)
Sets all callbacks for the application.
lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan)
Gets a list of currently enabled channels .
int16_t handle_tx(uint8_t port, const uint8_t *data, uint16_t length, uint8_t flags, bool null_allowed=false, bool allow_port_0=false)
Send message to gateway.
lorawan_status_t acquire_rx_metadata(lorawan_rx_metadata &metadata)
Acquire RX meta-data.
void remove_link_check_request()
Removes link check request sticky MAC command.
lorawan_status_t set_link_check_request()
Send Link Check Request MAC command.
lorawan_status_t connect()
Connect OTAA or ABP using Mbed-OS config system.
void bind_phy_and_radio_driver(LoRaRadio &radio, LoRaPHY &phy)
Binds PHY layer and radio driver to stack.
int16_t handle_rx(uint8_t *data, uint16_t length, uint8_t &port, int &flags, bool validate_params)
Receives a message from the Network Server.
lorawan_status_t set_device_class(const device_class_t &device_class)
Change device class.
lorawan_status_t acquire_backoff_metadata(int &backoff)
Acquire backoff meta-data.
lorawan_status_t set_confirmed_msg_retry(uint8_t count)
Sets up a retry counter for confirmed messages.
lorawan_status_t acquire_tx_metadata(lorawan_tx_metadata &metadata)
Acquire TX meta-data.
lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan)
Adds channels to use.
lorawan_status_t initialize_mac_layer(events::EventQueue *queue)
End device initialization.
lorawan_status_t connect(const lorawan_connect_t &connect)
Connect OTAA or ABP with parameters.
EventQueue.
Definition: EventQueue.h:62
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
RAII-style mechanism for owning a lock of Lockable object for the duration of a scoped block.
Definition: ScopedLock.h:63
Contains common data structures used by Mbed-OS LoRaWAN mplementation.
enum device_states device_states_t
End-device states.
#define LORAMAC_PHY_MAXPAYLOAD
Maximum PHY layer payload size for reception.
mcps_type_t
LoRaMAC data services.
uint32_t lorawan_time_t
Timer time variable definition.
enum lorawan_status lorawan_status_t
lorawan_status_t contains status codes in response to stack operations
enum lora_events lorawan_event_t
Events needed to announce stack operation results.
device_class_t
LoRaWAN device classes definition.
Definition: lorawan_types.h:59
A lock-free, primitive atomic flag.
Definition: mbed_atomic.h:118
DO NOT MODIFY, WILL BREAK THE API!
Stack level TX message structure.
Stack level callback functions.
lorawan_connect_t structure
Meta-data collection for the received packet.
Meta-data collection for a transmission.
Reporting functions for upper layers.
Definition: LoRaRadio.h:390