Nicolas Borla / Mbed OS BBR_1Ebene
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaWANInterface.h Source File

LoRaWANInterface.h

00001 /**
00002  * Copyright (c) 2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #ifndef LORAWANINTERFACE_H_
00019 #define LORAWANINTERFACE_H_
00020 
00021 #include "platform/Callback.h"
00022 #include "platform/ScopedLock.h"
00023 #include "LoRaWANStack.h"
00024 #include "LoRaRadio.h"
00025 #include "LoRaWANBase.h"
00026 
00027 class LoRaWANInterface: public LoRaWANBase {
00028 
00029 public:
00030 
00031     /** Constructs a LoRaWANInterface using the LoRaWANStack instance underneath.
00032      *
00033      * Currently, LoRaWANStack is a singleton and you should only
00034      * construct a single instance of LoRaWANInterface.
00035      *
00036      */
00037     LoRaWANInterface(LoRaRadio& radio);
00038 
00039     virtual ~LoRaWANInterface();
00040 
00041     /** Initialize the LoRa stack.
00042      *
00043      * You must call this first to be able to use the LoRa stack.
00044      *
00045      * @param ev_queue A pointer to EventQueue provided by the application.
00046      *
00047      * @return         0 on success, a negative error code on failure.
00048      */
00049     virtual lorawan_status_t initialize(events::EventQueue *ev_queue);
00050 
00051     /** Connect OTAA or ABP using Mbed-OS config system
00052      *
00053      * Connect by Over The Air Activation or Activation By Personalization.
00054      * You need to configure the connection properly via the Mbed OS configuration
00055      * system.
00056      *
00057      * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
00058      * However, this is not a real error. It tells you that the connection is in progress and you will
00059      * be notified of the completion via an event. By default, after the Join Accept message
00060      * is received, base stations may provide the node with a CF-List that replaces
00061      * all user-configured channels except the Join/Default channels. A CF-List can
00062      * configure a maximum of five channels other than the default channels.
00063      *
00064      * In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
00065      * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
00066      * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions
00067      * on these channels are severe and you may experience long delays or even failures in the confirmed traffic.
00068      * If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only.
00069      *
00070      * **NOTES ON RECONNECTION:**
00071      * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
00072      * memory storage. Therefore, the state and frame counters cannot be restored after
00073      * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
00074      * protocol, the state and frame counters are saved. Connecting again would try to
00075      * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
00076      * to zero for OTAA and a new Join request lets the network server know
00077      * that the counters need a reset. The same is said about the ABP but there
00078      * is no way to convey this information to the network server. For a network
00079      * server, an ABP device is always connected. That's why storing the frame counters
00080      * is important, at least for ABP. That's why we try to restore frame counters from
00081      * session information after a disconnection.
00082      *
00083      * @return         LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS
00084      *                 on success, or a negative error code on failure.
00085      */
00086     virtual lorawan_status_t connect();
00087 
00088     /** Connect OTAA or ABP with parameters
00089      *
00090      * All connection parameters are chosen by the user and provided in the
00091      * data structure passed down.
00092      *
00093      * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
00094      * However, this is not a real error. It tells you that connection is in progress and you will
00095      * be notified of completion via an event. By default, after Join Accept message
00096      * is received, base stations may provide the node with a CF-List which replaces
00097      * all user-configured channels except the Join/Default channels. A CF-List can
00098      * configure a maximum of five channels other than the default channels.
00099      *
00100      * In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
00101      * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
00102      * By default, the PHY layers configure only the mandatory Join
00103      * channels. The retransmission back-off restrictions on these channels
00104      * are severe and you may experience long delays or even
00105      * failures in the confirmed traffic. If you add more channels, the aggregated duty
00106      * cycle becomes much more relaxed as compared to the Join (default) channels only.
00107      *
00108      * **NOTES ON RECONNECTION:**
00109      * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
00110      * memory storage. Therefore, the state and frame counters cannot be restored after
00111      * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
00112      * protocol, the state and frame counters are saved. Connecting again would try to
00113      * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
00114      * to zero for OTAA and a new Join request lets the network server know
00115      * that the counters need a reset. The same is said about the ABP but there
00116      * is no way to convey this information to the network server. For a network
00117      * server, an ABP device is always connected. That's why storing the frame counters
00118      * is important, at least for ABP. That's why we try to restore frame counters from
00119      * session information after a disconnection.
00120      *
00121      * @param connect  Options for an end device connection to the gateway.
00122      *
00123      * @return        LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
00124      *                a negative error code on failure.
00125      */
00126     virtual lorawan_status_t connect(const lorawan_connect_t &connect);
00127 
00128     /** Disconnect the current session.
00129      *
00130      * @return         LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
00131      */
00132     virtual lorawan_status_t disconnect();
00133 
00134     /** Validate the connectivity with the network.
00135      *
00136      * Application may use this API to submit a request to the stack for
00137      * validation of its connectivity to a Network Server. Under the hood, this
00138      * API schedules a Link Check Request command (LinkCheckReq) for the network
00139      * server and once the response, i.e., LinkCheckAns MAC command is received
00140      * from the Network Server, user provided method is called.
00141      *
00142      * One way to use this API may be the validation of connectivity after a long
00143      * deep sleep. Mbed LoRaWANStack piggy-backs the MAC commands with data
00144      * frame payload so the application needs to try sending something and the Network
00145      * Server may respond during the RX slots.
00146      *
00147      * This API is usable only when the 'link_check_resp' callback is set by
00148      * the application. See add_lora_app_callbacks API. If the above mentioned
00149      * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown.
00150      *
00151      * First parameter to callback function is the demodulation margin and
00152      * the second parameter is the number of gateways that successfully received
00153      * the last request.
00154      *
00155      * A 'Link Check Request' MAC command remains set for every subsequent
00156      * transmission, until/unless application explicitly turns it off using
00157      * remove_link_check_request() API.
00158      *
00159      * @return          LORAWAN_STATUS_OK on successfully queuing a request, or
00160      *                  a negative error code on failure.
00161      *
00162      */
00163     virtual lorawan_status_t add_link_check_request();
00164 
00165     /** Removes link check request sticky MAC command.
00166      *
00167      * Any already queued request may still get entertained. However, no new
00168      * requests will be made.
00169      */
00170     virtual void remove_link_check_request();
00171 
00172     /** Sets up a particular data rate
00173      *
00174      * `set_datarate()` first verifies whether the data rate given is valid or not.
00175      * If it is valid, the system sets the given data rate to the channel.
00176      *
00177      * @param data_rate   The intended data rate, for example DR_0 or DR_1.
00178      *                    Please note, that the macro DR_* can mean different
00179      *                    things in different regions.
00180      * @return            LORAWAN_STATUS_OK if everything goes well, otherwise
00181      *                    a negative error code.
00182      */
00183     virtual lorawan_status_t set_datarate(uint8_t data_rate);
00184 
00185     /** Enables adaptive data rate (ADR).
00186      *
00187      * The underlying LoRaPHY and LoRaMac layers handle the data rate automatically
00188      * for the user, based upon the radio conditions (network congestion).
00189      *
00190      * @return          LORAWAN_STATUS_OK or negative error code otherwise.
00191      */
00192     virtual lorawan_status_t enable_adaptive_datarate();
00193 
00194     /** Disables adaptive data rate.
00195      *
00196      * When adaptive data rate (ADR) is disabled, you can either set a certain
00197      * data rate or the MAC layer selects a default value.
00198      *
00199      * @return          LORAWAN_STATUS_OK or negative error code otherwise.
00200      */
00201     virtual lorawan_status_t disable_adaptive_datarate();
00202 
00203     /** Sets up the retry counter for confirmed messages.
00204      *
00205      * Valid for confirmed messages only.
00206      *
00207      * The number of trials to transmit the frame, if the LoRaMAC layer did not
00208      * receive an acknowledgment. The MAC performs a data rate adaptation as in
00209      * the LoRaWAN Specification V1.0.2, chapter 18.4, table on page 64.
00210      *
00211      * Note, that if number of retries is set to 1 or 2, MAC will not decrease
00212      * the datarate, if the LoRaMAC layer did not receive an acknowledgment.
00213      *
00214      * @param count     The number of retries for confirmed messages.
00215      *
00216      * @return          LORAWAN_STATUS_OK or a negative error code.
00217      */
00218     virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count);
00219 
00220     /** Sets the channel plan.
00221      *
00222      * You can provide a list of channels with appropriate parameters filled
00223      * in. However, this list is not absolute. The stack applies a CF-List whenever
00224      * available, which means that the network can overwrite your channel
00225      * frequency settings right after Join Accept is received. You may try
00226      * to set up any channel or channels after that, and if the channel requested
00227      * is already active, the request is silently ignored. A negative error
00228      * code is returned if there is any problem with parameters.
00229      *
00230      * Please note that this API can also be used to add a single channel to the
00231      * existing channel plan.
00232      *
00233      * There is no reverse mechanism in the 1.0.2 specification for a node to request
00234      * a particular channel. Only the network server can initiate such a request.
00235      * You need to ensure that the corresponding base station supports the channel or channels being added.
00236      *
00237      * If your list includes a default channel (a channel where Join Requests
00238      * are received) you cannot fully configure the channel parameters.
00239      * Either leave the channel settings to default or check your
00240      * corresponding PHY layer implementation. For example, LoRaPHYE868.
00241      *
00242      * @param channel_plan      The channel plan to set.
00243      *
00244      * @return                  LORAWAN_STATUS_OK on success, a negative error
00245      *                          code on failure.
00246      */
00247     virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan);
00248 
00249     /** Gets the channel plans from the LoRa stack.
00250      *
00251      * Once you have selected a particular PHY layer, a set of channels
00252      * is automatically activated. Right after connecting, you can use this API
00253      * to see the current plan. Otherwise, this API returns the channel
00254      * plan that you have set using `set_channel_plan()`.
00255      *
00256      * @param  channel_plan     The current channel plan information.
00257      *
00258      * @return                  LORAWAN_STATUS_OK on success, a negative error
00259      *                          code on failure.
00260      */
00261     virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan);
00262 
00263     /** Removes an active channel plan.
00264      *
00265      * You cannot remove default channels (the channels the base stations are listening to).
00266      * When a plan is abolished, only the non-default channels are removed.
00267      *
00268      * @return                  LORAWAN_STATUS_OK on success, a negative error
00269      *                          code on failure.
00270      */
00271     virtual lorawan_status_t remove_channel_plan();
00272 
00273     /** Removes a single channel.
00274      *
00275      * You cannot remove default channels (the channels the base stations are listening to).
00276      *
00277      * @param    index          The channel index.
00278      *
00279      * @return                  LORAWAN_STATUS_OK on success, a negative error
00280      *                          code on failure.
00281      */
00282     virtual lorawan_status_t remove_channel(uint8_t index);
00283 
00284     /** Send message to gateway
00285      *
00286      * @param port              The application port number. Port numbers 0 and 224
00287      *                          are reserved, whereas port numbers from 1 to 223
00288      *                          (0x01 to 0xDF) are valid port numbers.
00289      *                          Anything out of this range is illegal.
00290      *
00291      * @param data              A pointer to the data being sent. The ownership of the
00292      *                          buffer is not transferred. The data is copied to the
00293      *                          internal buffers.
00294      *
00295      * @param length            The size of data in bytes.
00296      *
00297      * @param flags             A flag used to determine what type of
00298      *                          message is being sent, for example:
00299      *
00300      *                          MSG_UNCONFIRMED_FLAG = 0x01
00301      *                          MSG_CONFIRMED_FLAG = 0x02
00302      *                          MSG_MULTICAST_FLAG = 0x04
00303      *                          MSG_PROPRIETARY_FLAG = 0x08
00304      *                          MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be
00305      *                          used in conjunction with MSG_UNCONFIRMED_FLAG and
00306      *                          MSG_CONFIRMED_FLAG depending on the intended use.
00307      *
00308      *                          MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set
00309      *                          a confirmed message flag for a proprietary message.
00310      *                          MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
00311      *                          mutually exclusive.
00312      *
00313      *
00314      * @return                  The number of bytes sent, or
00315      *                          LORAWAN_STATUS_WOULD_BLOCK if another TX is
00316      *                          ongoing, or a negative error code on failure.
00317      */
00318     virtual int16_t send(uint8_t port, const uint8_t* data, uint16_t length,
00319                          int flags);
00320 
00321     /** Receives a message from the Network Server on a specific port.
00322      *
00323      * @param port              The application port number. Port numbers 0 and 224
00324      *                          are reserved, whereas port numbers from 1 to 223
00325      *                          (0x01 to 0xDF) are valid port numbers.
00326      *                          Anything out of this range is illegal.
00327      *
00328      * @param data              A pointer to buffer where the received data will be
00329      *                          stored.
00330      *
00331      * @param length            The size of data in bytes
00332      *
00333      * @param flags             A flag is used to determine what type of
00334      *                          message is being sent, for example:
00335      *
00336      *                          MSG_UNCONFIRMED_FLAG = 0x01,
00337      *                          MSG_CONFIRMED_FLAG = 0x02
00338      *                          MSG_MULTICAST_FLAG = 0x04,
00339      *                          MSG_PROPRIETARY_FLAG = 0x08
00340      *
00341      *                          MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be
00342      *                          used in conjunction with MSG_UNCONFIRMED_FLAG and
00343      *                          MSG_CONFIRMED_FLAG depending on the intended use.
00344      *
00345      *                          MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set
00346      *                          a confirmed message flag for a proprietary message.
00347      *
00348      *                          MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
00349      *                          not mutually exclusive, i.e., the user can subscribe to
00350      *                          receive both CONFIRMED AND UNCONFIRMED messages at
00351      *                          the same time.
00352      *
00353      * @return                  It could be one of these:
00354      *                             i)   0 if there is nothing else to read.
00355      *                             ii)  Number of bytes written to user buffer.
00356      *                             iii) LORAWAN_STATUS_WOULD_BLOCK if there is
00357      *                                  nothing available to read at the moment.
00358      *                             iv)  A negative error code on failure.
00359      */
00360     virtual int16_t receive(uint8_t port, uint8_t* data, uint16_t length, int flags);
00361 
00362     /** Receives a message from the Network Server on any port.
00363      *
00364      * @param data              A pointer to buffer where the received data will be
00365      *                          stored.
00366      *
00367      * @param length            The size of data in bytes
00368      *
00369      * @param port              Return the number of port to which message was received.
00370      *
00371      * @param flags             Return flags to determine what type of message was received.
00372      *                          MSG_UNCONFIRMED_FLAG = 0x01
00373      *                          MSG_CONFIRMED_FLAG = 0x02
00374      *                          MSG_MULTICAST_FLAG = 0x04
00375      *                          MSG_PROPRIETARY_FLAG = 0x08
00376      *
00377      * @return                  It could be one of these:
00378      *                             i)   0 if there is nothing else to read.
00379      *                             ii)  Number of bytes written to user buffer.
00380      *                             iii) LORAWAN_STATUS_WOULD_BLOCK if there is
00381      *                                  nothing available to read at the moment.
00382      *                             iv)  A negative error code on failure.
00383      */
00384     virtual int16_t receive(uint8_t* data, uint16_t length, uint8_t& port, int& flags);
00385 
00386     /** Add application callbacks to the stack.
00387      *
00388      * An example of using this API with a latch onto 'lorawan_events' could be:
00389      *
00390      * LoRaWANInterface lorawan(radio);
00391      * lorawan_app_callbacks_t cbs;
00392      * static void my_event_handler();
00393      *
00394      * int main()
00395      * {
00396      * lorawan.initialize();
00397      *  cbs.lorawan_events = mbed::callback(my_event_handler);
00398      *  lorawan.add_app_callbacks(&cbs);
00399      *  lorawan.connect();
00400      * }
00401      *
00402      * static void my_event_handler(lorawan_event_t event)
00403      * {
00404      *  switch(event) {
00405      *      case CONNECTED:
00406      *          //do something
00407      *          break;
00408      *      case DISCONNECTED:
00409      *          //do something
00410      *          break;
00411      *      case TX_DONE:
00412      *          //do something
00413      *          break;
00414      *      default:
00415      *          break;
00416      *  }
00417      * }
00418      *
00419      * @param callbacks         A pointer to the structure containing application
00420      *                          callbacks.
00421      *
00422      * @return                  LORAWAN_STATUS_OK on success, a negative error
00423      *                          code on failure.
00424      */
00425     virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks);
00426 
00427     /** Change device class
00428      *
00429      * Change current device class.
00430      *
00431      * @param    device_class   The device class
00432      *
00433      * @return                  LORAWAN_STATUS_OK on success,
00434      *                          LORAWAN_STATUS_UNSUPPORTED is requested class is not supported,
00435      *                          or other negative error code if request failed.
00436      */
00437     virtual lorawan_status_t set_device_class(const device_class_t device_class);
00438 
00439     void lock(void) { _lw_stack.lock(); }
00440     void unlock(void) { _lw_stack.unlock(); }
00441 
00442 
00443 private:
00444     typedef mbed::ScopedLock<LoRaWANInterface> Lock;
00445 
00446     LoRaWANStack _lw_stack;
00447 };
00448 
00449 #endif /* LORAWANINTERFACE_H_ */