Denislam Valeev / Mbed OS Nucleo_rtos_basic
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaWANStack.h Source File

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 &params);
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 &params);
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_ */