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