Nicolas Borla / Mbed OS BBR_1Ebene
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      */
00355     void set_device_class(const device_class_t& device_class);
00356 
00357     /**
00358      * @brief opens a continuous RX2 window for Class C devices
00359      */
00360     void open_continuous_rx_window(void);
00361 
00362     /**
00363      * @brief setup_link_check_request Adds link check request command
00364      * to be put on next outgoing message (when it fits)
00365      */
00366     void setup_link_check_request();
00367 
00368     /**
00369      * @brief prepare_join prepares arguments to be ready for join() call.
00370      * @param params Join parameters to use, if NULL, the default will be used.
00371      * @param is_otaa True if joining is to be done using OTAA, false for ABP.
00372      *
00373      * @return LORAWAN_STATUS_OK or a negative error code on failure.
00374      */
00375     lorawan_status_t prepare_join(const lorawan_connect_t *params, bool is_otaa);
00376 
00377     /**
00378      * @brief join Joins the network.
00379      * @param is_otaa True if joining is to be done using OTAA, false for ABP.
00380      * @return LORAWAN_STATUS_OK or a negative error code on failure.
00381      */
00382     lorawan_status_t join(bool is_otaa);
00383 
00384     /**
00385      * MAC operations upon successful transmission
00386      */
00387     void on_radio_tx_done(void);
00388 
00389     /**
00390      * MAC operations upon reception
00391      */
00392     void on_radio_rx_done(const uint8_t* const payload, uint16_t size,
00393                           int16_t rssi, int8_t snr);
00394 
00395     /**
00396      * MAC operations upon transmission timeout
00397      */
00398     void on_radio_tx_timeout(void);
00399 
00400     /**
00401      * MAC operations upon empty reception slots
00402      *
00403      * @param is_timeout false when radio encountered an error
00404      *                   true when the an RX slot went empty
00405      *
00406      * @return current RX slot
00407      */
00408     rx_slot_t  on_radio_rx_timeout(bool is_timeout);
00409 
00410     /**
00411      * Handles retransmissions of Join requests if an Accept
00412      * was not received.
00413      *
00414      * @returns true if a retry will be made
00415      */
00416     bool continue_joining_process(void);
00417 
00418     /**
00419      * Checks if the CONFIRMED data can be sent again or not.
00420      */
00421     bool continue_sending_process(void);
00422 
00423     /**
00424      * Read-only access to MAC primitive blocks
00425      */
00426     const loramac_mcps_confirm_t  *get_mcps_confirmation() const;
00427     const loramac_mcps_indication_t  *get_mcps_indication() const;
00428     const loramac_mlme_confirm_t  *get_mlme_confirmation() const;
00429     const loramac_mlme_indication_t  *get_mlme_indication() const;
00430 
00431     /**
00432      * Post processing steps in response to actions carried out
00433      * by controller layer and Mac
00434      */
00435     void post_process_mcps_req(void);
00436     void post_process_mcps_ind(void);
00437     void post_process_mlme_request(void);
00438     void post_process_mlme_ind(void);
00439 
00440     /**
00441      * These locks trample through to the upper layers and make
00442      * the stack thread safe.
00443      */
00444 #if MBED_CONF_RTOS_PRESENT
00445     void lock(void) { osStatus status = _mutex.lock(); MBED_ASSERT(status == osOK); }
00446     void unlock(void) { osStatus status = _mutex.unlock(); MBED_ASSERT(status == osOK); }
00447 #else
00448     void lock(void) { }
00449     void unlock(void) { }
00450 #endif
00451 
00452 private:
00453     typedef mbed::ScopedLock<LoRaMac> Lock;
00454 #if MBED_CONF_RTOS_PRESENT
00455     rtos::Mutex _mutex;
00456 #endif
00457 
00458     /**
00459      * Aborts reception
00460      */
00461     void abort_rx(void);
00462 
00463     /**
00464      * Handles a Join Accept frame
00465      */
00466     void handle_join_accept_frame(const uint8_t *payload, uint16_t size);
00467 
00468     /**
00469      * Handles data frames
00470      */
00471     void handle_data_frame(const uint8_t *payload,  uint16_t size, uint8_t ptr_pos,
00472                            uint8_t msg_type, int16_t rssi, int8_t snr);
00473 
00474     /**
00475      * Send a Join Request
00476      */
00477     lorawan_status_t send_join_request();
00478 
00479     /**
00480      * Handles retransmissions
00481      */
00482     lorawan_status_t handle_retransmission();
00483 
00484     /**
00485      * Checks if the frame is valid
00486      */
00487     void check_frame_size(uint16_t size);
00488 
00489     /**
00490      * Performs MIC
00491      */
00492     bool message_integrity_check(const uint8_t *payload, uint16_t size,
00493                                  uint8_t *ptr_pos, uint32_t address,
00494                                  uint32_t *downlink_counter, const uint8_t *nwk_skey);
00495 
00496     /**
00497      * Decrypts and extracts data and MAC commands from the received encrypted
00498      * payload
00499      */
00500     void extract_data_and_mac_commands(const uint8_t *payload, uint16_t size,
00501                                       uint8_t fopts_len, uint8_t *nwk_skey,
00502                                       uint8_t *app_skey, uint32_t address,
00503                                       uint32_t downlink_frame_counter,
00504                                       int16_t rssi, int8_t snr);
00505     /**
00506      * Decrypts and extracts MAC commands from the received encrypted
00507      * payload if there is no data
00508      */
00509     void extract_mac_commands_only(const uint8_t *payload, int8_t snr, uint8_t fopts_len);
00510 
00511     /**
00512      * Callback function to be executed when the DC backoff timer expires
00513      */
00514     void on_backoff_timer_expiry(void);
00515 
00516     /**
00517      * At the end of an RX1 window timer, an RX1 window is opened using this method.
00518      */
00519     void open_rx1_window(void);
00520 
00521     /**
00522      * At the end of an RX2 window timer, an RX2 window is opened using this method.
00523      */
00524     void open_rx2_window(void);
00525 
00526     /**
00527      * A method to retry a CONFIRMED message after a particular time period
00528      * (ACK_TIMEOUT = TIME_IN_MS) if the ack was not received
00529      */
00530     void on_ack_timeout_timer_event(void);
00531 
00532     /*!
00533      * \brief Check if the OnAckTimeoutTimer has do be disabled. If so, the
00534      *        function disables it.
00535      *
00536      * \param [in] node_ack_requested Set to true, if the node has requested an ACK
00537      * \param [in] dev_class The device class
00538      * \param [in] ack_received Set to true, if the node has received an ACK
00539      * \param [in] ack_timeout_retries_counter Retries counter for confirmed uplinks
00540      * \param [in] ack_timeout_retries Maximum retries for confirmed uplinks
00541      */
00542     void check_to_disable_ack_timeout(bool node_ack_requested,
00543                                       device_class_t dev_class,
00544                                       bool ack_received,
00545                                       uint8_t ack_timeout_retries_counter,
00546                                       uint8_t ack_timeout_retries);
00547 
00548     /**
00549      * Validates if the payload fits into the frame, taking the datarate
00550      * into account.
00551      *
00552      * Please Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0.2
00553      */
00554     bool validate_payload_length(uint16_t length, int8_t datarate, uint8_t fopts_len);
00555 
00556     /**
00557      * Prepares MAC frame on the behest of send() API.
00558      */
00559     lorawan_status_t prepare_frame(loramac_mhdr_t  *mac_hdr,
00560                                    loramac_frame_ctrl_t  *fctrl, const uint8_t fport,
00561                                    const void *fbuffer, uint16_t fbuffer_size);
00562 
00563     /**
00564      * Schedules a transmission on the behest of send() API.
00565      */
00566     lorawan_status_t schedule_tx();
00567 
00568     /**
00569      * Calculates the back-off time for the band of a channel.
00570      * Takes in the last used channel id as a parameter.
00571      */
00572     void calculate_backOff(uint8_t channel_id);
00573 
00574     /**
00575      * Hands over the MAC frame to PHY layer.
00576      */
00577     lorawan_status_t send_frame_on_channel(uint8_t channel);
00578 
00579     /**
00580      * Resets MAC primitive blocks
00581      */
00582     void reset_mcps_confirmation(void);
00583     void reset_mlme_confirmation(void);
00584     void reset_mcps_indication(void);
00585 
00586     /**
00587      * @brief set_tx_continuous_wave Puts the system in continuous transmission mode
00588      * @param [in] channel A Channel to use
00589      * @param [in] datarate A datarate to use
00590      * @param [in] tx_power A RF output power to use
00591      * @param [in] max_eirp A maximum possible EIRP to use
00592      * @param [in] antenna_gain Antenna gain to use
00593      * @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
00594      */
00595     void set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power,
00596                                 float max_eirp, float antenna_gain, uint16_t timeout);
00597 
00598 private:
00599     /**
00600      * Timer subsystem handle
00601      */
00602     LoRaWANTimeHandler _lora_time;
00603 
00604     /**
00605      * LoRa PHY layer object storage
00606      */
00607     LoRaPHY_region _lora_phy;
00608 
00609     /**
00610      * MAC command handle
00611      */
00612     LoRaMacCommand _mac_commands;
00613 
00614     /**
00615      * Channel planning subsystem
00616      */
00617     LoRaMacChannelPlan _channel_plan;
00618 
00619     /**
00620      * Crypto handling subsystem
00621      */
00622     LoRaMacCrypto _lora_crypto;
00623 
00624     /**
00625      * Central MAC layer data storage
00626      */
00627     loramac_protocol_params _params;
00628 
00629     /**
00630      * EventQueue object storage
00631      */
00632     events::EventQueue *_ev_queue;
00633 
00634     /**
00635      * Structure to hold MCPS indication data.
00636      */
00637     loramac_mcps_indication_t  _mcps_indication;
00638 
00639     /**
00640      * Structure to hold MCPS confirm data.
00641      */
00642     loramac_mcps_confirm_t  _mcps_confirmation;
00643 
00644     /**
00645      * Structure to hold MLME indication data.
00646      */
00647     loramac_mlme_indication_t  _mlme_indication;
00648 
00649     /**
00650      * Structure to hold MLME confirm data.
00651      */
00652     loramac_mlme_confirm_t  _mlme_confirmation;
00653 
00654     loramac_tx_message_t _ongoing_tx_msg;
00655 
00656     bool _is_nwk_joined;
00657 
00658     device_class_t _device_class;
00659 
00660 #if defined(LORAWAN_COMPLIANCE_TEST)
00661 public: // Test interface
00662 
00663     /**
00664      * @brief   Set forth an MLME request.
00665      *
00666      * @details The MAC layer management entity handles the management services.
00667      *
00668      * @param [in] request    The MLME request to perform.
00669      *                        Refer to \ref loramac_mlme_req_t.
00670      *
00671      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00672      *          \ref LORAWAN_STATUS_OK
00673      *          \ref LORAWAN_STATUS_BUSY
00674      *          \ref LORAWAN_STATUS_SERVICE_UNKNOWN
00675      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00676      *          \ref LORAWAN_STATUS_NO_NETWORK_JOINED
00677      *          \ref LORAWAN_STATUS_LENGTH_ERROR
00678      *          \ref LORAWAN_STATUS_DEVICE_OFF
00679      */
00680     lorawan_status_t mlme_request(loramac_mlme_req_t *request);
00681 
00682     /**
00683      * @brief   Set forth an MCPS request.
00684      *
00685      * @details The MAC Common Part Sublayer handles the data services. The following
00686      *          code-snippet shows how to use the API to send an unconfirmed
00687      *          LoRaMAC frame.
00688      *
00689      * @code
00690      *
00691      * uint8_t buffer[] = {1, 2, 3};
00692      *
00693      * loramac_compliance_test_req_t request;
00694      * request.type = MCPS_UNCONFIRMED;
00695      * request.fport = 1;
00696      * request.f_buffer = buffer;
00697      * request.f_buffer_size = sizeof(buffer);
00698      *
00699      * if (test_request(&request) == LORAWAN_STATUS_OK) {
00700      *   // Service started successfully. Waiting for the MCPS-Confirm event
00701      * }
00702      *
00703      * @endcode
00704      *
00705      * @param [in] request    The test request to perform.
00706      *                        Refer to \ref loramac_compliance_test_req_t.
00707      *
00708      * @return  `lorawan_status_t` The status of the operation. The possible values are:
00709      *          \ref LORAWAN_STATUS_OK
00710      *          \ref LORAWAN_STATUS_BUSY
00711      *          \ref LORAWAN_STATUS_SERVICE_UNKNOWN
00712      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00713      *          \ref LORAWAN_STATUS_NO_NETWORK_JOINED
00714      *          \ref LORAWAN_STATUS_LENGTH_ERROR
00715      *          \ref LORAWAN_STATUS_DEVICE_OFF
00716      */
00717     lorawan_status_t test_request(loramac_compliance_test_req_t *request);
00718 
00719     /**
00720      * \brief   LoRaMAC set tx timer.
00721      *
00722      * \details Sets up a timer for next transmission (application specific timers).
00723      *
00724      * \param   [in] NextTxTime - Periodic time for next uplink.
00725 
00726      * \retval  `lorawan_status_t` The status of the operation. The possible values are:
00727      *          \ref LORAWAN_STATUS_OK
00728      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00729      */
00730     lorawan_status_t LoRaMacSetTxTimer( uint32_t NextTxTime );
00731 
00732     /**
00733      * \brief   LoRaMAC stop tx timer.
00734      *
00735      * \details Stops the next tx timer.
00736      *
00737      * \retval  `lorawan_status_t` The status of the operation. The possible values are:
00738      *          \ref LORAWAN_STATUS_OK
00739      *          \ref LORAWAN_STATUS_PARAMETER_INVALID
00740      */
00741     lorawan_status_t LoRaMacStopTxTimer( );
00742 
00743     /**
00744      * \brief   Enabled or disables the reception windows
00745      *
00746      * \details This is a test function. It shall be used for testing purposes only.
00747      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00748      *
00749      * \param   [in] enable - Enabled or disables the reception windows
00750      */
00751     void LoRaMacTestRxWindowsOn( bool enable );
00752 
00753     /**
00754      * \brief   Enables the MIC field test
00755      *
00756      * \details This is a test function. It shall be used for testing purposes only.
00757      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00758      *
00759      * \param   [in] txPacketCounter - Fixed Tx packet counter value
00760      */
00761     void LoRaMacTestSetMic( uint16_t txPacketCounter );
00762 
00763     /**
00764      * \brief   Enabled or disables the duty cycle
00765      *
00766      * \details This is a test function. It shall be used for testing purposes only.
00767      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00768      *
00769      * \param   [in] enable - Enabled or disables the duty cycle
00770      */
00771     void LoRaMacTestSetDutyCycleOn( bool enable );
00772 
00773     /**
00774      * \brief   Sets the channel index
00775      *
00776      * \details This is a test function. It shall be used for testing purposes only.
00777      *          Changing this attribute may lead to a non-conformance LoRaMac operation.
00778      *
00779      * \param   [in] channel - Channel index
00780      */
00781     void LoRaMacTestSetChannel( uint8_t channel );
00782 
00783 private:
00784     /**
00785      * Timer to handle the application data transmission duty cycle
00786      */
00787     timer_event_t tx_next_packet_timer;
00788 #endif
00789 };
00790 
00791 #endif // MBED_LORAWAN_MAC_H__