BA
/
BaBoRo1
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 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 12:21:59 by
