Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaWANStack.h Source File

LoRaWANStack.h

Go to the documentation of this file.
00001 /**
00002  * \file      LoRaWANStack.h
00003  *
00004  * \brief     LoRaWAN stack layer implementation
00005  *
00006  * \copyright Revised BSD License, see LICENSE.TXT file include in the project
00007  *
00008  * \code
00009  *                ______                              _
00010  *               / _____)             _              | |
00011  *              ( (____  _____ ____ _| |_ _____  ____| |__
00012  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00013  *               _____) ) ____| | | || |_| ____( (___| | | |
00014  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
00015  *              (C)2013 Semtech
00016  *
00017  *               ___ _____ _   ___ _  _____ ___  ___  ___ ___
00018  *              / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
00019  *              \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
00020  *              |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
00021  *              embedded.connectivity.solutions===============
00022  *
00023  * \endcode
00024  *
00025  * \author    Miguel Luis ( Semtech )
00026  *
00027  * \author    Gregory Cristian ( Semtech )
00028  *
00029  * \author    Daniel Jaeckle ( STACKFORCE )
00030  *
00031  * \defgroup  LoRaWAN stack layer that controls MAC layer underneath
00032  *
00033  * License: Revised BSD License, see LICENSE.TXT file include in the project
00034  *
00035  * Copyright (c) 2017, Arm Limited and affiliates.
00036  *
00037  * SPDX-License-Identifier: BSD-3-Clause
00038  */
00039 
00040 #ifndef LORAWANSTACK_H_
00041 #define LORAWANSTACK_H_
00042 
00043 #include <stdint.h>
00044 #include "events/EventQueue.h"
00045 #include "platform/mbed_atomic.h"
00046 #include "platform/Callback.h"
00047 #include "platform/NonCopyable.h"
00048 #include "platform/ScopedLock.h"
00049 
00050 #include "lorastack/mac/LoRaMac.h"
00051 #include "system/LoRaWANTimer.h"
00052 #include "system/lorawan_data_structures.h"
00053 #include "LoRaRadio.h"
00054 
00055 class LoRaPHY;
00056 
00057 /** LoRaWANStack Class
00058  * A controller layer for LoRaWAN MAC and PHY
00059  */
00060 class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
00061 
00062 public:
00063     LoRaWANStack();
00064 
00065     /** Binds PHY layer and radio driver to stack.
00066      *
00067      * MAC layer is totally detached from the PHY layer so the stack layer
00068      * needs to play the role of an arbitrator.
00069      * This API sets the PHY layer object to stack and bind the radio driver
00070      * object from the application to the PHY layer.
00071      * Also initialises radio callback handles which the radio driver will
00072      * use in order to report events.
00073      *
00074      * @param radio            LoRaRadio object, i.e., the radio driver
00075      * @param phy              LoRaPHY object.
00076      *
00077      */
00078     void bind_phy_and_radio_driver(LoRaRadio &radio, LoRaPHY &phy);
00079 
00080     /** End device initialization.
00081      * @param queue            A pointer to an EventQueue passed from the application.
00082      * @return                 LORAWAN_STATUS_OK on success, a negative error code on failure.
00083      */
00084     lorawan_status_t initialize_mac_layer(events::EventQueue *queue);
00085 
00086     /** Sets all callbacks for the application.
00087      *
00088      * @param callbacks        A pointer to the structure carrying callbacks.
00089      * @return                 LORAWAN_STATUS_OK on success, a negative error code on failure.
00090      */
00091     lorawan_status_t set_lora_callbacks(const lorawan_app_callbacks_t *callbacks);
00092 
00093     /** Connect OTAA or ABP using Mbed-OS config system
00094      *
00095      * @return    For ABP:  If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
00096      *                      a 'CONNECTED' event. Otherwise a negative error code is returned.
00097      *                      Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
00098      *
00099      *            For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
00100      *                      Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
00101      *                      is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
00102      *                      A 'CONNECTED' event is sent to the application when the JoinAccept is received.
00103      */
00104     lorawan_status_t connect();
00105 
00106     /** Connect OTAA or ABP with parameters
00107      *
00108      * @param connect  Options for an end device connection to the gateway.
00109      *
00110      * @return    For ABP:  If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by
00111      *                      a 'CONNECTED' event. Otherwise a negative error code is returned.
00112      *                      Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows.
00113      *
00114      *            For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call.
00115      *                      Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection
00116      *                      is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully).
00117      *                      A 'CONNECTED' event is sent to the application when the JoinAccept is received.
00118      */
00119     lorawan_status_t connect(const lorawan_connect_t &connect);
00120 
00121     /** Adds channels to use.
00122      *
00123      * You can provide a list of channels with appropriate parameters filled
00124      * in. However, this list is not absolute. In some regions, a CF
00125      * list gets implemented by default, which means that the network can overwrite your channel
00126      * frequency settings right after receiving a Join Accept. You may try
00127      * to set up any channel or channels after that and if the channel requested
00128      * is already active, the request is silently ignored. A negative error
00129      * code is returned if there is any problem with parameters.
00130      *
00131      * You need to ensure that the base station nearby supports the channel or channels being added.
00132      *
00133      * If your list includes a default channel (a channel where Join Requests
00134      * are received) you cannot fully configure the channel parameters.
00135      * Either leave the channel settings to default or check your
00136      * corresponding PHY layer implementation. For example, LoRaPHYE868.
00137      *
00138      * @param  channel_plan     A list of channels or a single channel.
00139      *
00140      * @return                  LORAWAN_STATUS_OK on success, a negative error
00141      *                          code on failure.
00142      */
00143     lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan);
00144 
00145     /** Removes a channel from the list.
00146      *
00147      * @param channel_id        Index of the channel being removed
00148      *
00149      * @return                  LORAWAN_STATUS_OK on success, a negative error
00150      *                          code on failure.
00151      */
00152     lorawan_status_t remove_a_channel(uint8_t channel_id);
00153 
00154     /** Removes a previously set channel plan.
00155      *
00156      * @return                  LORAWAN_STATUS_OK on success, a negative error
00157      *                          code on failure.
00158      */
00159     lorawan_status_t drop_channel_list();
00160 
00161     /** Gets a list of currently enabled channels .
00162      *
00163      * @param channel_plan      The channel plan structure to store final result.
00164      *
00165      * @return                  LORAWAN_STATUS_OK on success, a negative error
00166      *                          code on failure.
00167      */
00168     lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan);
00169 
00170     /** Sets up a retry counter for confirmed messages.
00171      *
00172      * Valid only for confirmed messages. This API sets the number of times the
00173      * stack will retry a CONFIRMED message before giving up and reporting an
00174      * error.
00175      *
00176      * @param count             The number of retries for confirmed messages.
00177      *
00178      * @return                  LORAWAN_STATUS_OK or a negative error code.
00179      */
00180     lorawan_status_t set_confirmed_msg_retry(uint8_t count);
00181 
00182     /** Sets up the data rate.
00183      *
00184      * `set_datarate()` first verifies whether the data rate given is valid or not.
00185      * If it is valid, the system sets the given data rate to the channel.
00186      *
00187      * @param data_rate   The intended data rate, for example DR_0 or DR_1.
00188      *                    Note that the macro DR_* can mean different
00189      *                    things in different regions.
00190      *
00191      * @return            LORAWAN_STATUS_OK if everything goes well, otherwise
00192      *                    a negative error code.
00193      */
00194     lorawan_status_t set_channel_data_rate(uint8_t data_rate);
00195 
00196     /** Enables ADR.
00197      *
00198      * @param adr_enabled       0 ADR disabled, 1 ADR enabled.
00199      *
00200      * @return                  LORAWAN_STATUS_OK on success, a negative error
00201      *                          code on failure.
00202      */
00203     lorawan_status_t enable_adaptive_datarate(bool adr_enabled);
00204 
00205     /** Send message to gateway
00206      *
00207      * @param port              The application port number. Port numbers 0 and 224
00208      *                          are reserved, whereas port numbers from 1 to 223
00209      *                          (0x01 to 0xDF) are valid port numbers.
00210      *                          Anything out of this range is illegal.
00211      *
00212      * @param data              A pointer to the data being sent. The ownership of the
00213      *                          buffer is not transferred. The data is copied to the
00214      *                          internal buffers.
00215      *
00216      * @param length            The size of data in bytes.
00217      *
00218      * @param flags             A flag used to determine what type of
00219      *                          message is being sent, for example:
00220      *
00221      *                          MSG_UNCONFIRMED_FLAG = 0x01
00222      *                          MSG_CONFIRMED_FLAG = 0x02
00223      *                          MSG_MULTICAST_FLAG = 0x04
00224      *                          MSG_PROPRIETARY_FLAG = 0x08
00225      *                          MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be
00226      *                          used in conjunction with MSG_UNCONFIRMED_FLAG and
00227      *                          MSG_CONFIRMED_FLAG depending on the intended use.
00228      *
00229      *                          MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set
00230      *                          a confirmed message flag for a proprietary message.
00231      *                          MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
00232      *                          mutually exclusive.
00233      *
00234      * @param null_allowed      Internal use only. Needed for sending empty packet
00235      *                          having CONFIRMED bit on.
00236      *
00237      * @param allow_port_0      Internal use only. Needed for flushing MAC commands.
00238      *
00239      * @return                  The number of bytes sent, or
00240      *                          LORAWAN_STATUS_WOULD_BLOCK if another TX is
00241      *                          ongoing, or a negative error code on failure.
00242      */
00243     int16_t handle_tx(uint8_t port, const uint8_t *data,
00244                       uint16_t length, uint8_t flags,
00245                       bool null_allowed = false, bool allow_port_0 = false);
00246 
00247     /** Receives a message from the Network Server.
00248      *
00249      * @param data              A pointer to buffer where the received data will be
00250      *                          stored.
00251      *
00252      * @param length            The size of data in bytes
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      *                          In return will contain the number of port to which
00260      *                          message was received.
00261      *
00262      * @param flags             A flag is used to determine what type of
00263      *                          message is being received, for example:
00264      *
00265      *                          MSG_UNCONFIRMED_FLAG = 0x01,
00266      *                          MSG_CONFIRMED_FLAG = 0x02
00267      *                          MSG_MULTICAST_FLAG = 0x04,
00268      *                          MSG_PROPRIETARY_FLAG = 0x08
00269      *
00270      *                          MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be
00271      *                          used in conjunction with MSG_UNCONFIRMED_FLAG and
00272      *                          MSG_CONFIRMED_FLAG depending on the intended use.
00273      *
00274      *                          MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set
00275      *                          a confirmed message flag for a proprietary message.
00276      *
00277      *                          MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
00278      *                          not mutually exclusive, i.e., the user can subscribe to
00279      *                          receive both CONFIRMED AND UNCONFIRMED messages at
00280      *                          the same time.
00281      *
00282      *                          In return will contain the flags to determine what kind
00283      *                          of message was received.
00284      *
00285      * @param validate_params   If set to true, the given port and flags values will be checked
00286      *                          against the values received with the message. If values do not
00287      *                          match, LORAWAN_STATUS_WOULD_BLOCK will be returned.
00288      *
00289      * @return                  It could be one of these:
00290      *                             i)   0 if there is nothing else to read.
00291      *                             ii)  Number of bytes written to user buffer.
00292      *                             iii) LORAWAN_STATUS_WOULD_BLOCK if there is
00293      *                                  nothing available to read at the moment.
00294      *                             iv)  A negative error code on failure.
00295      */
00296     int16_t handle_rx(uint8_t *data, uint16_t length, uint8_t &port, int &flags, bool validate_params);
00297 
00298     /** Send Link Check Request MAC command.
00299      *
00300      *
00301      * This API schedules a Link Check Request command (LinkCheckReq) for the network
00302      * server and once the response, i.e., LinkCheckAns MAC command is received
00303      * from the Network Server, an event is generated.
00304      *
00305      * A callback function for the link check response must be set prior to using
00306      * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown.
00307      *
00308      * @return          LORAWAN_STATUS_OK on successfully queuing a request, or
00309      *                  a negative error code on failure.
00310      *
00311      */
00312     lorawan_status_t set_link_check_request();
00313 
00314     /** Removes link check request sticky MAC command.
00315      *
00316      * Any already queued request may still get entertained. However, no new
00317      * requests will be made.
00318      */
00319     void remove_link_check_request();
00320 
00321     /** Shuts down the LoRaWAN protocol.
00322      *
00323      * In response to the user call for disconnection, the stack shuts down itself.
00324      *
00325      * @return          LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
00326      */
00327     lorawan_status_t shutdown();
00328 
00329     /** Change device class
00330      *
00331      * Change current device class.
00332      *
00333      * @param    device_class   The device class
00334      *
00335      * @return                  LORAWAN_STATUS_OK on success,
00336      *                          LORAWAN_STATUS_UNSUPPORTED is requested class is not supported,
00337      *                          or other negative error code if request failed.
00338      */
00339     lorawan_status_t set_device_class(const device_class_t &device_class);
00340 
00341     /** Acquire TX meta-data
00342      *
00343      * Upon successful transmission, TX meta-data will be made available
00344      *
00345      * @param    metadata    A reference to the inbound structure which will be
00346      *                       filled with any TX meta-data if available.
00347      *
00348      * @return               LORAWAN_STATUS_OK if successful,
00349      *                       LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise
00350      */
00351     lorawan_status_t acquire_tx_metadata(lorawan_tx_metadata &metadata);
00352 
00353     /** Acquire RX meta-data
00354      *
00355      * Upon successful reception, RX meta-data will be made available
00356      *
00357      * @param    metadata    A reference to the inbound structure which will be
00358      *                       filled with any RX meta-data if available.
00359      *
00360      * @return               LORAWAN_STATUS_OK if successful,
00361      *                       LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise
00362      */
00363     lorawan_status_t acquire_rx_metadata(lorawan_rx_metadata &metadata);
00364 
00365     /** Acquire backoff meta-data
00366      *
00367      * Get hold of backoff time after which the transmission will take place.
00368      *
00369      * @param    backoff     A reference to the inbound integer which will be
00370      *                       filled with any backoff meta-data if available.
00371      *
00372      * @return               LORAWAN_STATUS_OK if successful,
00373      *                       LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise
00374      */
00375     lorawan_status_t acquire_backoff_metadata(int &backoff);
00376 
00377     /** Stops sending
00378      *
00379      * Stop sending any outstanding messages if they are not yet queued for
00380      * transmission, i.e., if the backoff timer is nhot elapsed yet.
00381      *
00382      * @return               LORAWAN_STATUS_OK if the transmission is cancelled.
00383      *                       LORAWAN_STATUS_BUSY otherwise.
00384      */
00385     lorawan_status_t stop_sending(void);
00386 
00387     void lock(void)
00388     {
00389         _loramac.lock();
00390     }
00391     void unlock(void)
00392     {
00393         _loramac.unlock();
00394     }
00395 
00396 private:
00397     typedef mbed::ScopedLock<LoRaWANStack> Lock;
00398     /**
00399      * Checks if the user provided port is valid or not
00400      */
00401     bool is_port_valid(uint8_t port, bool allow_port_0 = false);
00402 
00403     /**
00404      * State machine for stack controller layer.
00405      */
00406     lorawan_status_t state_controller(device_states_t new_state);
00407 
00408     /**
00409      * Helpers for state controller
00410      */
00411     void process_uninitialized_state(lorawan_status_t &op_status);
00412     void process_idle_state(lorawan_status_t &op_status);
00413     void process_connected_state();
00414     void process_connecting_state(lorawan_status_t &op_status);
00415     void process_joining_state(lorawan_status_t &op_status);
00416     void process_scheduling_state(lorawan_status_t &op_status);
00417     void process_status_check_state();
00418     void process_shutdown_state(lorawan_status_t &op_status);
00419     void state_machine_run_to_completion(void);
00420 
00421     /**
00422      * Handles MLME indications
00423      */
00424     void mlme_indication_handler(void);
00425 
00426     /**
00427      * Handles an MLME confirmation
00428      */
00429     void mlme_confirm_handler(void);
00430 
00431     /**
00432      * Handles an MCPS confirmation
00433      */
00434     void mcps_confirm_handler(void);
00435 
00436     /**
00437      * Handles an MCPS indication
00438      */
00439     void mcps_indication_handler(void);
00440 
00441     /**
00442      * Sets up user application port
00443      */
00444     lorawan_status_t set_application_port(uint8_t port, bool allow_port_0 = false);
00445 
00446     /**
00447      * Handles connection internally
00448      */
00449     lorawan_status_t handle_connect(bool is_otaa);
00450 
00451 
00452     /** Send event to application.
00453      *
00454      * @param  event            The event to be sent.
00455      */
00456     void send_event_to_application(const lorawan_event_t event) const;
00457 
00458     /** Send empty uplink message to network.
00459      *
00460      * Sends an empty confirmed message to gateway.
00461      *
00462      * @param  port            The event to be sent.
00463      */
00464     void send_automatic_uplink_message(uint8_t port);
00465 
00466     /**
00467      * TX interrupt handlers and corresponding processors
00468      */
00469     void tx_interrupt_handler(void);
00470     void tx_timeout_interrupt_handler(void);
00471     void process_transmission(void);
00472     void process_transmission_timeout(void);
00473 
00474     /**
00475      * RX interrupt handlers and corresponding processors
00476      */
00477     void rx_interrupt_handler(const uint8_t *payload, uint16_t size, int16_t rssi,
00478                               int8_t snr);
00479     void rx_timeout_interrupt_handler(void);
00480     void rx_error_interrupt_handler(void);
00481     void process_reception(const uint8_t *payload, uint16_t size, int16_t rssi,
00482                            int8_t snr);
00483     void process_reception_timeout(bool is_timeout);
00484 
00485     int convert_to_msg_flag(const mcps_type_t type);
00486 
00487     void make_tx_metadata_available(void);
00488     void make_rx_metadata_available(void);
00489 
00490     void handle_scheduling_failure(void);
00491 
00492     void post_process_tx_with_reception(void);
00493     void post_process_tx_no_reception(void);
00494 
00495 private:
00496     LoRaMac _loramac;
00497     radio_events_t radio_events;
00498     device_states_t _device_current_state;
00499     lorawan_app_callbacks_t _callbacks;
00500     lorawan_session_t _lw_session;
00501     loramac_tx_message_t _tx_msg;
00502     loramac_rx_message_t _rx_msg;
00503     lorawan_tx_metadata _tx_metadata;
00504     lorawan_rx_metadata _rx_metadata;
00505     uint8_t _num_retry;
00506     uint8_t _qos_cnt;
00507     uint32_t _ctrl_flags;
00508     uint8_t _app_port;
00509     bool _link_check_requested;
00510     bool _automatic_uplink_ongoing;
00511     core_util_atomic_flag _rx_payload_in_use;
00512     uint8_t _rx_payload[LORAMAC_PHY_MAXPAYLOAD];
00513     events::EventQueue *_queue;
00514     lorawan_time_t _tx_timestamp;
00515 };
00516 
00517 #endif /* LORAWANSTACK_H_ */