Nicolas Borla
/
BBR_1Ebene
BBR 1 Ebene
mbed-os/features/lorawan/LoRaWANStack.h@0:fbdae7e6d805, 2018-05-14 (annotated)
- Committer:
- borlanic
- Date:
- Mon May 14 11:29:06 2018 +0000
- Revision:
- 0:fbdae7e6d805
BBR
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
borlanic | 0:fbdae7e6d805 | 1 | /** |
borlanic | 0:fbdae7e6d805 | 2 | * \file LoRaWANStack.h |
borlanic | 0:fbdae7e6d805 | 3 | * |
borlanic | 0:fbdae7e6d805 | 4 | * \brief LoRaWAN stack layer implementation |
borlanic | 0:fbdae7e6d805 | 5 | * |
borlanic | 0:fbdae7e6d805 | 6 | * \copyright Revised BSD License, see LICENSE.TXT file include in the project |
borlanic | 0:fbdae7e6d805 | 7 | * |
borlanic | 0:fbdae7e6d805 | 8 | * \code |
borlanic | 0:fbdae7e6d805 | 9 | * ______ _ |
borlanic | 0:fbdae7e6d805 | 10 | * / _____) _ | | |
borlanic | 0:fbdae7e6d805 | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ |
borlanic | 0:fbdae7e6d805 | 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ |
borlanic | 0:fbdae7e6d805 | 13 | * _____) ) ____| | | || |_| ____( (___| | | | |
borlanic | 0:fbdae7e6d805 | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| |
borlanic | 0:fbdae7e6d805 | 15 | * (C)2013 Semtech |
borlanic | 0:fbdae7e6d805 | 16 | * |
borlanic | 0:fbdae7e6d805 | 17 | * ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
borlanic | 0:fbdae7e6d805 | 18 | * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
borlanic | 0:fbdae7e6d805 | 19 | * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
borlanic | 0:fbdae7e6d805 | 20 | * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
borlanic | 0:fbdae7e6d805 | 21 | * embedded.connectivity.solutions=============== |
borlanic | 0:fbdae7e6d805 | 22 | * |
borlanic | 0:fbdae7e6d805 | 23 | * \endcode |
borlanic | 0:fbdae7e6d805 | 24 | * |
borlanic | 0:fbdae7e6d805 | 25 | * \author Miguel Luis ( Semtech ) |
borlanic | 0:fbdae7e6d805 | 26 | * |
borlanic | 0:fbdae7e6d805 | 27 | * \author Gregory Cristian ( Semtech ) |
borlanic | 0:fbdae7e6d805 | 28 | * |
borlanic | 0:fbdae7e6d805 | 29 | * \author Daniel Jaeckle ( STACKFORCE ) |
borlanic | 0:fbdae7e6d805 | 30 | * |
borlanic | 0:fbdae7e6d805 | 31 | * \defgroup LoRaWAN stack layer that controls MAC layer underneath |
borlanic | 0:fbdae7e6d805 | 32 | * |
borlanic | 0:fbdae7e6d805 | 33 | * License: Revised BSD License, see LICENSE.TXT file include in the project |
borlanic | 0:fbdae7e6d805 | 34 | * |
borlanic | 0:fbdae7e6d805 | 35 | * Copyright (c) 2017, Arm Limited and affiliates. |
borlanic | 0:fbdae7e6d805 | 36 | * |
borlanic | 0:fbdae7e6d805 | 37 | * SPDX-License-Identifier: BSD-3-Clause |
borlanic | 0:fbdae7e6d805 | 38 | */ |
borlanic | 0:fbdae7e6d805 | 39 | |
borlanic | 0:fbdae7e6d805 | 40 | #ifndef LORAWANSTACK_H_ |
borlanic | 0:fbdae7e6d805 | 41 | #define LORAWANSTACK_H_ |
borlanic | 0:fbdae7e6d805 | 42 | |
borlanic | 0:fbdae7e6d805 | 43 | #include <stdint.h> |
borlanic | 0:fbdae7e6d805 | 44 | #include "events/EventQueue.h" |
borlanic | 0:fbdae7e6d805 | 45 | #include "platform/Callback.h" |
borlanic | 0:fbdae7e6d805 | 46 | #include "platform/NonCopyable.h" |
borlanic | 0:fbdae7e6d805 | 47 | #include "platform/ScopedLock.h" |
borlanic | 0:fbdae7e6d805 | 48 | |
borlanic | 0:fbdae7e6d805 | 49 | #include "lorastack/mac/LoRaMac.h" |
borlanic | 0:fbdae7e6d805 | 50 | #include "system/LoRaWANTimer.h" |
borlanic | 0:fbdae7e6d805 | 51 | #include "system/lorawan_data_structures.h" |
borlanic | 0:fbdae7e6d805 | 52 | #include "LoRaRadio.h" |
borlanic | 0:fbdae7e6d805 | 53 | |
borlanic | 0:fbdae7e6d805 | 54 | class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> { |
borlanic | 0:fbdae7e6d805 | 55 | |
borlanic | 0:fbdae7e6d805 | 56 | public: |
borlanic | 0:fbdae7e6d805 | 57 | LoRaWANStack(); |
borlanic | 0:fbdae7e6d805 | 58 | |
borlanic | 0:fbdae7e6d805 | 59 | /** Binds radio driver to PHY layer. |
borlanic | 0:fbdae7e6d805 | 60 | * |
borlanic | 0:fbdae7e6d805 | 61 | * MAC layer is totally detached from the PHY layer so the stack layer |
borlanic | 0:fbdae7e6d805 | 62 | * needs to play the role of an arbitrator. This API gets a radio driver |
borlanic | 0:fbdae7e6d805 | 63 | * object from the application (via LoRaWANInterface), binds it to the PHY |
borlanic | 0:fbdae7e6d805 | 64 | * layer and initialises radio callback handles which the radio driver will |
borlanic | 0:fbdae7e6d805 | 65 | * use in order to report events. |
borlanic | 0:fbdae7e6d805 | 66 | * |
borlanic | 0:fbdae7e6d805 | 67 | * @param radio LoRaRadio object, i.e., the radio driver |
borlanic | 0:fbdae7e6d805 | 68 | * |
borlanic | 0:fbdae7e6d805 | 69 | */ |
borlanic | 0:fbdae7e6d805 | 70 | void bind_radio_driver(LoRaRadio& radio); |
borlanic | 0:fbdae7e6d805 | 71 | |
borlanic | 0:fbdae7e6d805 | 72 | /** End device initialization. |
borlanic | 0:fbdae7e6d805 | 73 | * @param queue A pointer to an EventQueue passed from the application. |
borlanic | 0:fbdae7e6d805 | 74 | * @return LORAWAN_STATUS_OK on success, a negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 75 | */ |
borlanic | 0:fbdae7e6d805 | 76 | lorawan_status_t initialize_mac_layer(events::EventQueue *queue); |
borlanic | 0:fbdae7e6d805 | 77 | |
borlanic | 0:fbdae7e6d805 | 78 | /** Sets all callbacks for the application. |
borlanic | 0:fbdae7e6d805 | 79 | * |
borlanic | 0:fbdae7e6d805 | 80 | * @param callbacks A pointer to the structure carrying callbacks. |
borlanic | 0:fbdae7e6d805 | 81 | * @return LORAWAN_STATUS_OK on success, a negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 82 | */ |
borlanic | 0:fbdae7e6d805 | 83 | lorawan_status_t set_lora_callbacks(const lorawan_app_callbacks_t *callbacks); |
borlanic | 0:fbdae7e6d805 | 84 | |
borlanic | 0:fbdae7e6d805 | 85 | /** Connect OTAA or ABP using Mbed-OS config system |
borlanic | 0:fbdae7e6d805 | 86 | * |
borlanic | 0:fbdae7e6d805 | 87 | * Connect by Over The Air Activation or Activation By Personalization. |
borlanic | 0:fbdae7e6d805 | 88 | * You need to configure the connection properly via the Mbed OS configuration |
borlanic | 0:fbdae7e6d805 | 89 | * system. |
borlanic | 0:fbdae7e6d805 | 90 | * |
borlanic | 0:fbdae7e6d805 | 91 | * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. |
borlanic | 0:fbdae7e6d805 | 92 | * However, this is not a real error. It tells you that the connection is in progress and you will |
borlanic | 0:fbdae7e6d805 | 93 | * be notified of the completion via an event. By default, after the Join Accept message |
borlanic | 0:fbdae7e6d805 | 94 | * is received, base stations may provide the node with a CF-List that replaces |
borlanic | 0:fbdae7e6d805 | 95 | * all user-configured channels except the Join/Default channels. A CF-List can |
borlanic | 0:fbdae7e6d805 | 96 | * configure a maximum of five channels other than the default channels. |
borlanic | 0:fbdae7e6d805 | 97 | * |
borlanic | 0:fbdae7e6d805 | 98 | * In case of ABP, the CONNECTED event is posted before the call to `connect()` returns. |
borlanic | 0:fbdae7e6d805 | 99 | * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. |
borlanic | 0:fbdae7e6d805 | 100 | * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions |
borlanic | 0:fbdae7e6d805 | 101 | * on these channels are severe and you may experience long delays or even failures in the confirmed traffic. |
borlanic | 0:fbdae7e6d805 | 102 | * If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only. |
borlanic | 0:fbdae7e6d805 | 103 | * |
borlanic | 0:fbdae7e6d805 | 104 | * **NOTES ON RECONNECTION:** |
borlanic | 0:fbdae7e6d805 | 105 | * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile |
borlanic | 0:fbdae7e6d805 | 106 | * memory storage. Therefore, the state and frame counters cannot be restored after |
borlanic | 0:fbdae7e6d805 | 107 | * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN |
borlanic | 0:fbdae7e6d805 | 108 | * protocol, the state and frame counters are saved. Connecting again would try to |
borlanic | 0:fbdae7e6d805 | 109 | * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset |
borlanic | 0:fbdae7e6d805 | 110 | * to zero for OTAA and a new Join request lets the network server know |
borlanic | 0:fbdae7e6d805 | 111 | * that the counters need a reset. The same is said about the ABP but there |
borlanic | 0:fbdae7e6d805 | 112 | * is no way to convey this information to the network server. For a network |
borlanic | 0:fbdae7e6d805 | 113 | * server, an ABP device is always connected. That's why storing the frame counters |
borlanic | 0:fbdae7e6d805 | 114 | * is important, at least for ABP. That's why we try to restore frame counters from |
borlanic | 0:fbdae7e6d805 | 115 | * session information after a disconnection. |
borlanic | 0:fbdae7e6d805 | 116 | * |
borlanic | 0:fbdae7e6d805 | 117 | * @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS |
borlanic | 0:fbdae7e6d805 | 118 | * on success, or a negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 119 | */ |
borlanic | 0:fbdae7e6d805 | 120 | lorawan_status_t connect(); |
borlanic | 0:fbdae7e6d805 | 121 | |
borlanic | 0:fbdae7e6d805 | 122 | /** Connect OTAA or ABP with parameters |
borlanic | 0:fbdae7e6d805 | 123 | * |
borlanic | 0:fbdae7e6d805 | 124 | * All connection parameters are chosen by the user and provided in the |
borlanic | 0:fbdae7e6d805 | 125 | * data structure passed down. |
borlanic | 0:fbdae7e6d805 | 126 | * |
borlanic | 0:fbdae7e6d805 | 127 | * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. |
borlanic | 0:fbdae7e6d805 | 128 | * However, this is not a real error. It tells you that connection is in progress and you will |
borlanic | 0:fbdae7e6d805 | 129 | * be notified of completion via an event. By default, after Join Accept message |
borlanic | 0:fbdae7e6d805 | 130 | * is received, base stations may provide the node with a CF-List which replaces |
borlanic | 0:fbdae7e6d805 | 131 | * all user-configured channels except the Join/Default channels. A CF-List can |
borlanic | 0:fbdae7e6d805 | 132 | * configure a maximum of five channels other than the default channels. |
borlanic | 0:fbdae7e6d805 | 133 | * |
borlanic | 0:fbdae7e6d805 | 134 | * In case of ABP, the CONNECTED event is posted before the call to `connect()` returns. |
borlanic | 0:fbdae7e6d805 | 135 | * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. |
borlanic | 0:fbdae7e6d805 | 136 | * By default, the PHY layers configure only the mandatory Join |
borlanic | 0:fbdae7e6d805 | 137 | * channels. The retransmission back-off restrictions on these channels |
borlanic | 0:fbdae7e6d805 | 138 | * are severe and you may experience long delays or even |
borlanic | 0:fbdae7e6d805 | 139 | * failures in the confirmed traffic. If you add more channels, the aggregated duty |
borlanic | 0:fbdae7e6d805 | 140 | * cycle becomes much more relaxed as compared to the Join (default) channels only. |
borlanic | 0:fbdae7e6d805 | 141 | * |
borlanic | 0:fbdae7e6d805 | 142 | * **NOTES ON RECONNECTION:** |
borlanic | 0:fbdae7e6d805 | 143 | * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile |
borlanic | 0:fbdae7e6d805 | 144 | * memory storage. Therefore, the state and frame counters cannot be restored after |
borlanic | 0:fbdae7e6d805 | 145 | * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN |
borlanic | 0:fbdae7e6d805 | 146 | * protocol, the state and frame counters are saved. Connecting again would try to |
borlanic | 0:fbdae7e6d805 | 147 | * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset |
borlanic | 0:fbdae7e6d805 | 148 | * to zero for OTAA and a new Join request lets the network server know |
borlanic | 0:fbdae7e6d805 | 149 | * that the counters need a reset. The same is said about the ABP but there |
borlanic | 0:fbdae7e6d805 | 150 | * is no way to convey this information to the network server. For a network |
borlanic | 0:fbdae7e6d805 | 151 | * server, an ABP device is always connected. That's why storing the frame counters |
borlanic | 0:fbdae7e6d805 | 152 | * is important, at least for ABP. That's why we try to restore frame counters from |
borlanic | 0:fbdae7e6d805 | 153 | * session information after a disconnection. |
borlanic | 0:fbdae7e6d805 | 154 | * |
borlanic | 0:fbdae7e6d805 | 155 | * @param connect Options for an end device connection to the gateway. |
borlanic | 0:fbdae7e6d805 | 156 | * |
borlanic | 0:fbdae7e6d805 | 157 | * @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS, |
borlanic | 0:fbdae7e6d805 | 158 | * a negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 159 | */ |
borlanic | 0:fbdae7e6d805 | 160 | lorawan_status_t connect(const lorawan_connect_t &connect); |
borlanic | 0:fbdae7e6d805 | 161 | |
borlanic | 0:fbdae7e6d805 | 162 | /** Adds channels to use. |
borlanic | 0:fbdae7e6d805 | 163 | * |
borlanic | 0:fbdae7e6d805 | 164 | * You can provide a list of channels with appropriate parameters filled |
borlanic | 0:fbdae7e6d805 | 165 | * in. However, this list is not absolute. In some regions, a CF |
borlanic | 0:fbdae7e6d805 | 166 | * list gets implemented by default, which means that the network can overwrite your channel |
borlanic | 0:fbdae7e6d805 | 167 | * frequency settings right after receiving a Join Accept. You may try |
borlanic | 0:fbdae7e6d805 | 168 | * to set up any channel or channels after that and if the channel requested |
borlanic | 0:fbdae7e6d805 | 169 | * is already active, the request is silently ignored. A negative error |
borlanic | 0:fbdae7e6d805 | 170 | * code is returned if there is any problem with parameters. |
borlanic | 0:fbdae7e6d805 | 171 | * |
borlanic | 0:fbdae7e6d805 | 172 | * You need to ensure that the base station nearby supports the channel or channels being added. |
borlanic | 0:fbdae7e6d805 | 173 | * |
borlanic | 0:fbdae7e6d805 | 174 | * If your list includes a default channel (a channel where Join Requests |
borlanic | 0:fbdae7e6d805 | 175 | * are received) you cannot fully configure the channel parameters. |
borlanic | 0:fbdae7e6d805 | 176 | * Either leave the channel settings to default or check your |
borlanic | 0:fbdae7e6d805 | 177 | * corresponding PHY layer implementation. For example, LoRaPHYE868. |
borlanic | 0:fbdae7e6d805 | 178 | * |
borlanic | 0:fbdae7e6d805 | 179 | * @param channel_plan A list of channels or a single channel. |
borlanic | 0:fbdae7e6d805 | 180 | * |
borlanic | 0:fbdae7e6d805 | 181 | * @return LORAWAN_STATUS_OK on success, a negative error |
borlanic | 0:fbdae7e6d805 | 182 | * code on failure. |
borlanic | 0:fbdae7e6d805 | 183 | */ |
borlanic | 0:fbdae7e6d805 | 184 | lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan); |
borlanic | 0:fbdae7e6d805 | 185 | |
borlanic | 0:fbdae7e6d805 | 186 | /** Removes a channel from the list. |
borlanic | 0:fbdae7e6d805 | 187 | * |
borlanic | 0:fbdae7e6d805 | 188 | * @param channel_id Index of the channel being removed |
borlanic | 0:fbdae7e6d805 | 189 | * |
borlanic | 0:fbdae7e6d805 | 190 | * @return LORAWAN_STATUS_OK on success, a negative error |
borlanic | 0:fbdae7e6d805 | 191 | * code on failure. |
borlanic | 0:fbdae7e6d805 | 192 | */ |
borlanic | 0:fbdae7e6d805 | 193 | lorawan_status_t remove_a_channel(uint8_t channel_id); |
borlanic | 0:fbdae7e6d805 | 194 | |
borlanic | 0:fbdae7e6d805 | 195 | /** Removes a previously set channel plan. |
borlanic | 0:fbdae7e6d805 | 196 | * |
borlanic | 0:fbdae7e6d805 | 197 | * @return LORAWAN_STATUS_OK on success, a negative error |
borlanic | 0:fbdae7e6d805 | 198 | * code on failure. |
borlanic | 0:fbdae7e6d805 | 199 | */ |
borlanic | 0:fbdae7e6d805 | 200 | lorawan_status_t drop_channel_list(); |
borlanic | 0:fbdae7e6d805 | 201 | |
borlanic | 0:fbdae7e6d805 | 202 | /** Gets a list of currently enabled channels . |
borlanic | 0:fbdae7e6d805 | 203 | * |
borlanic | 0:fbdae7e6d805 | 204 | * @param channel_plan The channel plan structure to store final result. |
borlanic | 0:fbdae7e6d805 | 205 | * |
borlanic | 0:fbdae7e6d805 | 206 | * @return LORAWAN_STATUS_OK on success, a negative error |
borlanic | 0:fbdae7e6d805 | 207 | * code on failure. |
borlanic | 0:fbdae7e6d805 | 208 | */ |
borlanic | 0:fbdae7e6d805 | 209 | lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan); |
borlanic | 0:fbdae7e6d805 | 210 | |
borlanic | 0:fbdae7e6d805 | 211 | /** Sets up a retry counter for confirmed messages. |
borlanic | 0:fbdae7e6d805 | 212 | * |
borlanic | 0:fbdae7e6d805 | 213 | * Valid only for confirmed messages. This API sets the number of times the |
borlanic | 0:fbdae7e6d805 | 214 | * stack will retry a CONFIRMED message before giving up and reporting an |
borlanic | 0:fbdae7e6d805 | 215 | * error. |
borlanic | 0:fbdae7e6d805 | 216 | * |
borlanic | 0:fbdae7e6d805 | 217 | * @param count The number of retries for confirmed messages. |
borlanic | 0:fbdae7e6d805 | 218 | * |
borlanic | 0:fbdae7e6d805 | 219 | * @return LORAWAN_STATUS_OK or a negative error code. |
borlanic | 0:fbdae7e6d805 | 220 | */ |
borlanic | 0:fbdae7e6d805 | 221 | lorawan_status_t set_confirmed_msg_retry(uint8_t count); |
borlanic | 0:fbdae7e6d805 | 222 | |
borlanic | 0:fbdae7e6d805 | 223 | /** Sets up the data rate. |
borlanic | 0:fbdae7e6d805 | 224 | * |
borlanic | 0:fbdae7e6d805 | 225 | * `set_datarate()` first verifies whether the data rate given is valid or not. |
borlanic | 0:fbdae7e6d805 | 226 | * If it is valid, the system sets the given data rate to the channel. |
borlanic | 0:fbdae7e6d805 | 227 | * |
borlanic | 0:fbdae7e6d805 | 228 | * @param data_rate The intended data rate, for example DR_0 or DR_1. |
borlanic | 0:fbdae7e6d805 | 229 | * Note that the macro DR_* can mean different |
borlanic | 0:fbdae7e6d805 | 230 | * things in different regions. |
borlanic | 0:fbdae7e6d805 | 231 | * |
borlanic | 0:fbdae7e6d805 | 232 | * @return LORAWAN_STATUS_OK if everything goes well, otherwise |
borlanic | 0:fbdae7e6d805 | 233 | * a negative error code. |
borlanic | 0:fbdae7e6d805 | 234 | */ |
borlanic | 0:fbdae7e6d805 | 235 | lorawan_status_t set_channel_data_rate(uint8_t data_rate); |
borlanic | 0:fbdae7e6d805 | 236 | |
borlanic | 0:fbdae7e6d805 | 237 | /** Enables ADR. |
borlanic | 0:fbdae7e6d805 | 238 | * |
borlanic | 0:fbdae7e6d805 | 239 | * @param adr_enabled 0 ADR disabled, 1 ADR enabled. |
borlanic | 0:fbdae7e6d805 | 240 | * |
borlanic | 0:fbdae7e6d805 | 241 | * @return LORAWAN_STATUS_OK on success, a negative error |
borlanic | 0:fbdae7e6d805 | 242 | * code on failure. |
borlanic | 0:fbdae7e6d805 | 243 | */ |
borlanic | 0:fbdae7e6d805 | 244 | lorawan_status_t enable_adaptive_datarate(bool adr_enabled); |
borlanic | 0:fbdae7e6d805 | 245 | |
borlanic | 0:fbdae7e6d805 | 246 | /** Send message to gateway |
borlanic | 0:fbdae7e6d805 | 247 | * |
borlanic | 0:fbdae7e6d805 | 248 | * @param port The application port number. Port numbers 0 and 224 |
borlanic | 0:fbdae7e6d805 | 249 | * are reserved, whereas port numbers from 1 to 223 |
borlanic | 0:fbdae7e6d805 | 250 | * (0x01 to 0xDF) are valid port numbers. |
borlanic | 0:fbdae7e6d805 | 251 | * Anything out of this range is illegal. |
borlanic | 0:fbdae7e6d805 | 252 | * |
borlanic | 0:fbdae7e6d805 | 253 | * @param data A pointer to the data being sent. The ownership of the |
borlanic | 0:fbdae7e6d805 | 254 | * buffer is not transferred. The data is copied to the |
borlanic | 0:fbdae7e6d805 | 255 | * internal buffers. |
borlanic | 0:fbdae7e6d805 | 256 | * |
borlanic | 0:fbdae7e6d805 | 257 | * @param length The size of data in bytes. |
borlanic | 0:fbdae7e6d805 | 258 | * |
borlanic | 0:fbdae7e6d805 | 259 | * @param flags A flag used to determine what type of |
borlanic | 0:fbdae7e6d805 | 260 | * message is being sent, for example: |
borlanic | 0:fbdae7e6d805 | 261 | * |
borlanic | 0:fbdae7e6d805 | 262 | * MSG_UNCONFIRMED_FLAG = 0x01 |
borlanic | 0:fbdae7e6d805 | 263 | * MSG_CONFIRMED_FLAG = 0x02 |
borlanic | 0:fbdae7e6d805 | 264 | * MSG_MULTICAST_FLAG = 0x04 |
borlanic | 0:fbdae7e6d805 | 265 | * MSG_PROPRIETARY_FLAG = 0x08 |
borlanic | 0:fbdae7e6d805 | 266 | * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be |
borlanic | 0:fbdae7e6d805 | 267 | * used in conjunction with MSG_UNCONFIRMED_FLAG and |
borlanic | 0:fbdae7e6d805 | 268 | * MSG_CONFIRMED_FLAG depending on the intended use. |
borlanic | 0:fbdae7e6d805 | 269 | * |
borlanic | 0:fbdae7e6d805 | 270 | * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set |
borlanic | 0:fbdae7e6d805 | 271 | * a confirmed message flag for a proprietary message. |
borlanic | 0:fbdae7e6d805 | 272 | * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are |
borlanic | 0:fbdae7e6d805 | 273 | * mutually exclusive. |
borlanic | 0:fbdae7e6d805 | 274 | * |
borlanic | 0:fbdae7e6d805 | 275 | * @param null_allowed Internal use only. Needed for sending empty packet |
borlanic | 0:fbdae7e6d805 | 276 | * having CONFIRMED bit on. |
borlanic | 0:fbdae7e6d805 | 277 | * |
borlanic | 0:fbdae7e6d805 | 278 | * @param allow_port_0 Internal use only. Needed for flushing MAC commands. |
borlanic | 0:fbdae7e6d805 | 279 | * |
borlanic | 0:fbdae7e6d805 | 280 | * @return The number of bytes sent, or |
borlanic | 0:fbdae7e6d805 | 281 | * LORAWAN_STATUS_WOULD_BLOCK if another TX is |
borlanic | 0:fbdae7e6d805 | 282 | * ongoing, or a negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 283 | */ |
borlanic | 0:fbdae7e6d805 | 284 | int16_t handle_tx(uint8_t port, const uint8_t* data, |
borlanic | 0:fbdae7e6d805 | 285 | uint16_t length, uint8_t flags, |
borlanic | 0:fbdae7e6d805 | 286 | bool null_allowed = false, bool allow_port_0 = false); |
borlanic | 0:fbdae7e6d805 | 287 | |
borlanic | 0:fbdae7e6d805 | 288 | /** Receives a message from the Network Server. |
borlanic | 0:fbdae7e6d805 | 289 | * |
borlanic | 0:fbdae7e6d805 | 290 | * @param data A pointer to buffer where the received data will be |
borlanic | 0:fbdae7e6d805 | 291 | * stored. |
borlanic | 0:fbdae7e6d805 | 292 | * |
borlanic | 0:fbdae7e6d805 | 293 | * @param length The size of data in bytes |
borlanic | 0:fbdae7e6d805 | 294 | * |
borlanic | 0:fbdae7e6d805 | 295 | * @param port The application port number. Port numbers 0 and 224 |
borlanic | 0:fbdae7e6d805 | 296 | * are reserved, whereas port numbers from 1 to 223 |
borlanic | 0:fbdae7e6d805 | 297 | * (0x01 to 0xDF) are valid port numbers. |
borlanic | 0:fbdae7e6d805 | 298 | * Anything out of this range is illegal. |
borlanic | 0:fbdae7e6d805 | 299 | * |
borlanic | 0:fbdae7e6d805 | 300 | * In return will contain the number of port to which |
borlanic | 0:fbdae7e6d805 | 301 | * message was received. |
borlanic | 0:fbdae7e6d805 | 302 | * |
borlanic | 0:fbdae7e6d805 | 303 | * @param flags A flag is used to determine what type of |
borlanic | 0:fbdae7e6d805 | 304 | * message is being received, for example: |
borlanic | 0:fbdae7e6d805 | 305 | * |
borlanic | 0:fbdae7e6d805 | 306 | * MSG_UNCONFIRMED_FLAG = 0x01, |
borlanic | 0:fbdae7e6d805 | 307 | * MSG_CONFIRMED_FLAG = 0x02 |
borlanic | 0:fbdae7e6d805 | 308 | * MSG_MULTICAST_FLAG = 0x04, |
borlanic | 0:fbdae7e6d805 | 309 | * MSG_PROPRIETARY_FLAG = 0x08 |
borlanic | 0:fbdae7e6d805 | 310 | * |
borlanic | 0:fbdae7e6d805 | 311 | * MSG_MULTICAST_FLAG and MSG_PROPRIETARY_FLAG can be |
borlanic | 0:fbdae7e6d805 | 312 | * used in conjunction with MSG_UNCONFIRMED_FLAG and |
borlanic | 0:fbdae7e6d805 | 313 | * MSG_CONFIRMED_FLAG depending on the intended use. |
borlanic | 0:fbdae7e6d805 | 314 | * |
borlanic | 0:fbdae7e6d805 | 315 | * MSG_PROPRIETARY_FLAG|MSG_CONFIRMED_FLAG mask will set |
borlanic | 0:fbdae7e6d805 | 316 | * a confirmed message flag for a proprietary message. |
borlanic | 0:fbdae7e6d805 | 317 | * |
borlanic | 0:fbdae7e6d805 | 318 | * MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are |
borlanic | 0:fbdae7e6d805 | 319 | * not mutually exclusive, i.e., the user can subscribe to |
borlanic | 0:fbdae7e6d805 | 320 | * receive both CONFIRMED AND UNCONFIRMED messages at |
borlanic | 0:fbdae7e6d805 | 321 | * the same time. |
borlanic | 0:fbdae7e6d805 | 322 | * |
borlanic | 0:fbdae7e6d805 | 323 | * In return will contain the flags to determine what kind |
borlanic | 0:fbdae7e6d805 | 324 | * of message was received. |
borlanic | 0:fbdae7e6d805 | 325 | * |
borlanic | 0:fbdae7e6d805 | 326 | * @param validate_params If set to true, the given port and flags values will be checked |
borlanic | 0:fbdae7e6d805 | 327 | * against the values received with the message. If values do not |
borlanic | 0:fbdae7e6d805 | 328 | * match, LORAWAN_STATUS_WOULD_BLOCK will be returned. |
borlanic | 0:fbdae7e6d805 | 329 | * |
borlanic | 0:fbdae7e6d805 | 330 | * @return It could be one of these: |
borlanic | 0:fbdae7e6d805 | 331 | * i) 0 if there is nothing else to read. |
borlanic | 0:fbdae7e6d805 | 332 | * ii) Number of bytes written to user buffer. |
borlanic | 0:fbdae7e6d805 | 333 | * iii) LORAWAN_STATUS_WOULD_BLOCK if there is |
borlanic | 0:fbdae7e6d805 | 334 | * nothing available to read at the moment. |
borlanic | 0:fbdae7e6d805 | 335 | * iv) A negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 336 | */ |
borlanic | 0:fbdae7e6d805 | 337 | int16_t handle_rx(uint8_t* data, uint16_t length, uint8_t& port, int& flags, bool validate_params); |
borlanic | 0:fbdae7e6d805 | 338 | |
borlanic | 0:fbdae7e6d805 | 339 | /** Send Link Check Request MAC command. |
borlanic | 0:fbdae7e6d805 | 340 | * |
borlanic | 0:fbdae7e6d805 | 341 | * |
borlanic | 0:fbdae7e6d805 | 342 | * This API schedules a Link Check Request command (LinkCheckReq) for the network |
borlanic | 0:fbdae7e6d805 | 343 | * server and once the response, i.e., LinkCheckAns MAC command is received |
borlanic | 0:fbdae7e6d805 | 344 | * from the Network Server, an event is generated. |
borlanic | 0:fbdae7e6d805 | 345 | * |
borlanic | 0:fbdae7e6d805 | 346 | * A callback function for the link check response must be set prior to using |
borlanic | 0:fbdae7e6d805 | 347 | * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. |
borlanic | 0:fbdae7e6d805 | 348 | * |
borlanic | 0:fbdae7e6d805 | 349 | * @return LORAWAN_STATUS_OK on successfully queuing a request, or |
borlanic | 0:fbdae7e6d805 | 350 | * a negative error code on failure. |
borlanic | 0:fbdae7e6d805 | 351 | * |
borlanic | 0:fbdae7e6d805 | 352 | */ |
borlanic | 0:fbdae7e6d805 | 353 | lorawan_status_t set_link_check_request(); |
borlanic | 0:fbdae7e6d805 | 354 | |
borlanic | 0:fbdae7e6d805 | 355 | /** Removes link check request sticky MAC command. |
borlanic | 0:fbdae7e6d805 | 356 | * |
borlanic | 0:fbdae7e6d805 | 357 | * Any already queued request may still get entertained. However, no new |
borlanic | 0:fbdae7e6d805 | 358 | * requests will be made. |
borlanic | 0:fbdae7e6d805 | 359 | */ |
borlanic | 0:fbdae7e6d805 | 360 | void remove_link_check_request(); |
borlanic | 0:fbdae7e6d805 | 361 | |
borlanic | 0:fbdae7e6d805 | 362 | /** Shuts down the LoRaWAN protocol. |
borlanic | 0:fbdae7e6d805 | 363 | * |
borlanic | 0:fbdae7e6d805 | 364 | * In response to the user call for disconnection, the stack shuts down itself. |
borlanic | 0:fbdae7e6d805 | 365 | * |
borlanic | 0:fbdae7e6d805 | 366 | * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. |
borlanic | 0:fbdae7e6d805 | 367 | */ |
borlanic | 0:fbdae7e6d805 | 368 | lorawan_status_t shutdown(); |
borlanic | 0:fbdae7e6d805 | 369 | |
borlanic | 0:fbdae7e6d805 | 370 | /** Change device class |
borlanic | 0:fbdae7e6d805 | 371 | * |
borlanic | 0:fbdae7e6d805 | 372 | * Change current device class. |
borlanic | 0:fbdae7e6d805 | 373 | * |
borlanic | 0:fbdae7e6d805 | 374 | * @param device_class The device class |
borlanic | 0:fbdae7e6d805 | 375 | * |
borlanic | 0:fbdae7e6d805 | 376 | * @return LORAWAN_STATUS_OK on success, |
borlanic | 0:fbdae7e6d805 | 377 | * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, |
borlanic | 0:fbdae7e6d805 | 378 | * or other negative error code if request failed. |
borlanic | 0:fbdae7e6d805 | 379 | */ |
borlanic | 0:fbdae7e6d805 | 380 | lorawan_status_t set_device_class(const device_class_t& device_class); |
borlanic | 0:fbdae7e6d805 | 381 | |
borlanic | 0:fbdae7e6d805 | 382 | void lock(void) { _loramac.lock(); } |
borlanic | 0:fbdae7e6d805 | 383 | void unlock(void) { _loramac.unlock(); } |
borlanic | 0:fbdae7e6d805 | 384 | |
borlanic | 0:fbdae7e6d805 | 385 | private: |
borlanic | 0:fbdae7e6d805 | 386 | typedef mbed::ScopedLock<LoRaWANStack> Lock; |
borlanic | 0:fbdae7e6d805 | 387 | /** |
borlanic | 0:fbdae7e6d805 | 388 | * Checks if the user provided port is valid or not |
borlanic | 0:fbdae7e6d805 | 389 | */ |
borlanic | 0:fbdae7e6d805 | 390 | bool is_port_valid(uint8_t port, bool allow_port_0 = false); |
borlanic | 0:fbdae7e6d805 | 391 | |
borlanic | 0:fbdae7e6d805 | 392 | /** |
borlanic | 0:fbdae7e6d805 | 393 | * State machine for stack controller layer. |
borlanic | 0:fbdae7e6d805 | 394 | */ |
borlanic | 0:fbdae7e6d805 | 395 | lorawan_status_t state_controller(device_states_t new_state); |
borlanic | 0:fbdae7e6d805 | 396 | |
borlanic | 0:fbdae7e6d805 | 397 | /** |
borlanic | 0:fbdae7e6d805 | 398 | * Helpers for state controller |
borlanic | 0:fbdae7e6d805 | 399 | */ |
borlanic | 0:fbdae7e6d805 | 400 | void process_uninitialized_state(lorawan_status_t& op_status); |
borlanic | 0:fbdae7e6d805 | 401 | void process_idle_state(lorawan_status_t& op_status); |
borlanic | 0:fbdae7e6d805 | 402 | void process_connected_state(); |
borlanic | 0:fbdae7e6d805 | 403 | void process_connecting_state(lorawan_status_t& op_status); |
borlanic | 0:fbdae7e6d805 | 404 | void process_joining_state(lorawan_status_t& op_status); |
borlanic | 0:fbdae7e6d805 | 405 | void process_scheduling_state(lorawan_status_t& op_status); |
borlanic | 0:fbdae7e6d805 | 406 | void process_status_check_state(); |
borlanic | 0:fbdae7e6d805 | 407 | void process_shutdown_state(lorawan_status_t& op_status); |
borlanic | 0:fbdae7e6d805 | 408 | void state_machine_run_to_completion(void); |
borlanic | 0:fbdae7e6d805 | 409 | |
borlanic | 0:fbdae7e6d805 | 410 | /** |
borlanic | 0:fbdae7e6d805 | 411 | * Handles MLME indications |
borlanic | 0:fbdae7e6d805 | 412 | */ |
borlanic | 0:fbdae7e6d805 | 413 | void mlme_indication_handler(void); |
borlanic | 0:fbdae7e6d805 | 414 | |
borlanic | 0:fbdae7e6d805 | 415 | /** |
borlanic | 0:fbdae7e6d805 | 416 | * Handles an MLME confirmation |
borlanic | 0:fbdae7e6d805 | 417 | */ |
borlanic | 0:fbdae7e6d805 | 418 | void mlme_confirm_handler(void); |
borlanic | 0:fbdae7e6d805 | 419 | |
borlanic | 0:fbdae7e6d805 | 420 | /** |
borlanic | 0:fbdae7e6d805 | 421 | * Handles an MCPS confirmation |
borlanic | 0:fbdae7e6d805 | 422 | */ |
borlanic | 0:fbdae7e6d805 | 423 | void mcps_confirm_handler(void); |
borlanic | 0:fbdae7e6d805 | 424 | |
borlanic | 0:fbdae7e6d805 | 425 | /** |
borlanic | 0:fbdae7e6d805 | 426 | * Handles an MCPS indication |
borlanic | 0:fbdae7e6d805 | 427 | */ |
borlanic | 0:fbdae7e6d805 | 428 | void mcps_indication_handler(void); |
borlanic | 0:fbdae7e6d805 | 429 | |
borlanic | 0:fbdae7e6d805 | 430 | /** |
borlanic | 0:fbdae7e6d805 | 431 | * Sets up user application port |
borlanic | 0:fbdae7e6d805 | 432 | */ |
borlanic | 0:fbdae7e6d805 | 433 | lorawan_status_t set_application_port(uint8_t port, bool allow_port_0 = false); |
borlanic | 0:fbdae7e6d805 | 434 | |
borlanic | 0:fbdae7e6d805 | 435 | /** |
borlanic | 0:fbdae7e6d805 | 436 | * Handles connection internally |
borlanic | 0:fbdae7e6d805 | 437 | */ |
borlanic | 0:fbdae7e6d805 | 438 | lorawan_status_t handle_connect(bool is_otaa); |
borlanic | 0:fbdae7e6d805 | 439 | |
borlanic | 0:fbdae7e6d805 | 440 | |
borlanic | 0:fbdae7e6d805 | 441 | /** Send event to application. |
borlanic | 0:fbdae7e6d805 | 442 | * |
borlanic | 0:fbdae7e6d805 | 443 | * @param event The event to be sent. |
borlanic | 0:fbdae7e6d805 | 444 | */ |
borlanic | 0:fbdae7e6d805 | 445 | void send_event_to_application(const lorawan_event_t event) const; |
borlanic | 0:fbdae7e6d805 | 446 | |
borlanic | 0:fbdae7e6d805 | 447 | /** Send empty uplink message to network. |
borlanic | 0:fbdae7e6d805 | 448 | * |
borlanic | 0:fbdae7e6d805 | 449 | * Sends an empty confirmed message to gateway. |
borlanic | 0:fbdae7e6d805 | 450 | * |
borlanic | 0:fbdae7e6d805 | 451 | * @param port The event to be sent. |
borlanic | 0:fbdae7e6d805 | 452 | */ |
borlanic | 0:fbdae7e6d805 | 453 | void send_automatic_uplink_message(uint8_t port); |
borlanic | 0:fbdae7e6d805 | 454 | |
borlanic | 0:fbdae7e6d805 | 455 | /** |
borlanic | 0:fbdae7e6d805 | 456 | * TX interrupt handlers and corresponding processors |
borlanic | 0:fbdae7e6d805 | 457 | */ |
borlanic | 0:fbdae7e6d805 | 458 | void tx_interrupt_handler(void); |
borlanic | 0:fbdae7e6d805 | 459 | void tx_timeout_interrupt_handler(void); |
borlanic | 0:fbdae7e6d805 | 460 | void process_transmission(void); |
borlanic | 0:fbdae7e6d805 | 461 | void process_transmission_timeout(void); |
borlanic | 0:fbdae7e6d805 | 462 | |
borlanic | 0:fbdae7e6d805 | 463 | /** |
borlanic | 0:fbdae7e6d805 | 464 | * RX interrupt handlers and corresponding processors |
borlanic | 0:fbdae7e6d805 | 465 | */ |
borlanic | 0:fbdae7e6d805 | 466 | void rx_interrupt_handler(const uint8_t *payload, uint16_t size, int16_t rssi, |
borlanic | 0:fbdae7e6d805 | 467 | int8_t snr); |
borlanic | 0:fbdae7e6d805 | 468 | void rx_timeout_interrupt_handler(void); |
borlanic | 0:fbdae7e6d805 | 469 | void rx_error_interrupt_handler(void); |
borlanic | 0:fbdae7e6d805 | 470 | void process_reception(const uint8_t *payload, uint16_t size, int16_t rssi, |
borlanic | 0:fbdae7e6d805 | 471 | int8_t snr); |
borlanic | 0:fbdae7e6d805 | 472 | void process_reception_timeout(bool is_timeout); |
borlanic | 0:fbdae7e6d805 | 473 | |
borlanic | 0:fbdae7e6d805 | 474 | int convert_to_msg_flag(const mcps_type_t type); |
borlanic | 0:fbdae7e6d805 | 475 | |
borlanic | 0:fbdae7e6d805 | 476 | private: |
borlanic | 0:fbdae7e6d805 | 477 | LoRaMac _loramac; |
borlanic | 0:fbdae7e6d805 | 478 | radio_events_t radio_events; |
borlanic | 0:fbdae7e6d805 | 479 | device_states_t _device_current_state; |
borlanic | 0:fbdae7e6d805 | 480 | lorawan_app_callbacks_t _callbacks; |
borlanic | 0:fbdae7e6d805 | 481 | lorawan_session_t _lw_session; |
borlanic | 0:fbdae7e6d805 | 482 | loramac_tx_message_t _tx_msg; |
borlanic | 0:fbdae7e6d805 | 483 | loramac_rx_message_t _rx_msg; |
borlanic | 0:fbdae7e6d805 | 484 | uint8_t _num_retry; |
borlanic | 0:fbdae7e6d805 | 485 | uint32_t _ctrl_flags; |
borlanic | 0:fbdae7e6d805 | 486 | uint8_t _app_port; |
borlanic | 0:fbdae7e6d805 | 487 | bool _link_check_requested; |
borlanic | 0:fbdae7e6d805 | 488 | bool _automatic_uplink_ongoing; |
borlanic | 0:fbdae7e6d805 | 489 | volatile bool _ready_for_rx; |
borlanic | 0:fbdae7e6d805 | 490 | uint8_t _rx_payload[LORAMAC_PHY_MAXPAYLOAD]; |
borlanic | 0:fbdae7e6d805 | 491 | events::EventQueue *_queue; |
borlanic | 0:fbdae7e6d805 | 492 | |
borlanic | 0:fbdae7e6d805 | 493 | #if defined(LORAWAN_COMPLIANCE_TEST) |
borlanic | 0:fbdae7e6d805 | 494 | |
borlanic | 0:fbdae7e6d805 | 495 | /** |
borlanic | 0:fbdae7e6d805 | 496 | * Used only for compliance testing |
borlanic | 0:fbdae7e6d805 | 497 | */ |
borlanic | 0:fbdae7e6d805 | 498 | void compliance_test_handler(loramac_mcps_indication_t *mcps_indication); |
borlanic | 0:fbdae7e6d805 | 499 | |
borlanic | 0:fbdae7e6d805 | 500 | /** |
borlanic | 0:fbdae7e6d805 | 501 | * Used only for compliance testing |
borlanic | 0:fbdae7e6d805 | 502 | */ |
borlanic | 0:fbdae7e6d805 | 503 | lorawan_status_t send_compliance_test_frame_to_mac(); |
borlanic | 0:fbdae7e6d805 | 504 | |
borlanic | 0:fbdae7e6d805 | 505 | compliance_test_t _compliance_test; |
borlanic | 0:fbdae7e6d805 | 506 | #endif |
borlanic | 0:fbdae7e6d805 | 507 | }; |
borlanic | 0:fbdae7e6d805 | 508 | |
borlanic | 0:fbdae7e6d805 | 509 | #endif /* LORAWANSTACK_H_ */ |