1 /* 2 * Copyright (c) 2020 Manivannan Sadhasivam <mani@kernel.org> 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_ 8 #define ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_ 9 10 /** 11 * @file 12 * @brief Public LoRaWAN APIs 13 * @defgroup lorawan_api LoRaWAN APIs 14 * @ingroup connectivity 15 * @{ 16 */ 17 18 #include <zephyr/device.h> 19 #include <zephyr/sys/slist.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /** 26 * @brief LoRaWAN class types. 27 */ 28 enum lorawan_class { 29 LORAWAN_CLASS_A = 0x00, 30 LORAWAN_CLASS_B = 0x01, 31 LORAWAN_CLASS_C = 0x02, 32 }; 33 34 /** 35 * @brief LoRaWAN activation types. 36 */ 37 enum lorawan_act_type { 38 LORAWAN_ACT_OTAA = 0, 39 LORAWAN_ACT_ABP, 40 }; 41 42 /** 43 * @brief LoRaWAN datarate types. 44 */ 45 enum lorawan_datarate { 46 LORAWAN_DR_0 = 0, 47 LORAWAN_DR_1, 48 LORAWAN_DR_2, 49 LORAWAN_DR_3, 50 LORAWAN_DR_4, 51 LORAWAN_DR_5, 52 LORAWAN_DR_6, 53 LORAWAN_DR_7, 54 LORAWAN_DR_8, 55 LORAWAN_DR_9, 56 LORAWAN_DR_10, 57 LORAWAN_DR_11, 58 LORAWAN_DR_12, 59 LORAWAN_DR_13, 60 LORAWAN_DR_14, 61 LORAWAN_DR_15, 62 }; 63 64 /** 65 * @brief LoRaWAN region types. 66 */ 67 enum lorawan_region { 68 LORAWAN_REGION_AS923, 69 LORAWAN_REGION_AU915, 70 LORAWAN_REGION_CN470, 71 LORAWAN_REGION_CN779, 72 LORAWAN_REGION_EU433, 73 LORAWAN_REGION_EU868, 74 LORAWAN_REGION_KR920, 75 LORAWAN_REGION_IN865, 76 LORAWAN_REGION_US915, 77 LORAWAN_REGION_RU864, 78 }; 79 80 /** 81 * @brief LoRaWAN message types. 82 */ 83 enum lorawan_message_type { 84 LORAWAN_MSG_UNCONFIRMED = 0, 85 LORAWAN_MSG_CONFIRMED, 86 }; 87 88 /** 89 * @brief LoRaWAN join parameters for over-the-Air activation (OTAA) 90 * 91 * Note that all of the fields use LoRaWAN 1.1 terminology. 92 * 93 * All parameters are optional if a secure element is present in which 94 * case the values stored in the secure element will be used instead. 95 */ 96 struct lorawan_join_otaa { 97 /** Join EUI */ 98 uint8_t *join_eui; 99 /** Network Key */ 100 uint8_t *nwk_key; 101 /** Application Key */ 102 uint8_t *app_key; 103 /** 104 * Device Nonce 105 * 106 * Starting with LoRaWAN 1.0.4 the DevNonce must be monotonically 107 * increasing for each OTAA join with the same EUI. The DevNonce 108 * should be stored in non-volatile memory by the application. 109 */ 110 uint16_t dev_nonce; 111 }; 112 113 /** 114 * @brief LoRaWAN join parameters for activation by personalization (ABP) 115 */ 116 struct lorawan_join_abp { 117 /** Device address on the network */ 118 uint32_t dev_addr; 119 /** Application session key */ 120 uint8_t *app_skey; 121 /** Network session key */ 122 uint8_t *nwk_skey; 123 /** Application EUI */ 124 uint8_t *app_eui; 125 }; 126 127 /** 128 * @brief LoRaWAN join parameters 129 */ 130 struct lorawan_join_config { 131 union { 132 struct lorawan_join_otaa otaa; 133 struct lorawan_join_abp abp; 134 }; 135 136 /** Device EUI. Optional if a secure element is present. */ 137 uint8_t *dev_eui; 138 139 /** Activation mode */ 140 enum lorawan_act_type mode; 141 }; 142 143 #define LW_RECV_PORT_ANY UINT16_MAX 144 145 /** 146 * @brief LoRaWAN downlink callback parameters 147 */ 148 struct lorawan_downlink_cb { 149 /** 150 * @brief Port to handle messages for. 151 * 152 * - Port 0: TX packet acknowledgements 153 * - Ports 1-255: Standard downlink port 154 * - LW_RECV_PORT_ANY: All downlinks 155 */ 156 uint16_t port; 157 /** 158 * @brief Callback function to run on downlink data 159 * 160 * @note Callbacks are run on the system workqueue, 161 * and should therefore be as short as possible. 162 * 163 * @param port Port message was sent on 164 * @param data_pending Network server has more downlink packets pending 165 * @param rssi Received signal strength in dBm 166 * @param snr Signal to Noise ratio in dBm 167 * @param len Length of data received, will be 0 for ACKs 168 * @param data Data received, will be NULL for ACKs 169 */ 170 void (*cb)(uint8_t port, bool data_pending, 171 int16_t rssi, int8_t snr, 172 uint8_t len, const uint8_t *data); 173 /** Node for callback list */ 174 sys_snode_t node; 175 }; 176 177 /** 178 * @brief Add battery level callback function. 179 * 180 * Provide the LoRaWAN stack with a function to be called whenever a battery 181 * level needs to be read. As per LoRaWAN specification the callback needs to 182 * return "0: node is connected to an external power source, 183 * 1..254: battery level, where 1 is the minimum and 254 is the maximum 184 * value, 185 * 255: the node was not able to measure the battery level" 186 * 187 * Should no callback be provided the lorawan backend will report 255. 188 * 189 * @param battery_lvl_cb Pointer to the battery level function 190 * 191 * @return 0 if successful, negative errno code if failure 192 */ 193 int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void)); 194 195 /** 196 * @brief Register a callback to be run on downlink packets 197 * 198 * @param cb Pointer to structure containing callback parameters 199 */ 200 void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb); 201 202 /** 203 * @brief Register a callback to be called when the datarate changes 204 * 205 * The callback is called once upon successfully joining a network and again 206 * each time the datarate changes due to ADR. 207 * 208 * The callback function takes one parameter: 209 * - dr - updated datarate 210 * 211 * @param dr_cb Pointer to datarate update callback 212 */ 213 void lorawan_register_dr_changed_callback(void (*dr_cb)(enum lorawan_datarate)); 214 215 /** 216 * @brief Join the LoRaWAN network 217 * 218 * Join the LoRaWAN network using OTAA or AWB. 219 * 220 * @param config Configuration to be used 221 * 222 * @return 0 if successful, negative errno code if failure 223 */ 224 int lorawan_join(const struct lorawan_join_config *config); 225 226 /** 227 * @brief Start the LoRaWAN stack 228 * 229 * This function need to be called before joining the network. 230 * 231 * @return 0 if successful, negative errno code if failure 232 */ 233 int lorawan_start(void); 234 235 /** 236 * @brief Send data to the LoRaWAN network 237 * 238 * Send data to the connected LoRaWAN network. 239 * 240 * @param port Port to be used for sending data. Must be set if the 241 * payload is not empty. 242 * @param data Data buffer to be sent 243 * @param len Length of the buffer to be sent. Maximum length of this 244 * buffer is 255 bytes but the actual payload size varies with 245 * region and datarate. 246 * @param type Specifies if the message shall be confirmed or unconfirmed. 247 * Must be one of @ref lorawan_message_type. 248 * 249 * @return 0 if successful, negative errno code if failure 250 */ 251 int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, enum lorawan_message_type type); 252 253 /** 254 * @brief Set the current device class 255 * 256 * Change the current device class. This function may be called before 257 * or after a network connection has been established. 258 * 259 * @param dev_class New device class 260 * 261 * @return 0 if successful, negative errno code if failure 262 */ 263 int lorawan_set_class(enum lorawan_class dev_class); 264 265 /** 266 * @brief Set the number of tries used for transmissions 267 * 268 * @param tries Number of tries to be used 269 * 270 * @return 0 if successful, negative errno code if failure 271 */ 272 int lorawan_set_conf_msg_tries(uint8_t tries); 273 274 /** 275 * @brief Enable Adaptive Data Rate (ADR) 276 * 277 * Control whether adaptive data rate (ADR) is enabled. When ADR is enabled, 278 * the data rate is treated as a default data rate that will be used if the 279 * ADR algorithm has not established a data rate. ADR should normally only 280 * be enabled for devices with stable RF conditions (i.e., devices in a mostly 281 * static location). 282 * 283 * @param enable Enable or Disable adaptive data rate. 284 */ 285 void lorawan_enable_adr(bool enable); 286 287 /** 288 * @brief Set the default data rate 289 * 290 * Change the default data rate. 291 * 292 * @param dr Data rate used for transmissions 293 * 294 * @return 0 if successful, negative errno code if failure 295 */ 296 int lorawan_set_datarate(enum lorawan_datarate dr); 297 298 /** 299 * @brief Get the minimum possible datarate 300 * 301 * The minimum possible datarate may change in response to a TxParamSetupReq 302 * command from the network server. 303 * 304 * @return Minimum possible data rate 305 */ 306 enum lorawan_datarate lorawan_get_min_datarate(void); 307 308 /** 309 * @brief Get the current payload sizes 310 * 311 * Query the current payload sizes. The maximum payload size varies with 312 * datarate, while the current payload size can be less due to MAC layer 313 * commands which are inserted into uplink packets. 314 * 315 * @param max_next_payload_size Maximum payload size for the next transmission 316 * @param max_payload_size Maximum payload size for this datarate 317 */ 318 void lorawan_get_payload_sizes(uint8_t *max_next_payload_size, 319 uint8_t *max_payload_size); 320 321 /** 322 * @brief Set the region and frequency to be used 323 * 324 * Control the LoRa region and frequency settings. This should be called before 325 * @a lorawan_start(). If you only have support for a single region selected via 326 * Kconfig, this function does not need to be called at all. 327 * 328 * @param region The region to be selected 329 * @return 0 if successful, negative errno otherwise 330 */ 331 int lorawan_set_region(enum lorawan_region region); 332 333 #ifdef CONFIG_LORAWAN_APP_CLOCK_SYNC 334 335 /** 336 * @brief Run Application Layer Clock Synchronization service 337 * 338 * This service sends out its current time in a regular interval (configurable 339 * via Kconfig) and receives a correction offset from the application server if 340 * the clock deviation is considered too large. 341 * 342 * Clock synchronization is required for firmware upgrades over multicast 343 * sessions, but can also be used independent of a FUOTA process. 344 * 345 * @return 0 if successful, negative errno otherwise. 346 */ 347 int lorawan_clock_sync_run(void); 348 349 /** 350 * @brief Retrieve the current synchronized time 351 * 352 * This function uses the GPS epoch format, as used in all LoRaWAN services. 353 * 354 * The GPS epoch started on 1980-01-06T00:00:00Z, but has since diverged 355 * from UTC, as it does not consider corrections like leap seconds. 356 * 357 * @param gps_time Synchronized time in GPS epoch format truncated to 32-bit. 358 * 359 * @return 0 if successful, -EAGAIN if the clock is not yet synchronized. 360 */ 361 int lorawan_clock_sync_get(uint32_t *gps_time); 362 363 #endif /* CONFIG_LORAWAN_APP_CLOCK_SYNC */ 364 365 #ifdef __cplusplus 366 } 367 #endif 368 369 /** 370 * @} 371 */ 372 373 #endif /* ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_ */ 374