Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

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