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.
LoRaWANStack.h
00001 /** 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 Description: LoRaWAN stack layer that controls both MAC and PHY underneath 00015 00016 License: Revised BSD License, see LICENSE.TXT file include in the project 00017 00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 00019 00020 00021 Copyright (c) 2017, Arm Limited and affiliates. 00022 00023 SPDX-License-Identifier: BSD-3-Clause 00024 */ 00025 00026 #ifndef LORAWANSTACK_H_ 00027 #define LORAWANSTACK_H_ 00028 00029 #include <stdint.h> 00030 #include "events/EventQueue.h" 00031 #include "platform/Callback.h" 00032 #include "platform/NonCopyable.h" 00033 #include "lorawan/system/LoRaWANTimer.h" 00034 #include "lorastack/mac/LoRaMac.h" 00035 #include "lorawan/system/lorawan_data_structures.h" 00036 #include "LoRaRadio.h" 00037 00038 /** 00039 * A mask for the network ID. 00040 */ 00041 #define LORAWAN_NETWORK_ID_MASK ( uint32_t )0xFE000000 00042 00043 class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> { 00044 private: 00045 /** End-device states. 00046 * 00047 */ 00048 typedef enum device_states { 00049 DEVICE_STATE_NOT_INITIALIZED, 00050 DEVICE_STATE_INIT, 00051 DEVICE_STATE_JOINING, 00052 DEVICE_STATE_ABP_CONNECTING, 00053 DEVICE_STATE_JOINED, 00054 DEVICE_STATE_SEND, 00055 DEVICE_STATE_IDLE, 00056 #if defined(LORAWAN_COMPLIANCE_TEST) 00057 DEVICE_STATE_COMPLIANCE_TEST, 00058 #endif 00059 DEVICE_STATE_SHUTDOWN 00060 } device_states_t; 00061 00062 public: 00063 static LoRaWANStack& get_lorawan_stack(); 00064 00065 /** Binds radio driver to PHY layer. 00066 * 00067 * MAC layer is totally detached from the PHY layer so the stack layer 00068 * needs to play the role of an arbitrator. This API gets a radio driver 00069 * object from the application (via LoRaWANInterface), binds it to the PHY 00070 * layer and initialises radio callback handles which the radio driver will 00071 * use in order to report events. 00072 * 00073 * @param radio LoRaRadio object, i.e., the radio driver 00074 * 00075 */ 00076 void bind_radio_driver(LoRaRadio& radio); 00077 00078 /** Connect OTAA or ABP using Mbed-OS config system 00079 * 00080 * Connect by Over The Air Activation or Activation By Personalization. 00081 * You need to configure the connection properly via the Mbed OS configuration 00082 * system. 00083 * 00084 * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. 00085 * However, this is not a real error. It tells you that the connection is in progress and you will 00086 * be notified of the completion via an event. By default, after the Join Accept message 00087 * is received, base stations may provide the node with a CF-List that replaces 00088 * all user-configured channels except the Join/Default channels. A CF-List can 00089 * configure a maximum of five channels other than the default channels. 00090 * 00091 * In case of ABP, the CONNECTED event is posted before the call to `connect()` returns. 00092 * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. 00093 * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions 00094 * on these channels are severe and you may experience long delays or even failures in the confirmed traffic. 00095 * If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only. 00096 * 00097 * **NOTES ON RECONNECTION:** 00098 * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile 00099 * memory storage. Therefore, the state and frame counters cannot be restored after 00100 * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN 00101 * protocol, the state and frame counters are saved. Connecting again would try to 00102 * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset 00103 * to zero for OTAA and a new Join request lets the network server know 00104 * that the counters need a reset. The same is said about the ABP but there 00105 * is no way to convey this information to the network server. For a network 00106 * server, an ABP device is always connected. That's why storing the frame counters 00107 * is important, at least for ABP. That's why we try to restore frame counters from 00108 * session information after a disconnection. 00109 * 00110 * @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS 00111 * on success, or a negative error code on failure. 00112 */ 00113 lorawan_status_t connect(); 00114 00115 /** Connect OTAA or ABP with parameters 00116 * 00117 * All connection parameters are chosen by the user and provided in the 00118 * data structure passed down. 00119 * 00120 * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. 00121 * However, this is not a real error. It tells you that connection is in progress and you will 00122 * be notified of completion via an event. By default, after Join Accept message 00123 * is received, base stations may provide the node with a CF-List which replaces 00124 * all user-configured channels except the Join/Default channels. A CF-List can 00125 * configure a maximum of five channels other than the default channels. 00126 * 00127 * In case of ABP, the CONNECTED event is posted before the call to `connect()` returns. 00128 * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. 00129 * By default, the PHY layers configure only the mandatory Join 00130 * channels. The retransmission back-off restrictions on these channels 00131 * are severe and you may experience long delays or even 00132 * failures in the confirmed traffic. If you add more channels, the aggregated duty 00133 * cycle becomes much more relaxed as compared to the Join (default) channels only. 00134 * 00135 * **NOTES ON RECONNECTION:** 00136 * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile 00137 * memory storage. Therefore, the state and frame counters cannot be restored after 00138 * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN 00139 * protocol, the state and frame counters are saved. Connecting again would try to 00140 * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset 00141 * to zero for OTAA and a new Join request lets the network server know 00142 * that the counters need a reset. The same is said about the ABP but there 00143 * is no way to convey this information to the network server. For a network 00144 * server, an ABP device is always connected. That's why storing the frame counters 00145 * is important, at least for ABP. That's why we try to restore frame counters from 00146 * session information after a disconnection. 00147 * 00148 * @param connect Options for an end device connection to the gateway. 00149 * 00150 * @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS, 00151 * a negative error code on failure. 00152 */ 00153 lorawan_status_t connect(const lorawan_connect_t &connect); 00154 00155 /** End device initialization. 00156 * @param queue A pointer to an EventQueue passed from the application. 00157 * @return LORAWAN_STATUS_OK on success, a negative error code on failure. 00158 */ 00159 lorawan_status_t initialize_mac_layer(events::EventQueue *queue); 00160 00161 /** Sets all callbacks for the application. 00162 * 00163 * @param callbacks A pointer to the structure carrying callbacks. 00164 * @return LORAWAN_STATUS_OK on success, a negative error code on failure. 00165 */ 00166 lorawan_status_t set_lora_callbacks(lorawan_app_callbacks_t *callbacks); 00167 00168 /** Adds channels to use. 00169 * 00170 * You can provide a list of channels with appropriate parameters filled 00171 * in. However, this list is not absolute. In some regions, a CF 00172 * list gets implemented by default, which means that the network can overwrite your channel 00173 * frequency settings right after receiving a Join Accept. You may try 00174 * to set up any channel or channels after that and if the channel requested 00175 * is already active, the request is silently ignored. A negative error 00176 * code is returned if there is any problem with parameters. 00177 * 00178 * You need to ensure that the base station nearby supports the channel or channels being added. 00179 * 00180 * If your list includes a default channel (a channel where Join Requests 00181 * are received) you cannot fully configure the channel parameters. 00182 * Either leave the channel settings to default or check your 00183 * corresponding PHY layer implementation. For example, LoRaPHYE868. 00184 * 00185 * @param channel_plan A list of channels or a single channel. 00186 * 00187 * @return LORAWAN_STATUS_OK on success, a negative error 00188 * code on failure. 00189 */ 00190 lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan); 00191 00192 /** Removes a channel from the list. 00193 * 00194 * @param channel_id Index of the channel being removed 00195 * 00196 * @return LORAWAN_STATUS_OK on success, a negative error 00197 * code on failure. 00198 */ 00199 lorawan_status_t remove_a_channel(uint8_t channel_id); 00200 00201 /** Removes a previously set channel plan. 00202 * 00203 * @return LORAWAN_STATUS_OK on success, a negative error 00204 * code on failure. 00205 */ 00206 lorawan_status_t drop_channel_list(); 00207 00208 /** Gets a list of currently enabled channels . 00209 * 00210 * @param channel_plan The channel plan structure to store final result. 00211 * 00212 * @return LORAWAN_STATUS_OK on success, a negative error 00213 * code on failure. 00214 */ 00215 lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan); 00216 00217 /** Sets up a retry counter for confirmed messages. 00218 * 00219 * Valid only for confirmed messages. This API sets the number of times the 00220 * stack will retry a CONFIRMED message before giving up and reporting an 00221 * error. 00222 * 00223 * @param count The number of retries for confirmed messages. 00224 * 00225 * @return LORAWAN_STATUS_OK or a negative error code. 00226 */ 00227 lorawan_status_t set_confirmed_msg_retry(uint8_t count); 00228 00229 /** Sets up the data rate. 00230 * 00231 * `set_datarate()` first verifies whether the data rate given is valid or not. 00232 * If it is valid, the system sets the given data rate to the channel. 00233 * 00234 * @param data_rate The intended data rate, for example DR_0 or DR_1. 00235 * Note that the macro DR_* can mean different 00236 * things in different regions. 00237 * 00238 * @return LORAWAN_STATUS_OK if everything goes well, otherwise 00239 * a negative error code. 00240 */ 00241 lorawan_status_t set_channel_data_rate(uint8_t data_rate); 00242 00243 /** Enables ADR. 00244 * 00245 * @param adr_enabled 0 ADR disabled, 1 ADR enabled. 00246 * 00247 * @return LORAWAN_STATUS_OK on success, a negative error 00248 * code on failure. 00249 */ 00250 lorawan_status_t enable_adaptive_datarate(bool adr_enabled); 00251 00252 /** Send message to gateway 00253 * 00254 * @param port The application port number. Port numbers 0 and 224 00255 * are reserved, whereas port numbers from 1 to 223 00256 * (0x01 to 0xDF) are valid port numbers. 00257 * Anything out of this range is illegal. 00258 * 00259 * @param data A pointer to the data being sent. The ownership of the 00260 * buffer is not transferred. The data is copied to the 00261 * internal buffers. 00262 * 00263 * @param length The size of data in bytes. 00264 * 00265 * @param flags A flag used to determine what type of 00266 * message is being sent, for example: 00267 * 00268 * MSG_UNCONFIRMED_FLAG = 0x01 00269 * MSG_CONFIRMED_FLAG = 0x02 00270 * MSG_MULTICAST_FLAG = 0x04 00271 * MSG_PROPRIETARY_FLAG = 0x08 00272 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be 00273 * used in conjunction with MSG_UNCONFIRMED_FLAG and 00274 * MSG_CONFIRMED_FLAG depending on the intended use. 00275 * 00276 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set 00277 * a confirmed message flag for a proprietary message. 00278 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are 00279 * mutually exclusive. 00280 * 00281 * @param null_allowed Internal use only. Needed for sending empty packet 00282 * having CONFIRMED bit on. 00283 * 00284 * @return The number of bytes sent, or 00285 * LORAWAN_STATUS_WOULD_BLOCK if another TX is 00286 * ongoing, or a negative error code on failure. 00287 */ 00288 int16_t handle_tx(uint8_t port, const uint8_t* data, 00289 uint16_t length, uint8_t flags, bool null_allowed = false); 00290 00291 /** Receives a message from the Network Server. 00292 * 00293 * @param port The application port number. Port numbers 0 and 224 00294 * are reserved, whereas port numbers from 1 to 223 00295 * (0x01 to 0xDF) are valid port numbers. 00296 * Anything out of this range is illegal. 00297 * 00298 * @param data A pointer to buffer where the received data will be 00299 * stored. 00300 * 00301 * @param length The size of data in bytes 00302 * 00303 * @param flags A flag is used to determine what type of 00304 * message is being received, for example: 00305 * 00306 * MSG_UNCONFIRMED_FLAG = 0x01, 00307 * MSG_CONFIRMED_FLAG = 0x02 00308 * MSG_MULTICAST_FLAG = 0x04, 00309 * MSG_PROPRIETARY_FLAG = 0x08 00310 * 00311 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be 00312 * used in conjunction with MSG_UNCONFIRMED_FLAG and 00313 * MSG_CONFIRMED_FLAG depending on the intended use. 00314 * 00315 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set 00316 * a confirmed message flag for a proprietary message. 00317 * 00318 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are 00319 * not mutually exclusive, i.e., the user can subscribe to 00320 * receive both CONFIRMED AND UNCONFIRMED messages at 00321 * the same time. 00322 * 00323 * @return It could be one of these: 00324 * i) 0 if there is nothing else to read. 00325 * ii) Number of bytes written to user buffer. 00326 * iii) LORAWAN_STATUS_WOULD_BLOCK if there is 00327 * nothing available to read at the moment. 00328 * iv) A negative error code on failure. 00329 */ 00330 int16_t handle_rx(const uint8_t port, uint8_t* data, 00331 uint16_t length, uint8_t flags); 00332 00333 /** Send Link Check Request MAC command. 00334 * 00335 * 00336 * This API schedules a Link Check Request command (LinkCheckReq) for the network 00337 * server and once the response, i.e., LinkCheckAns MAC command is received 00338 * from the Network Server, an event is generated. 00339 * 00340 * A callback function for the link check response must be set prior to using 00341 * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. 00342 * 00343 * @return LORAWAN_STATUS_OK on successfully queuing a request, or 00344 * a negative error code on failure. 00345 * 00346 */ 00347 lorawan_status_t set_link_check_request(); 00348 00349 /** Removes link check request sticky MAC command. 00350 * 00351 * Any already queued request may still get entertained. However, no new 00352 * requests will be made. 00353 */ 00354 void remove_link_check_request(); 00355 00356 /** Shuts down the LoRaWAN protocol. 00357 * 00358 * In response to the user call for disconnection, the stack shuts down itself. 00359 * 00360 * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. 00361 */ 00362 lorawan_status_t shutdown(); 00363 00364 /** Change device class 00365 * 00366 * Change current device class. 00367 * 00368 * @param device_class The device class 00369 * 00370 * @return LORAWAN_STATUS_OK on success, 00371 * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, 00372 * or other negative error code if request failed. 00373 */ 00374 lorawan_status_t set_device_class(const device_class_t & device_class); 00375 00376 private: 00377 LoRaWANStack(); 00378 ~LoRaWANStack(); 00379 00380 /** 00381 * Checks if the user provided port is valid or not 00382 */ 00383 bool is_port_valid(uint8_t port); 00384 00385 /** 00386 * State machine for stack controller layer. 00387 */ 00388 lorawan_status_t lora_state_machine(device_states_t new_state); 00389 00390 /** 00391 * Callback function for MLME indication. Mac layer calls this function once 00392 * an MLME indication is received. This method translates Mac layer data 00393 * structure into stack layer data structure. 00394 */ 00395 void mlme_indication_handler(loramac_mlme_indication_t *mlmeIndication); 00396 00397 /** 00398 * Handles an MLME confirmation coming from the Mac layer and uses it to 00399 * update the state for example, a Join Accept triggers an MLME confirmation, 00400 * that eventually comes here and we take necessary steps accordingly. 00401 */ 00402 void mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm); 00403 00404 /** 00405 * Handles an MCPS confirmation coming from the Mac layer in response to an 00406 * MCPS request. We take appropriate actions in response to the confirmation, 00407 * e.g., letting the application know that ack was not received in case of 00408 * a CONFIRMED message or scheduling error etc. 00409 */ 00410 void mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm); 00411 00412 /** 00413 * Handles an MCPS indication coming from the Mac layer, e.g., once we 00414 * receive a packet from the Network Server, it is indicated to this handler 00415 * and consequently this handler posts an event to the application that 00416 * there is something available to read. 00417 */ 00418 void mcps_indication_handler(loramac_mcps_indication_t *mcps_indication); 00419 00420 /** 00421 * Sets up user application port 00422 */ 00423 lorawan_status_t set_application_port(uint8_t port); 00424 00425 /** End device OTAA join. 00426 * 00427 * Based on the LoRaWAN standard 1.0.2. 00428 * Join the network using the Over The Air Activation (OTAA) procedure. 00429 * 00430 * @param params The `lorawan_connect_t` type structure. 00431 * 00432 * @return LORAWAN_STATUS_OK or 00433 * LORAWAN_STATUS_CONNECT_IN_PROGRESS on success, 00434 * or a negative error code on failure. 00435 */ 00436 lorawan_status_t join_request_by_otaa(const lorawan_connect_t ¶ms); 00437 00438 /** End device ABP join. 00439 * 00440 * Based on the LoRaWAN standard 1.0.2. 00441 * Join the network using the Activation By Personalization (ABP) procedure. 00442 * 00443 * @param params The `lorawan_connect_t` type structure. 00444 * 00445 * @return LORAWAN_STATUS_OK or 00446 * LORAWAN_STATUS_CONNECT_IN_PROGRESS on success, 00447 * or a negative error code on failure. 00448 */ 00449 lorawan_status_t activation_by_personalization(const lorawan_connect_t ¶ms); 00450 00451 private: 00452 00453 LoRaMac _loramac; 00454 loramac_primitives_t LoRaMacPrimitives; 00455 00456 device_states_t _device_current_state; 00457 lorawan_app_callbacks_t _callbacks; 00458 lorawan_session_t _lw_session; 00459 loramac_tx_message_t _tx_msg; 00460 loramac_rx_message_t _rx_msg; 00461 uint8_t _num_retry; 00462 uint8_t _app_port; 00463 bool _link_check_requested; 00464 00465 events::EventQueue *_queue; 00466 00467 #if defined(LORAWAN_COMPLIANCE_TEST) 00468 00469 /** 00470 * Used only for compliance testing 00471 */ 00472 void compliance_test_handler(loramac_mcps_indication_t *mcps_indication); 00473 00474 /** 00475 * Used only for compliance testing 00476 */ 00477 lorawan_status_t send_compliance_test_frame_to_mac(); 00478 00479 compliance_test_t _compliance_test; 00480 #endif 00481 }; 00482 00483 #endif /* LORAWANSTACK_H_ */
Generated on Tue Jul 12 2022 14:23:52 by
