Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51_Vdd TextLCD BME280
LoRaWANStack.h
00001 /** 00002 * \file LoRaWANStack.h 00003 * 00004 * \brief LoRaWAN stack layer implementation 00005 * 00006 * \copyright Revised BSD License, see LICENSE.TXT file include in the project 00007 * 00008 * \code 00009 * ______ _ 00010 * / _____) _ | | 00011 * ( (____ _____ ____ _| |_ _____ ____| |__ 00012 * \____ \| ___ | (_ _) ___ |/ ___) _ \ 00013 * _____) ) ____| | | || |_| ____( (___| | | | 00014 * (______/|_____)_|_|_| \__)_____)\____)_| |_| 00015 * (C)2013 Semtech 00016 * 00017 * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00018 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00019 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00020 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00021 * embedded.connectivity.solutions=============== 00022 * 00023 * \endcode 00024 * 00025 * \author Miguel Luis ( Semtech ) 00026 * 00027 * \author Gregory Cristian ( Semtech ) 00028 * 00029 * \author Daniel Jaeckle ( STACKFORCE ) 00030 * 00031 * \defgroup LoRaWAN stack layer that controls MAC layer underneath 00032 * 00033 * License: Revised BSD License, see LICENSE.TXT file include in the project 00034 * 00035 * Copyright (c) 2017, Arm Limited and affiliates. 00036 * 00037 * SPDX-License-Identifier: BSD-3-Clause 00038 */ 00039 00040 #ifndef LORAWANSTACK_H_ 00041 #define LORAWANSTACK_H_ 00042 00043 #include <stdint.h> 00044 #include "events/EventQueue.h" 00045 #include "platform/Callback.h" 00046 #include "platform/NonCopyable.h" 00047 #include "platform/ScopedLock.h" 00048 00049 #include "lorastack/mac/LoRaMac.h" 00050 #include "system/LoRaWANTimer.h" 00051 #include "system/lorawan_data_structures.h" 00052 #include "LoRaRadio.h" 00053 00054 class LoRaPHY; 00055 00056 class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> { 00057 00058 public: 00059 LoRaWANStack(); 00060 00061 /** Binds PHY layer and radio driver to stack. 00062 * 00063 * MAC layer is totally detached from the PHY layer so the stack layer 00064 * needs to play the role of an arbitrator. 00065 * This API sets the PHY layer object to stack and bind the radio driver 00066 * object from the application to the PHY layer. 00067 * Also initialises radio callback handles which the radio driver will 00068 * use in order to report events. 00069 * 00070 * @param radio LoRaRadio object, i.e., the radio driver 00071 * @param phy LoRaPHY object. 00072 * 00073 */ 00074 void bind_phy_and_radio_driver(LoRaRadio &radio, LoRaPHY &phy); 00075 00076 /** End device initialization. 00077 * @param queue A pointer to an EventQueue passed from the application. 00078 * @return LORAWAN_STATUS_OK on success, a negative error code on failure. 00079 */ 00080 lorawan_status_t initialize_mac_layer(events::EventQueue *queue); 00081 00082 /** Sets all callbacks for the application. 00083 * 00084 * @param callbacks A pointer to the structure carrying callbacks. 00085 * @return LORAWAN_STATUS_OK on success, a negative error code on failure. 00086 */ 00087 lorawan_status_t set_lora_callbacks(const lorawan_app_callbacks_t *callbacks); 00088 00089 /** Connect OTAA or ABP using Mbed-OS config system 00090 * 00091 * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by 00092 * a 'CONNECTED' event. Otherwise a negative error code is returned. 00093 * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. 00094 * 00095 * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. 00096 * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection 00097 * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). 00098 * A 'CONNECTED' event is sent to the application when the JoinAccept is received. 00099 */ 00100 lorawan_status_t connect(); 00101 00102 /** Connect OTAA or ABP with parameters 00103 * 00104 * @param connect Options for an end device connection to the gateway. 00105 * 00106 * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by 00107 * a 'CONNECTED' event. Otherwise a negative error code is returned. 00108 * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. 00109 * 00110 * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. 00111 * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection 00112 * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). 00113 * A 'CONNECTED' event is sent to the application when the JoinAccept is received. 00114 */ 00115 lorawan_status_t connect(const lorawan_connect_t &connect); 00116 00117 /** Adds channels to use. 00118 * 00119 * You can provide a list of channels with appropriate parameters filled 00120 * in. However, this list is not absolute. In some regions, a CF 00121 * list gets implemented by default, which means that the network can overwrite your channel 00122 * frequency settings right after receiving a Join Accept. You may try 00123 * to set up any channel or channels after that and if the channel requested 00124 * is already active, the request is silently ignored. A negative error 00125 * code is returned if there is any problem with parameters. 00126 * 00127 * You need to ensure that the base station nearby supports the channel or channels being added. 00128 * 00129 * If your list includes a default channel (a channel where Join Requests 00130 * are received) you cannot fully configure the channel parameters. 00131 * Either leave the channel settings to default or check your 00132 * corresponding PHY layer implementation. For example, LoRaPHYE868. 00133 * 00134 * @param channel_plan A list of channels or a single channel. 00135 * 00136 * @return LORAWAN_STATUS_OK on success, a negative error 00137 * code on failure. 00138 */ 00139 lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan); 00140 00141 /** Removes a channel from the list. 00142 * 00143 * @param channel_id Index of the channel being removed 00144 * 00145 * @return LORAWAN_STATUS_OK on success, a negative error 00146 * code on failure. 00147 */ 00148 lorawan_status_t remove_a_channel(uint8_t channel_id); 00149 00150 /** Removes a previously set channel plan. 00151 * 00152 * @return LORAWAN_STATUS_OK on success, a negative error 00153 * code on failure. 00154 */ 00155 lorawan_status_t drop_channel_list(); 00156 00157 /** Gets a list of currently enabled channels . 00158 * 00159 * @param channel_plan The channel plan structure to store final result. 00160 * 00161 * @return LORAWAN_STATUS_OK on success, a negative error 00162 * code on failure. 00163 */ 00164 lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan); 00165 00166 /** Sets up a retry counter for confirmed messages. 00167 * 00168 * Valid only for confirmed messages. This API sets the number of times the 00169 * stack will retry a CONFIRMED message before giving up and reporting an 00170 * error. 00171 * 00172 * @param count The number of retries for confirmed messages. 00173 * 00174 * @return LORAWAN_STATUS_OK or a negative error code. 00175 */ 00176 lorawan_status_t set_confirmed_msg_retry(uint8_t count); 00177 00178 /** Sets up the data rate. 00179 * 00180 * `set_datarate()` first verifies whether the data rate given is valid or not. 00181 * If it is valid, the system sets the given data rate to the channel. 00182 * 00183 * @param data_rate The intended data rate, for example DR_0 or DR_1. 00184 * Note that the macro DR_* can mean different 00185 * things in different regions. 00186 * 00187 * @return LORAWAN_STATUS_OK if everything goes well, otherwise 00188 * a negative error code. 00189 */ 00190 lorawan_status_t set_channel_data_rate(uint8_t data_rate); 00191 00192 /** Enables ADR. 00193 * 00194 * @param adr_enabled 0 ADR disabled, 1 ADR enabled. 00195 * 00196 * @return LORAWAN_STATUS_OK on success, a negative error 00197 * code on failure. 00198 */ 00199 lorawan_status_t enable_adaptive_datarate(bool adr_enabled); 00200 00201 /** Send message to gateway 00202 * 00203 * @param port The application port number. Port numbers 0 and 224 00204 * are reserved, whereas port numbers from 1 to 223 00205 * (0x01 to 0xDF) are valid port numbers. 00206 * Anything out of this range is illegal. 00207 * 00208 * @param data A pointer to the data being sent. The ownership of the 00209 * buffer is not transferred. The data is copied to the 00210 * internal buffers. 00211 * 00212 * @param length The size of data in bytes. 00213 * 00214 * @param flags A flag used to determine what type of 00215 * message is being sent, for example: 00216 * 00217 * MSG_UNCONFIRMED_FLAG = 0x01 00218 * MSG_CONFIRMED_FLAG = 0x02 00219 * MSG_MULTICAST_FLAG = 0x04 00220 * MSG_PROPRIETARY_FLAG = 0x08 00221 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be 00222 * used in conjunction with MSG_UNCONFIRMED_FLAG and 00223 * MSG_CONFIRMED_FLAG depending on the intended use. 00224 * 00225 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set 00226 * a confirmed message flag for a proprietary message. 00227 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are 00228 * mutually exclusive. 00229 * 00230 * @param null_allowed Internal use only. Needed for sending empty packet 00231 * having CONFIRMED bit on. 00232 * 00233 * @param allow_port_0 Internal use only. Needed for flushing MAC commands. 00234 * 00235 * @return The number of bytes sent, or 00236 * LORAWAN_STATUS_WOULD_BLOCK if another TX is 00237 * ongoing, or a negative error code on failure. 00238 */ 00239 int16_t handle_tx(uint8_t port, const uint8_t *data, 00240 uint16_t length, uint8_t flags, 00241 bool null_allowed = false, bool allow_port_0 = false); 00242 00243 /** Receives a message from the Network Server. 00244 * 00245 * @param data A pointer to buffer where the received data will be 00246 * stored. 00247 * 00248 * @param length The size of data in bytes 00249 * 00250 * @param port The application port number. Port numbers 0 and 224 00251 * are reserved, whereas port numbers from 1 to 223 00252 * (0x01 to 0xDF) are valid port numbers. 00253 * Anything out of this range is illegal. 00254 * 00255 * In return will contain the number of port to which 00256 * message was received. 00257 * 00258 * @param flags A flag is used to determine what type of 00259 * message is being received, for example: 00260 * 00261 * MSG_UNCONFIRMED_FLAG = 0x01, 00262 * MSG_CONFIRMED_FLAG = 0x02 00263 * MSG_MULTICAST_FLAG = 0x04, 00264 * MSG_PROPRIETARY_FLAG = 0x08 00265 * 00266 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be 00267 * used in conjunction with MSG_UNCONFIRMED_FLAG and 00268 * MSG_CONFIRMED_FLAG depending on the intended use. 00269 * 00270 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set 00271 * a confirmed message flag for a proprietary message. 00272 * 00273 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are 00274 * not mutually exclusive, i.e., the user can subscribe to 00275 * receive both CONFIRMED AND UNCONFIRMED messages at 00276 * the same time. 00277 * 00278 * In return will contain the flags to determine what kind 00279 * of message was received. 00280 * 00281 * @param validate_params If set to true, the given port and flags values will be checked 00282 * against the values received with the message. If values do not 00283 * match, LORAWAN_STATUS_WOULD_BLOCK will be returned. 00284 * 00285 * @return It could be one of these: 00286 * i) 0 if there is nothing else to read. 00287 * ii) Number of bytes written to user buffer. 00288 * iii) LORAWAN_STATUS_WOULD_BLOCK if there is 00289 * nothing available to read at the moment. 00290 * iv) A negative error code on failure. 00291 */ 00292 int16_t handle_rx(uint8_t *data, uint16_t length, uint8_t &port, int &flags, bool validate_params); 00293 00294 /** Send Link Check Request MAC command. 00295 * 00296 * 00297 * This API schedules a Link Check Request command (LinkCheckReq) for the network 00298 * server and once the response, i.e., LinkCheckAns MAC command is received 00299 * from the Network Server, an event is generated. 00300 * 00301 * A callback function for the link check response must be set prior to using 00302 * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. 00303 * 00304 * @return LORAWAN_STATUS_OK on successfully queuing a request, or 00305 * a negative error code on failure. 00306 * 00307 */ 00308 lorawan_status_t set_link_check_request(); 00309 00310 /** Removes link check request sticky MAC command. 00311 * 00312 * Any already queued request may still get entertained. However, no new 00313 * requests will be made. 00314 */ 00315 void remove_link_check_request(); 00316 00317 /** Shuts down the LoRaWAN protocol. 00318 * 00319 * In response to the user call for disconnection, the stack shuts down itself. 00320 * 00321 * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. 00322 */ 00323 lorawan_status_t shutdown(); 00324 00325 /** Change device class 00326 * 00327 * Change current device class. 00328 * 00329 * @param device_class The device class 00330 * 00331 * @return LORAWAN_STATUS_OK on success, 00332 * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, 00333 * or other negative error code if request failed. 00334 */ 00335 lorawan_status_t set_device_class(const device_class_t &device_class); 00336 00337 /** Acquire TX meta-data 00338 * 00339 * Upon successful transmission, TX meta-data will be made available 00340 * 00341 * @param metadata A reference to the inbound structure which will be 00342 * filled with any TX meta-data if available. 00343 * 00344 * @return LORAWAN_STATUS_OK if successful, 00345 * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise 00346 */ 00347 lorawan_status_t acquire_tx_metadata(lorawan_tx_metadata &metadata); 00348 00349 /** Acquire RX meta-data 00350 * 00351 * Upon successful reception, RX meta-data will be made available 00352 * 00353 * @param metadata A reference to the inbound structure which will be 00354 * filled with any RX meta-data if available. 00355 * 00356 * @return LORAWAN_STATUS_OK if successful, 00357 * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise 00358 */ 00359 lorawan_status_t acquire_rx_metadata(lorawan_rx_metadata &metadata); 00360 00361 /** Acquire backoff meta-data 00362 * 00363 * Get hold of backoff time after which the transmission will take place. 00364 * 00365 * @param backoff A reference to the inbound integer which will be 00366 * filled with any backoff meta-data if available. 00367 * 00368 * @return LORAWAN_STATUS_OK if successful, 00369 * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise 00370 */ 00371 lorawan_status_t acquire_backoff_metadata(int &backoff); 00372 00373 /** Stops sending 00374 * 00375 * Stop sending any outstanding messages if they are not yet queued for 00376 * transmission, i.e., if the backoff timer is nhot elapsed yet. 00377 * 00378 * @return LORAWAN_STATUS_OK if the transmission is cancelled. 00379 * LORAWAN_STATUS_BUSY otherwise. 00380 */ 00381 lorawan_status_t stop_sending(void); 00382 00383 void lock(void) 00384 { 00385 _loramac.lock(); 00386 } 00387 void unlock(void) 00388 { 00389 _loramac.unlock(); 00390 } 00391 00392 private: 00393 typedef mbed::ScopedLock<LoRaWANStack> Lock; 00394 /** 00395 * Checks if the user provided port is valid or not 00396 */ 00397 bool is_port_valid(uint8_t port, bool allow_port_0 = false); 00398 00399 /** 00400 * State machine for stack controller layer. 00401 */ 00402 lorawan_status_t state_controller(device_states_t new_state); 00403 00404 /** 00405 * Helpers for state controller 00406 */ 00407 void process_uninitialized_state(lorawan_status_t &op_status); 00408 void process_idle_state(lorawan_status_t &op_status); 00409 void process_connected_state(); 00410 void process_connecting_state(lorawan_status_t &op_status); 00411 void process_joining_state(lorawan_status_t &op_status); 00412 void process_scheduling_state(lorawan_status_t &op_status); 00413 void process_status_check_state(); 00414 void process_shutdown_state(lorawan_status_t &op_status); 00415 void state_machine_run_to_completion(void); 00416 00417 /** 00418 * Handles MLME indications 00419 */ 00420 void mlme_indication_handler(void); 00421 00422 /** 00423 * Handles an MLME confirmation 00424 */ 00425 void mlme_confirm_handler(void); 00426 00427 /** 00428 * Handles an MCPS confirmation 00429 */ 00430 void mcps_confirm_handler(void); 00431 00432 /** 00433 * Handles an MCPS indication 00434 */ 00435 void mcps_indication_handler(void); 00436 00437 /** 00438 * Sets up user application port 00439 */ 00440 lorawan_status_t set_application_port(uint8_t port, bool allow_port_0 = false); 00441 00442 /** 00443 * Handles connection internally 00444 */ 00445 lorawan_status_t handle_connect(bool is_otaa); 00446 00447 00448 /** Send event to application. 00449 * 00450 * @param event The event to be sent. 00451 */ 00452 void send_event_to_application(const lorawan_event_t event) const; 00453 00454 /** Send empty uplink message to network. 00455 * 00456 * Sends an empty confirmed message to gateway. 00457 * 00458 * @param port The event to be sent. 00459 */ 00460 void send_automatic_uplink_message(uint8_t port); 00461 00462 /** 00463 * TX interrupt handlers and corresponding processors 00464 */ 00465 void tx_interrupt_handler(void); 00466 void tx_timeout_interrupt_handler(void); 00467 void process_transmission(void); 00468 void process_transmission_timeout(void); 00469 00470 /** 00471 * RX interrupt handlers and corresponding processors 00472 */ 00473 void rx_interrupt_handler(const uint8_t *payload, uint16_t size, int16_t rssi, 00474 int8_t snr); 00475 void rx_timeout_interrupt_handler(void); 00476 void rx_error_interrupt_handler(void); 00477 void process_reception(const uint8_t *payload, uint16_t size, int16_t rssi, 00478 int8_t snr); 00479 void process_reception_timeout(bool is_timeout); 00480 00481 int convert_to_msg_flag(const mcps_type_t type); 00482 00483 void make_tx_metadata_available(void); 00484 void make_rx_metadata_available(void); 00485 00486 void handle_scheduling_failure(void); 00487 00488 void post_process_tx_with_reception(void); 00489 void post_process_tx_no_reception(void); 00490 00491 private: 00492 LoRaMac _loramac; 00493 radio_events_t radio_events; 00494 device_states_t _device_current_state; 00495 lorawan_app_callbacks_t _callbacks; 00496 lorawan_session_t _lw_session; 00497 loramac_tx_message_t _tx_msg; 00498 loramac_rx_message_t _rx_msg; 00499 lorawan_tx_metadata _tx_metadata; 00500 lorawan_rx_metadata _rx_metadata; 00501 uint8_t _num_retry; 00502 uint8_t _qos_cnt; 00503 uint32_t _ctrl_flags; 00504 uint8_t _app_port; 00505 bool _link_check_requested; 00506 bool _automatic_uplink_ongoing; 00507 volatile bool _ready_for_rx; 00508 uint8_t _rx_payload[LORAMAC_PHY_MAXPAYLOAD]; 00509 events::EventQueue *_queue; 00510 lorawan_time_t _tx_timestamp; 00511 }; 00512 00513 #endif /* LORAWANSTACK_H_ */
Generated on Tue Jul 12 2022 15:15:48 by
