Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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