BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

UserRevisionLine numberNew 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_ */