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 #ifdef MBED_CONF_LORA_PHY 00039 #if MBED_CONF_LORA_PHY == 0 00040 #include "lorawan/lorastack/phy/LoRaPHYEU868.h" 00041 #define LoRaPHY_region LoRaPHYEU868 00042 #elif MBED_CONF_LORA_PHY == 1 00043 #include "lorawan/lorastack/phy/LoRaPHYAS923.h" 00044 #define LoRaPHY_region LoRaPHYAS923 00045 #elif MBED_CONF_LORA_PHY == 2 00046 #include "lorawan/lorastack/phy/LoRaPHYAU915.h" 00047 #define LoRaPHY_region LoRaPHYAU915; 00048 #elif MBED_CONF_LORA_PHY == 3 00049 #include "lorawan/lorastack/phy/LoRaPHYCN470.h" 00050 #define LoRaPHY_region LoRaPHYCN470 00051 #elif MBED_CONF_LORA_PHY == 4 00052 #include "lorawan/lorastack/phy/LoRaPHYCN779.h" 00053 #define LoRaPHY_region LoRaPHYCN779 00054 #elif MBED_CONF_LORA_PHY == 5 00055 #include "lorawan/lorastack/phy/LoRaPHYEU433.h" 00056 #define LoRaPHY_region LoRaPHYEU433 00057 #elif MBED_CONF_LORA_PHY == 6 00058 #include "lorawan/lorastack/phy/LoRaPHYIN865.h" 00059 #define LoRaPHY_region LoRaPHYIN865 00060 #elif MBED_CONF_LORA_PHY == 7 00061 #include "lorawan/lorastack/phy/LoRaPHYKR920.h" 00062 #define LoRaPHY_region LoRaPHYKR920 00063 #elif MBED_CONF_LORA_PHY == 8 00064 #include "lorawan/lorastack/phy/LoRaPHYUS915.h" 00065 #define LoRaPHY_region LoRaPHYUS915 00066 #elif MBED_CONF_LORA_PHY == 9 00067 #include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h" 00068 #define LoRaPHY_region LoRaPHYUS915Hybrid 00069 #endif //MBED_CONF_LORA_PHY == VALUE 00070 #else 00071 #error "Must set LoRa PHY layer parameters." 00072 #endif //MBED_CONF_LORA_PHY 00073 00074 /** 00075 * A mask for the network ID. 00076 */ 00077 #define LORAWAN_NETWORK_ID_MASK ( uint32_t )0xFE000000 00078 00079 class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> { 00080 private: 00081 /** End-device states. 00082 * 00083 */ 00084 typedef enum device_states { 00085 DEVICE_STATE_NOT_INITIALIZED, 00086 DEVICE_STATE_INIT, 00087 DEVICE_STATE_JOINING, 00088 DEVICE_STATE_ABP_CONNECTING, 00089 DEVICE_STATE_JOINED, 00090 DEVICE_STATE_SEND, 00091 DEVICE_STATE_IDLE, 00092 #if defined(LORAWAN_COMPLIANCE_TEST) 00093 DEVICE_STATE_COMPLIANCE_TEST, 00094 #endif 00095 DEVICE_STATE_SHUTDOWN 00096 } device_states_t; 00097 00098 public: 00099 static LoRaWANStack& get_lorawan_stack(); 00100 00101 /** Binds radio driver to PHY layer. 00102 * 00103 * MAC layer is totally detached from the PHY layer so the stack layer 00104 * needs to play the role of an arbitrator. This API gets a radio driver 00105 * object from the application (via LoRaWANInterface), binds it to the PHY 00106 * layer and returns MAC layer callback handles which the radio driver will 00107 * use in order to report events. 00108 * 00109 * @param radio LoRaRadio object, i.e., the radio driver 00110 * 00111 * @return A list of callbacks from MAC layer that needs to 00112 * be passed to radio driver 00113 */ 00114 radio_events_t *bind_radio_driver(LoRaRadio& radio); 00115 00116 /** End device initialization. 00117 * @param queue A pointer to an EventQueue passed from the application. 00118 * @return LORAWAN_STATUS_OK on success, a negative error code on failure. 00119 */ 00120 lorawan_status_t initialize_mac_layer(events::EventQueue *queue); 00121 00122 /** Sets all callbacks for the application. 00123 * 00124 * @param callbacks A pointer to the structure carrying callbacks. 00125 */ 00126 void set_lora_callbacks(lorawan_app_callbacks_t *callbacks); 00127 00128 /** Adds channels to use. 00129 * 00130 * You can provide a list of channels with appropriate parameters filled 00131 * in. However, this list is not absolute. In some regions, a CF 00132 * list gets implemented by default, which means that the network can overwrite your channel 00133 * frequency settings right after receiving a Join Accept. You may try 00134 * to set up any channel or channels after that and if the channel requested 00135 * is already active, the request is silently ignored. A negative error 00136 * code is returned if there is any problem with parameters. 00137 * 00138 * You need to ensure that the base station nearby supports the channel or channels being added. 00139 * 00140 * If your list includes a default channel (a channel where Join Requests 00141 * are received) you cannot fully configure the channel parameters. 00142 * Either leave the channel settings to default or check your 00143 * corresponding PHY layer implementation. For example, LoRaPHYE868. 00144 * 00145 * @param channel_plan A list of channels or a single channel. 00146 * 00147 * @return LORAWAN_STATUS_OK on success, a negative error 00148 * code on failure. 00149 */ 00150 lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan); 00151 00152 /** Removes a channel from the list. 00153 * 00154 * @param channel_id Index of the channel being removed 00155 * 00156 * @return LORAWAN_STATUS_OK on success, a negative error 00157 * code on failure. 00158 */ 00159 lorawan_status_t remove_a_channel(uint8_t channel_id); 00160 00161 /** Removes a previously set channel plan. 00162 * 00163 * @return LORAWAN_STATUS_OK on success, a negative error 00164 * code on failure. 00165 */ 00166 lorawan_status_t drop_channel_list(); 00167 00168 /** Gets a list of currently enabled channels . 00169 * 00170 * @param channel_plan The channel plan structure to store final result. 00171 * 00172 * @return LORAWAN_STATUS_OK on success, a negative error 00173 * code on failure. 00174 */ 00175 lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan); 00176 00177 /** Sets up a retry counter for confirmed messages. 00178 * 00179 * Valid only for confirmed messages. This API sets the number of times the 00180 * stack will retry a CONFIRMED message before giving up and reporting an 00181 * error. 00182 * 00183 * @param count The number of retries for confirmed messages. 00184 * 00185 * @return LORAWAN_STATUS_OK or a negative error code. 00186 */ 00187 lorawan_status_t set_confirmed_msg_retry(uint8_t count); 00188 00189 /** Sets up the data rate. 00190 * 00191 * `set_datarate()` first verifies whether the data rate given is valid or not. 00192 * If it is valid, the system sets the given data rate to the channel. 00193 * 00194 * @param data_rate The intended data rate, for example DR_0 or DR_1. 00195 * Note that the macro DR_* can mean different 00196 * things in different regions. 00197 * 00198 * @return LORAWAN_STATUS_OK if everything goes well, otherwise 00199 * a negative error code. 00200 */ 00201 lorawan_status_t set_channel_data_rate(uint8_t data_rate); 00202 00203 /** Enables ADR. 00204 * 00205 * @param adr_enabled 0 ADR disabled, 1 ADR enabled. 00206 * 00207 * @return LORAWAN_STATUS_OK on success, a negative error 00208 * code on failure. 00209 */ 00210 lorawan_status_t enable_adaptive_datarate(bool adr_enabled); 00211 00212 /** Commissions a LoRa device. 00213 * 00214 * @param commission_data A structure representing all the commission 00215 * information. 00216 */ 00217 void commission_device(const lorawan_dev_commission_t &commission_data); 00218 00219 /** End device OTAA join. 00220 * 00221 * Based on the LoRaWAN standard 1.0.2. 00222 * Join the network using the Over The Air Activation (OTAA) procedure. 00223 * 00224 * @param params The `lorawan_connect_t` type structure. 00225 * 00226 * @return LORAWAN_STATUS_OK or 00227 * LORAWAN_STATUS_CONNECT_IN_PROGRESS on success, 00228 * or a negative error code on failure. 00229 */ 00230 lorawan_status_t join_request_by_otaa(const lorawan_connect_t ¶ms); 00231 00232 /** End device ABP join. 00233 * 00234 * Based on the LoRaWAN standard 1.0.2. 00235 * Join the network using the Activation By Personalization (ABP) procedure. 00236 * 00237 * @param params The `lorawan_connect_t` type structure. 00238 * 00239 * @return LORAWAN_STATUS_OK or 00240 * LORAWAN_STATUS_CONNECT_IN_PROGRESS on success, 00241 * or a negative error code on failure. 00242 */ 00243 lorawan_status_t activation_by_personalization(const lorawan_connect_t ¶ms); 00244 00245 /** Send message to gateway 00246 * 00247 * @param port The application port number. Port numbers 0 and 224 00248 * are reserved, whereas port numbers from 1 to 223 00249 * (0x01 to 0xDF) are valid port numbers. 00250 * Anything out of this range is illegal. 00251 * 00252 * @param data A pointer to the data being sent. The ownership of the 00253 * buffer is not transferred. The data is copied to the 00254 * internal buffers. 00255 * 00256 * @param length The size of data in bytes. 00257 * 00258 * @param flags A flag used to determine what type of 00259 * message is being sent, for example: 00260 * 00261 * MSG_UNCONFIRMED_FLAG = 0x01 00262 * MSG_CONFIRMED_FLAG = 0x02 00263 * MSG_MULTICAST_FLAG = 0x04 00264 * MSG_PROPRIETARY_FLAG = 0x08 00265 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be 00266 * used in conjunction with MSG_UNCONFIRMED_FLAG and 00267 * MSG_CONFIRMED_FLAG depending on the intended use. 00268 * 00269 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set 00270 * a confirmed message flag for a proprietary message. 00271 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are 00272 * mutually exclusive. 00273 * 00274 * 00275 * @return The number of bytes sent, or 00276 * LORAWAN_STATUS_WOULD_BLOCK if another TX is 00277 * ongoing, or a negative error code on failure. 00278 */ 00279 int16_t handle_tx(uint8_t port, const uint8_t* data, 00280 uint16_t length, uint8_t flags); 00281 00282 /** Receives a message from the Network Server. 00283 * 00284 * @param port The application port number. Port numbers 0 and 224 00285 * are reserved, whereas port numbers from 1 to 223 00286 * (0x01 to 0xDF) are valid port numbers. 00287 * Anything out of this range is illegal. 00288 * 00289 * @param data A pointer to buffer where the received data will be 00290 * stored. 00291 * 00292 * @param length The size of data in bytes 00293 * 00294 * @param flags A flag is used to determine what type of 00295 * message is being received, for example: 00296 * 00297 * MSG_UNCONFIRMED_FLAG = 0x01, 00298 * MSG_CONFIRMED_FLAG = 0x02 00299 * MSG_MULTICAST_FLAG = 0x04, 00300 * MSG_PROPRIETARY_FLAG = 0x08 00301 * 00302 * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be 00303 * used in conjunction with MSG_UNCONFIRMED_FLAG and 00304 * MSG_CONFIRMED_FLAG depending on the intended use. 00305 * 00306 * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set 00307 * a confirmed message flag for a proprietary message. 00308 * 00309 * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are 00310 * not mutually exclusive, i.e., the user can subscribe to 00311 * receive both CONFIRMED AND UNCONFIRMED messages at 00312 * the same time. 00313 * 00314 * @return It could be one of these: 00315 * i) 0 if there is nothing else to read. 00316 * ii) Number of bytes written to user buffer. 00317 * iii) LORAWAN_STATUS_WOULD_BLOCK if there is 00318 * nothing available to read at the moment. 00319 * iv) A negative error code on failure. 00320 */ 00321 int16_t handle_rx(const uint8_t port, uint8_t* data, 00322 uint16_t length, uint8_t flags); 00323 00324 /** Send Link Check Request MAC command. 00325 * 00326 * 00327 * This API schedules a Link Check Request command (LinkCheckReq) for the network 00328 * server and once the response, i.e., LinkCheckAns MAC command is received 00329 * from the Network Server, an event is generated. 00330 * 00331 * A callback function for the link check response must be set prior to using 00332 * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. 00333 * 00334 * @return LORAWAN_STATUS_OK on successfully queuing a request, or 00335 * a negative error code on failure. 00336 * 00337 */ 00338 lorawan_status_t set_link_check_request(); 00339 00340 /** Shuts down the LoRaWAN protocol. 00341 * 00342 * In response to the user call for disconnection, the stack shuts down itself. 00343 * 00344 * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. 00345 */ 00346 lorawan_status_t shutdown(); 00347 00348 private: 00349 LoRaWANStack(); 00350 ~LoRaWANStack(); 00351 00352 /** 00353 * Checks if the user provided port is valid or not 00354 */ 00355 bool is_port_valid(uint8_t port); 00356 00357 /** 00358 * State machine for stack controller layer. 00359 * Needs to be wriggled for every state change 00360 */ 00361 lorawan_status_t lora_state_machine(); 00362 00363 /** 00364 * Sets the current state of the device. 00365 * Every call to set_device_state() should precede with 00366 * a call to lora_state_machine() in order to take the state change 00367 * in effect. 00368 */ 00369 void set_device_state(device_states_t new_state); 00370 00371 /** 00372 * Hands over the packet to Mac layer by posting an MCPS request. 00373 */ 00374 lorawan_status_t send_frame_to_mac(); 00375 00376 /** 00377 * Callback function for MLME indication. Mac layer calls this function once 00378 * an MLME indication is received. This method translates Mac layer data 00379 * structure into stack layer data structure. 00380 */ 00381 void mlme_indication_handler(loramac_mlme_indication_t *mlmeIndication); 00382 00383 /** 00384 * Handles an MLME request coming from the upper layers and delegates 00385 * it to the Mac layer, for example, a Join request goes as an MLME request 00386 * to the Mac layer. 00387 */ 00388 lorawan_status_t mlme_request_handler(loramac_mlme_req_t *mlme_request); 00389 00390 /** 00391 * Handles an MLME confirmation coming from the Mac layer and uses it to 00392 * update the state for example, a Join Accept triggers an MLME confirmation, 00393 * that eventually comes here and we take necessary steps accordingly. 00394 */ 00395 void mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm); 00396 00397 /** 00398 * Handles an MCPS request while attempting to hand over a packet from 00399 * upper layers to Mac layer. For example in response to send_frame_to_mac(), 00400 * an MCPS request is generated. 00401 */ 00402 lorawan_status_t mcps_request_handler(loramac_mcps_req_t *mcps_request); 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 a MIB request, i.e., update a particular parameter etc. 00422 */ 00423 lorawan_status_t mib_set_request(loramac_mib_req_confirm_t *mib_set_params); 00424 00425 /** 00426 * Requests the MIB to inquire about a particular parameter. 00427 */ 00428 lorawan_status_t mib_get_request(loramac_mib_req_confirm_t *mib_get_params); 00429 00430 /** 00431 * Sets up user application port 00432 */ 00433 lorawan_status_t set_application_port(uint8_t port); 00434 00435 /** 00436 * Helper function to figure out if the user defined data size is possible 00437 * to send or not. The allowed size for transmission depends on the current 00438 * data rate set for the channel. If its not possible to send user defined 00439 * packet size, this method returns the maximum possible size at the moment, 00440 * otherwise the user defined size is returned which means all of user data 00441 * can be sent. 00442 */ 00443 uint16_t check_possible_tx_size(uint16_t size); 00444 00445 private: 00446 00447 LoRaWANTimeHandler _lora_time; 00448 LoRaMac _loramac; 00449 LoRaPHY_region _lora_phy; 00450 loramac_primitives_t LoRaMacPrimitives; 00451 00452 device_states_t _device_current_state; 00453 lorawan_app_callbacks_t _callbacks; 00454 radio_events_t *_mac_handlers; 00455 lorawan_session_t _lw_session; 00456 loramac_tx_message_t _tx_msg; 00457 loramac_rx_message_t _rx_msg; 00458 uint8_t _num_retry; 00459 uint8_t _app_port; 00460 bool _duty_cycle_on; 00461 events::EventQueue *_queue; 00462 00463 #if defined(LORAWAN_COMPLIANCE_TEST) 00464 /** 00465 * This function is used only for compliance testing 00466 */ 00467 void prepare_special_tx_frame(uint8_t port); 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 uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE]; 00480 compliance_test_t _compliance_test; 00481 #endif 00482 }; 00483 00484 #endif /* LORAWANSTACK_H_ */
Generated on Tue Jul 12 2022 11:43:35 by
