Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMac.h Source File

LoRaMac.h

Go to the documentation of this file.
00001 /**
00002  * \file      LoRaMac.h
00003  *
00004  * \brief     LoRa MAC 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  LORAMAC LoRa MAC layer implementation
00032  *            This module specifies the API implementation of the LoRaMAC layer.
00033  *            This is a placeholder for a detailed description of the LoRaMac
00034  *            layer and the supported features.
00035  *
00036  * Copyright (c) 2017, Arm Limited and affiliates.
00037  * SPDX-License-Identifier: BSD-3-Clause
00038  *
00039  */
00040 #ifndef MBED_LORAWAN_MAC_H__
00041 #define MBED_LORAWAN_MAC_H__
00042 
00043 #include "events/EventQueue.h"
00044 
00045 #include "lorastack/phy/loraphy_target.h"
00046 #include "lorastack/phy/LoRaPHY.h"
00047 
00048 #include "system/LoRaWANTimer.h"
00049 #include "system/lorawan_data_structures.h"
00050 
00051 #include "LoRaMacChannelPlan.h"
00052 #include "LoRaMacCommand.h"
00053 #include "LoRaMacCrypto.h"
00054 #if MBED_CONF_RTOS_PRESENT
00055 #include "rtos/Mutex.h"
00056 #endif
00057 
00058 #include "platform/ScopedLock.h"
00059 
00060 class LoRaMac {
00061 
00062 public:
00063 
00064     /**
00065      * Constructor
00066      */
00067     LoRaMac();
00068 
00069     /**
00070      * Destructor
00071      */
00072     ~LoRaMac();
00073 
00074     /**
00075      * @brief   LoRaMAC layer initialization
00076      *
00077      * @details Initializes the LoRaMAC layer,
00078      *
00079      *
00080      * @param   queue [in]        A pointer to the application provided EventQueue.
00081      *
00082      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00083      *          \ref LORAWAN_STATUS_OK
00084      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00085      */
00086     lorawan_status_t initialize(events::EventQueue *queue);
00087 
00088     /**
00089      * @brief   Disconnect LoRaMac layer
00090      *
00091      * @details Cancels all outstanding requests and sets LoRaMac's
00092      *          internal state to idle.
00093      */
00094     void disconnect(void);
00095 
00096     /**
00097      * @brief   Queries the LoRaMAC whether it is possible to send the next frame with
00098      *          a given payload size. The LoRaMAC takes the scheduled MAC commands into
00099      *          account and returns corresponding value.
00100      *
00101      * @param   size     [in]    The size of the applicable payload to be sent next.
00102      *
00103      * @return  Size of the biggest packet that can be sent.
00104      *          Please note that if the size of the MAC commands in the queue do
00105      *          not fit into the payload size on the related datarate, the LoRaMAC will
00106      *          omit the MAC commands.
00107      */
00108     uint8_t get_max_possible_tx_size(uint8_t size);
00109 
00110     /**
00111      * @brief nwk_joined Checks if device has joined to network
00112      * @return True if joined to network, false otherwise
00113      */
00114     bool nwk_joined();
00115 
00116     /**
00117      * @brief set_nwk_joined This is used for ABP mode for which real joining does not happen
00118      * @param joined True if device has joined in network, false otherwise
00119      */
00120     void set_nwk_joined(bool joined);
00121 
00122     /**
00123      * @brief   Adds a channel plan to the system.
00124      *
00125      * @details Adds a whole channel plan or a single new channel if the plan
00126      *          contains only one channel and 'plan.nb_channels' is set to 1.
00127      *          Please note that this functionality is not available in all regions.
00128      *          Information on the allowed ranges is available at the
00129      *          LoRaWAN Regional Parameters V1.0.2rB.
00130      *
00131      * @param   plan [in]    A reference to application provided channel plan.
00132      *
00133      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00134      *          \ref LORAWAN_STATUS_OK
00135      *          \ref LORAWAN_STATUS_BUSY
00136      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00137      */
00138     lorawan_status_t add_channel_plan(const lorawan_channelplan_t &plan);
00139 
00140     /**
00141      * @brief   Removes a channel plan from the system.
00142      *
00143      * @details Removes the whole active channel plan except the 'Default Channels'.
00144      *          Please note that this functionality is not available in all regions.
00145      *          Information on the allowed ranges is available at the
00146      *          LoRaWAN Regional Parameters V1.0.2rB.
00147      *
00148      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00149      *          \ref LORAWAN_STATUS_OK
00150      *          \ref LORAWAN_STATUS_BUSY
00151      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00152      */
00153     lorawan_status_t remove_channel_plan();
00154 
00155     /**
00156      * @brief   Access active channel plan.
00157      *
00158      * @details Provides access to the current active channel plan.
00159      *
00160      * @param   plan [out]    A reference to application provided channel plan data
00161      *                        structure which will be filled in with active channel
00162      *                        plan.
00163      *
00164      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00165      *          \ref LORAWAN_STATUS_OK
00166      *          \ref LORAWAN_STATUS_BUSY
00167      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00168      */
00169     lorawan_status_t get_channel_plan(lorawan_channelplan_t &plan);
00170 
00171     /**
00172      * @brief   Remove a given channel from the active plan.
00173      *
00174      * @details Deactivates the given channel.
00175      *
00176      * @param id    Id of the channel.
00177      *
00178      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00179      *          \ref LORAWAN_STATUS_OK
00180      *          \ref LORAWAN_STATUS_BUSY
00181      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00182      */
00183     lorawan_status_t remove_single_channel(uint8_t id);
00184 
00185     /**
00186      * @brief   LoRaMAC multicast channel link service.
00187      *
00188      * @details Links a multicast channel into the linked list.
00189      *
00190      * @param [in] channel_param    The multicast channel parameters to link.
00191      *
00192      * @return  `lorawan_status_t` The  status of the operation. The possible values are:
00193      *          \ref LORAWAN_STATUS_OK
00194      *          \ref LORAWAN_STATUS_BUSY
00195      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00196      */
00197     lorawan_status_t multicast_channel_link(multicast_params_t  *channel_param);
00198 
00199     /**
00200      * @brief   LoRaMAC multicast channel unlink service.
00201      *
00202      * @details Unlinks a multicast channel from the linked list.
00203      *
00204      * @param [in] channel_param    The multicast channel parameters to unlink.
00205      *
00206      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00207      *          \ref LORAWAN_STATUS_OK
00208      *          \ref LORAWAN_STATUS_BUSY
00209      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00210      */
00211     lorawan_status_t multicast_channel_unlink(multicast_params_t  *channel_param);
00212 
00213     /** Binds radio driver to PHY layer.
00214      *
00215      * MAC layer is totally detached from the PHY layer so the stack layer
00216      * needs to play the role of an arbitrator. This API gets a radio driver
00217      * object from the application (via LoRaWANInterface), binds it to the PHY
00218      * layer and initialises radio callback handles which the radio driver will
00219      * use in order to report events.
00220      *
00221      * @param radio            LoRaRadio object, i.e., the radio driver
00222      *
00223      */
00224     void bind_radio_driver(LoRaRadio &radio);
00225 
00226     /**
00227      * @brief Configures the events to trigger an MLME-Indication with
00228      *        a MLME type of MLME_SCHEDULE_UPLINK.
00229      */
00230     void set_mlme_schedule_ul_indication(void);
00231 
00232     /**
00233      * @brief Schedules the frame for sending.
00234      *
00235      * @details Prepares a full MAC frame and schedules it for physical
00236      *          transmission.
00237      *
00238      * @param [in] mac_hdr      MAC frame header field
00239      * @param [in] fport        Payload port
00240      * @param [in] fbuffer      MAC frame data buffer to be sent
00241      * @param [in] fbuffer_size MAC frame data buffer size
00242      *
00243      * @return status          Status of the operation. LORAWAN_STATUS_OK in case
00244      *                         of success and a negative error code in case of
00245      *                         failure.
00246      */
00247     lorawan_status_t send(loramac_mhdr_t  *mac_hdr, const uint8_t fport,
00248                           const void *fbuffer, uint16_t fbuffer_size);
00249 
00250     /**
00251      * @brief Puts the system in continuous transmission mode
00252      *
00253      * @remark Uses the radio parameters set on the previous transmission.
00254      *
00255      * @param [in] timeout    Time in seconds while the radio is kept in continuous wave mode
00256      *
00257      * @return status          Status of the operation. LORAWAN_STATUS_OK in case
00258      *                         of success and a negative error code in case of
00259      *                         failure.
00260      */
00261     lorawan_status_t set_tx_continuous_wave(uint16_t timeout);
00262 
00263     /**
00264      * @brief Puts the system in continuous transmission mode
00265      *
00266      * @param [in] timeout     Time in seconds while the radio is kept in continuous wave mode
00267      * @param [in] frequency   RF frequency to be set.
00268      * @param [in] power       RF output power to be set.
00269      *
00270      * @return status          Status of the operation. LORAWAN_STATUS_OK in case
00271      *                         of success and a negative error code in case of
00272      *                         failure.
00273      */
00274     lorawan_status_t set_tx_continuous_wave1(uint16_t timeout, uint32_t frequency, uint8_t power);
00275 
00276     /**
00277      * @brief Resets MAC specific parameters to default
00278      */
00279     void reset_mac_parameters(void);
00280 
00281     /**
00282      * @brief get_default_tx_datarate Gets the default TX datarate
00283      * @return default TX datarate.
00284      */
00285     uint8_t get_default_tx_datarate();
00286 
00287     /**
00288      * @brief enable_adaptive_datarate Enables or disables adaptive datarate.
00289      * @param adr_enabled Flag indicating is adr enabled or disabled.
00290      */
00291     void enable_adaptive_datarate(bool adr_enabled);
00292 
00293     /** Sets up the data rate.
00294      *
00295      * `set_datarate()` first verifies whether the data rate given is valid or not.
00296      * If it is valid, the system sets the given data rate to the channel.
00297      *
00298      * @param data_rate   The intended data rate, for example DR_0 or DR_1.
00299      *                    Note that the macro DR_* can mean different
00300      *                    things in different regions.
00301      *
00302      * @return            LORAWAN_STATUS_OK if everything goes well, otherwise
00303      *                    a negative error code.
00304      */
00305     lorawan_status_t set_channel_data_rate(uint8_t data_rate);
00306 
00307     /**
00308      * @brief tx_ongoing Check whether a prepare is done or not.
00309      * @return True if prepare_ongoing_tx is called, false otherwise.
00310      */
00311     bool tx_ongoing();
00312 
00313     /**
00314      * @brief set_tx_ongoing Changes the ongoing status for prepared message.
00315      * @param ongoing The value indicating the status.
00316      */
00317     void set_tx_ongoing(bool ongoing);
00318 
00319     /**
00320      * @brief reset_ongoing_tx Resets _ongoing_tx_msg.
00321      * @param reset_pending If true resets pending size also.
00322      */
00323     void reset_ongoing_tx(bool reset_pending = false);
00324 
00325     /**
00326      * @brief prepare_ongoing_tx This will prepare (and override) ongoing_tx_msg.
00327      * @param port The application port number.
00328      * @param data A pointer to the data being sent. The ownership of the
00329      *             buffer is not transferred.
00330      * @param length The size of data in bytes.
00331      * @param flags A flag used to determine what type of
00332      *              message is being sent.
00333      * @param num_retries Number of retries for a confirmed type message
00334      * @return The number of bytes prepared for sending.
00335      */
00336     int16_t prepare_ongoing_tx(const uint8_t port, const uint8_t *data,
00337                                uint16_t length, uint8_t flags, uint8_t num_retries);
00338 
00339     /**
00340      * @brief send_ongoing_tx Sends the ongoing_tx_msg
00341      * @return LORAWAN_STATUS_OK or a negative error code on failure.
00342      */
00343     lorawan_status_t send_ongoing_tx(void);
00344 
00345     /**
00346      * @brief device_class Returns active device class
00347      * @return Device class in use.
00348      */
00349     device_class_t get_device_class() const;
00350 
00351     /**
00352      * @brief set_device_class Sets active device class.
00353      * @param device_class Device class to use.
00354      * @param ack_expiry_handler callback function to inform about ack expiry
00355      */
00356     void set_device_class(const device_class_t &device_class,
00357                           mbed::Callback<void(void)>ack_expiry_handler);
00358 
00359     /**
00360      * @brief opens a continuous RX2 window for Class C devices
00361      */
00362     void open_continuous_rx_window(void);
00363 
00364     /**
00365      * @brief setup_link_check_request Adds link check request command
00366      * to be put on next outgoing message (when it fits)
00367      */
00368     void setup_link_check_request();
00369 
00370     /**
00371      * @brief prepare_join prepares arguments to be ready for join() call.
00372      * @param params Join parameters to use, if NULL, the default will be used.
00373      * @param is_otaa True if joining is to be done using OTAA, false for ABP.
00374      *
00375      * @return LORAWAN_STATUS_OK or a negative error code on failure.
00376      */
00377     lorawan_status_t prepare_join(const lorawan_connect_t *params, bool is_otaa);
00378 
00379     /**
00380      * @brief join Joins the network.
00381      * @param is_otaa True if joining is to be done using OTAA, false for ABP.
00382      * @return LORAWAN_STATUS_OK or a negative error code on failure.
00383      */
00384     lorawan_status_t join(bool is_otaa);
00385 
00386     /**
00387      * MAC operations upon successful transmission
00388      */
00389     void on_radio_tx_done(lorawan_time_t timestamp);
00390 
00391     /**
00392      * MAC operations upon reception
00393      */
00394     void on_radio_rx_done(const uint8_t *const payload, uint16_t size,
00395                           int16_t rssi, int8_t snr);
00396 
00397     /**
00398      * MAC operations upon transmission timeout
00399      */
00400     void on_radio_tx_timeout(void);
00401 
00402     /**
00403      * MAC operations upon empty reception slots
00404      *
00405      * @param is_timeout false when radio encountered an error
00406      *                   true when the an RX slot went empty
00407      *
00408      * @return current RX slot
00409      */
00410     void on_radio_rx_timeout(bool is_timeout);
00411 
00412     /**
00413      * Handles retransmissions of Join requests if an Accept
00414      * was not received.
00415      *
00416      * @returns true if a retry will be made
00417      */
00418     bool continue_joining_process(void);
00419 
00420     /**
00421      * Checks if the CONFIRMED data can be sent again or not.
00422      */
00423     bool continue_sending_process(void);
00424 
00425     /**
00426      * Read-only access to MAC primitive blocks
00427      */
00428     const loramac_mcps_confirm_t  *get_mcps_confirmation() const;
00429     const loramac_mcps_indication_t  *get_mcps_indication() const;
00430     const loramac_mlme_confirm_t  *get_mlme_confirmation() const;
00431     const loramac_mlme_indication_t  *get_mlme_indication() const;
00432 
00433     /**
00434      * Post processing steps in response to actions carried out
00435      * by controller layer and Mac
00436      */
00437     void post_process_mcps_req(void);
00438     void post_process_mcps_ind(void);
00439     void post_process_mlme_request(void);
00440     void post_process_mlme_ind(void);
00441 
00442     /**
00443      * Set battery level query callback
00444      */
00445     void set_batterylevel_callback(mbed::Callback<uint8_t(void)> battery_level);
00446 
00447     /**
00448      * Returns the event ID of backoff timer.
00449      */
00450     int get_backoff_timer_event_id(void);
00451 
00452     /**
00453      * Clears out the TX pipe by discarding any outgoing message if the backoff
00454      * timer is still running.
00455      */
00456     lorawan_status_t clear_tx_pipe(void);
00457 
00458     /**
00459      * Gets the current time
00460      */
00461     lorawan_time_t get_current_time(void);
00462 
00463     /**
00464      * Gets the current receive slot
00465      */
00466     rx_slot_t  get_current_slot(void);
00467 
00468     /**
00469      * These locks trample through to the upper layers and make
00470      * the stack thread safe.
00471      */
00472 #if MBED_CONF_RTOS_PRESENT
00473     void lock(void)
00474     {
00475         osStatus status = _mutex.lock();
00476         MBED_ASSERT(status == osOK);
00477     }
00478     void unlock(void)
00479     {
00480         osStatus status = _mutex.unlock();
00481         MBED_ASSERT(status == osOK);
00482     }
00483 #else
00484     void lock(void) { }
00485     void unlock(void) { }
00486 #endif
00487 
00488 private:
00489     typedef mbed::ScopedLock<LoRaMac> Lock;
00490 #if MBED_CONF_RTOS_PRESENT
00491     rtos::Mutex _mutex;
00492 #endif
00493 
00494     /**
00495      * Handles a Join Accept frame
00496      */
00497     void handle_join_accept_frame(const uint8_t *payload, uint16_t size);
00498 
00499     /**
00500      * Handles data frames
00501      */
00502     void handle_data_frame(const uint8_t *payload,  uint16_t size, uint8_t ptr_pos,
00503                            uint8_t msg_type, int16_t rssi, int8_t snr);
00504 
00505     /**
00506      * Send a Join Request
00507      */
00508     lorawan_status_t send_join_request();
00509 
00510     /**
00511      * Handles retransmissions
00512      */
00513     lorawan_status_t handle_retransmission();
00514 
00515     /**
00516      * Checks if the frame is valid
00517      */
00518     void check_frame_size(uint16_t size);
00519 
00520     /**
00521      * Performs MIC
00522      */
00523     bool message_integrity_check(const uint8_t *payload, uint16_t size,
00524                                  uint8_t *ptr_pos, uint32_t address,
00525                                  uint32_t *downlink_counter, const uint8_t *nwk_skey);
00526 
00527     /**
00528      * Decrypts and extracts data and MAC commands from the received encrypted
00529      * payload
00530      */
00531     void extract_data_and_mac_commands(const uint8_t *payload, uint16_t size,
00532                                        uint8_t fopts_len, uint8_t *nwk_skey,
00533                                        uint8_t *app_skey, uint32_t address,
00534                                        uint32_t downlink_frame_counter,
00535                                        int16_t rssi, int8_t snr);
00536     /**
00537      * Decrypts and extracts MAC commands from the received encrypted
00538      * payload if there is no data
00539      */
00540     void extract_mac_commands_only(const uint8_t *payload, int8_t snr, uint8_t fopts_len);
00541 
00542     /**
00543      * Callback function to be executed when the DC backoff timer expires
00544      */
00545     void on_backoff_timer_expiry(void);
00546 
00547     /**
00548      * At the end of an RX1 window timer, an RX1 window is opened using this method.
00549      */
00550     void open_rx1_window(void);
00551 
00552     /**
00553      * At the end of an RX2 window timer, an RX2 window is opened using this method.
00554      */
00555     void open_rx2_window(void);
00556 
00557     /**
00558      * A method to retry a CONFIRMED message after a particular time period
00559      * (ACK_TIMEOUT = TIME_IN_MS) if the ack was not received
00560      */
00561     void on_ack_timeout_timer_event(void);
00562 
00563     /*!
00564      * \brief Check if the OnAckTimeoutTimer has do be disabled. If so, the
00565      *        function disables it.
00566      *
00567      * \param [in] node_ack_requested Set to true, if the node has requested an ACK
00568      * \param [in] dev_class The device class
00569      * \param [in] ack_received Set to true, if the node has received an ACK
00570      * \param [in] ack_timeout_retries_counter Retries counter for confirmed uplinks
00571      * \param [in] ack_timeout_retries Maximum retries for confirmed uplinks
00572      */
00573     void check_to_disable_ack_timeout(bool node_ack_requested,
00574                                       device_class_t dev_class,
00575                                       bool ack_received,
00576                                       uint8_t ack_timeout_retries_counter,
00577                                       uint8_t ack_timeout_retries);
00578 
00579     /**
00580      * Validates if the payload fits into the frame, taking the datarate
00581      * into account.
00582      *
00583      * Please Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0.2
00584      */
00585     bool validate_payload_length(uint16_t length, int8_t datarate, uint8_t fopts_len);
00586 
00587     /**
00588      * Prepares MAC frame on the behest of send() API.
00589      */
00590     lorawan_status_t prepare_frame(loramac_mhdr_t  *mac_hdr,
00591                                    loramac_frame_ctrl_t  *fctrl, const uint8_t fport,
00592                                    const void *fbuffer, uint16_t fbuffer_size);
00593 
00594     /**
00595      * Schedules a transmission on the behest of send() API.
00596      */
00597     lorawan_status_t schedule_tx();
00598 
00599     /**
00600      * Calculates the back-off time for the band of a channel.
00601      * Takes in the last used channel id as a parameter.
00602      */
00603     void calculate_backOff(uint8_t channel_id);
00604 
00605     /**
00606      * Hands over the MAC frame to PHY layer.
00607      */
00608     lorawan_status_t send_frame_on_channel(uint8_t channel);
00609 
00610     /**
00611      * Resets MAC primitive blocks
00612      */
00613     void reset_mcps_confirmation(void);
00614     void reset_mlme_confirmation(void);
00615     void reset_mcps_indication(void);
00616 
00617     /**
00618      * @brief set_tx_continuous_wave Puts the system in continuous transmission mode
00619      * @param [in] channel A Channel to use
00620      * @param [in] datarate A datarate to use
00621      * @param [in] tx_power A RF output power to use
00622      * @param [in] max_eirp A maximum possible EIRP to use
00623      * @param [in] antenna_gain Antenna gain to use
00624      * @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
00625      */
00626     void set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power,
00627                                 float max_eirp, float antenna_gain, uint16_t timeout);
00628 
00629 private:
00630     /**
00631      * Timer subsystem handle
00632      */
00633     LoRaWANTimeHandler _lora_time;
00634 
00635     /**
00636      * LoRa PHY layer object storage
00637      */
00638     LoRaPHY_region _lora_phy;
00639 
00640     /**
00641      * MAC command handle
00642      */
00643     LoRaMacCommand _mac_commands;
00644 
00645     /**
00646      * Channel planning subsystem
00647      */
00648     LoRaMacChannelPlan _channel_plan;
00649 
00650     /**
00651      * Crypto handling subsystem
00652      */
00653     LoRaMacCrypto _lora_crypto;
00654 
00655     /**
00656      * Central MAC layer data storage
00657      */
00658     loramac_protocol_params _params;
00659 
00660     /**
00661      * EventQueue object storage
00662      */
00663     events::EventQueue *_ev_queue;
00664 
00665     /**
00666      * Class C doesn't timeout in RX2 window as it is a continuous window.
00667      * We use this callback to inform the LoRaWANStack controller that the
00668      * system cannot do more retries.
00669      */
00670     mbed::Callback<void(void)> _ack_expiry_handler_for_class_c;
00671 
00672     /**
00673      * Structure to hold MCPS indication data.
00674      */
00675     loramac_mcps_indication_t  _mcps_indication;
00676 
00677     /**
00678      * Structure to hold MCPS confirm data.
00679      */
00680     loramac_mcps_confirm_t  _mcps_confirmation;
00681 
00682     /**
00683      * Structure to hold MLME indication data.
00684      */
00685     loramac_mlme_indication_t  _mlme_indication;
00686 
00687     /**
00688      * Structure to hold MLME confirm data.
00689      */
00690     loramac_mlme_confirm_t  _mlme_confirmation;
00691 
00692     loramac_tx_message_t _ongoing_tx_msg;
00693 
00694     bool _is_nwk_joined;
00695 
00696     bool _continuous_rx2_window_open;
00697 
00698     device_class_t _device_class;
00699 
00700 #if defined(LORAWAN_COMPLIANCE_TEST)
00701 public: // Test interface
00702 
00703     /**
00704      * @brief   Set forth an MLME request.
00705      *
00706      * @details The MAC layer management entity handles the management services.
00707      *
00708      * @param [in] request    The MLME request to perform.
00709      *                        Refer to \ref loramac_mlme_req_t.
00710      *
00711      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00712      *          \ref LORAWAN_STATUS_OK
00713      *          \ref LORAWAN_STATUS_BUSY
00714      *          \ref LORAWAN_STATUS_SERVICE_UNKNOWN
00715      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00716      *          \ref LORAWAN_STATUS_NO_NETWORK_JOINED
00717      *          \ref LORAWAN_STATUS_LENGTH_ERROR
00718      *          \ref LORAWAN_STATUS_DEVICE_OFF
00719      */
00720     lorawan_status_t mlme_request(loramac_mlme_req_t *request);
00721 
00722     /**
00723      * @brief   Set forth an MCPS request.
00724      *
00725      * @details The MAC Common Part Sublayer handles the data services. The following
00726      *          code-snippet shows how to use the API to send an unconfirmed
00727      *          LoRaMAC frame.
00728      *
00729      * @code
00730      *
00731      * uint8_t buffer[] = {1, 2, 3};
00732      *
00733      * loramac_compliance_test_req_t request;
00734      * request.type = MCPS_UNCONFIRMED;
00735      * request.fport = 1;
00736      * request.f_buffer = buffer;
00737      * request.f_buffer_size = sizeof(buffer);
00738      *
00739      * if (test_request(&request) == LORAWAN_STATUS_OK) {
00740      *   // Service started successfully. Waiting for the MCPS-Confirm event
00741      * }
00742      *
00743      * @endcode
00744      *
00745      * @param [in] request    The test request to perform.
00746      *                        Refer to \ref loramac_compliance_test_req_t.
00747      *
00748      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00749      *          \ref LORAWAN_STATUS_OK
00750      *          \ref LORAWAN_STATUS_BUSY
00751      *          \ref LORAWAN_STATUS_SERVICE_UNKNOWN
00752      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00753      *          \ref LORAWAN_STATUS_NO_NETWORK_JOINED
00754      *          \ref LORAWAN_STATUS_LENGTH_ERROR
00755      *          \ref LORAWAN_STATUS_DEVICE_OFF
00756      */
00757     lorawan_status_t test_request(loramac_compliance_test_req_t *request);
00758 
00759     /**
00760      * \brief   LoRaMAC set tx timer.
00761      *
00762      * \details Sets up a timer for next transmission (application specific timers).
00763      *
00764      * \param   [in] NextTxTime - Periodic time for next uplink.
00765 
00766      * \retval  `lorawan_status_t` The status of the operation. The possible values are:
00767      *          \ref LORAWAN_STATUS_OK
00768      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00769      */
00770     lorawan_status_t LoRaMacSetTxTimer(uint32_t NextTxTime);
00771 
00772     /**
00773      * \brief   LoRaMAC stop tx timer.
00774      *
00775      * \details Stops the next tx timer.
00776      *
00777      * \retval  `lorawan_status_t` The status of the operation. The possible values are:
00778      *          \ref LORAWAN_STATUS_OK
00779      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00780      */
00781     lorawan_status_t LoRaMacStopTxTimer();
00782 
00783     /**
00784      * \brief   Enabled or disables the reception windows
00785      *
00786      * \details This is a test function. It shall be used for testing purposes only.
00787      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00788      *
00789      * \param   [in] enable - Enabled or disables the reception windows
00790      */
00791     void LoRaMacTestRxWindowsOn(bool enable);
00792 
00793     /**
00794      * \brief   Enables the MIC field test
00795      *
00796      * \details This is a test function. It shall be used for testing purposes only.
00797      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00798      *
00799      * \param   [in] txPacketCounter - Fixed Tx packet counter value
00800      */
00801     void LoRaMacTestSetMic(uint16_t txPacketCounter);
00802 
00803     /**
00804      * \brief   Enabled or disables the duty cycle
00805      *
00806      * \details This is a test function. It shall be used for testing purposes only.
00807      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00808      *
00809      * \param   [in] enable - Enabled or disables the duty cycle
00810      */
00811     void LoRaMacTestSetDutyCycleOn(bool enable);
00812 
00813     /**
00814      * \brief   Sets the channel index
00815      *
00816      * \details This is a test function. It shall be used for testing purposes only.
00817      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00818      *
00819      * \param   [in] channel - Channel index
00820      */
00821     void LoRaMacTestSetChannel(uint8_t channel);
00822 
00823 private:
00824     /**
00825      * Timer to handle the application data transmission duty cycle
00826      */
00827     timer_event_t tx_next_packet_timer;
00828 #endif
00829 };
00830 
00831 #endif // MBED_LORAWAN_MAC_H__