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 */ 14 15 #include <device.h> 16 #include <sys/slist.h> 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 /** 23 * @brief LoRaWAN class types. 24 */ 25 enum lorawan_class { 26 LORAWAN_CLASS_A = 0x00, 27 LORAWAN_CLASS_B = 0x01, 28 LORAWAN_CLASS_C = 0x02, 29 }; 30 31 /** 32 * @brief LoRaWAN activation types. 33 */ 34 enum lorawan_act_type { 35 LORAWAN_ACT_OTAA = 0, 36 LORAWAN_ACT_ABP, 37 }; 38 39 /** 40 * @brief LoRaWAN datarate types. 41 */ 42 enum lorawan_datarate { 43 LORAWAN_DR_0 = 0, 44 LORAWAN_DR_1, 45 LORAWAN_DR_2, 46 LORAWAN_DR_3, 47 LORAWAN_DR_4, 48 LORAWAN_DR_5, 49 LORAWAN_DR_6, 50 LORAWAN_DR_7, 51 LORAWAN_DR_8, 52 LORAWAN_DR_9, 53 LORAWAN_DR_10, 54 LORAWAN_DR_11, 55 LORAWAN_DR_12, 56 LORAWAN_DR_13, 57 LORAWAN_DR_14, 58 LORAWAN_DR_15, 59 }; 60 61 /** 62 * @brief LoRaWAN message types. 63 * 64 * Note: The default message type is unconfirmed. 65 */ 66 enum lorawan_message_type { 67 LORAWAN_MSG_CONFIRMED = BIT(0), 68 }; 69 70 /** 71 * @brief LoRaWAN join parameters for over-the-Air activation (OTAA) 72 * 73 * Note that all of the fields use LoRaWAN 1.1 terminology. 74 * 75 * All parameters are optional if a secure element is present in which 76 * case the values stored in the secure element will be used instead. 77 */ 78 struct lorawan_join_otaa { 79 uint8_t *join_eui; 80 uint8_t *nwk_key; 81 uint8_t *app_key; 82 }; 83 84 struct lorawan_join_abp { 85 /** Device address on the network */ 86 uint32_t dev_addr; 87 /** Application session key */ 88 uint8_t *app_skey; 89 /** Network session key */ 90 uint8_t *nwk_skey; 91 /** Application EUI */ 92 uint8_t *app_eui; 93 }; 94 95 struct lorawan_join_config { 96 union { 97 struct lorawan_join_otaa otaa; 98 struct lorawan_join_abp abp; 99 }; 100 101 /** Device EUI. Optional if a secure element is present. */ 102 uint8_t *dev_eui; 103 104 enum lorawan_act_type mode; 105 }; 106 107 #define LW_RECV_PORT_ANY UINT16_MAX 108 109 struct lorawan_downlink_cb { 110 /* Port to handle messages for: 111 * Port 0: TX packet acknowledgements 112 * Ports 1-255: Standard downlink port 113 * LW_RECV_PORT_ANY: All downlinks 114 */ 115 uint16_t port; 116 /** 117 * @brief Callback function to run on downlink data 118 * 119 * @note Callbacks are run on the system workqueue, 120 * and should therefore be as short as possible. 121 * 122 * @param port Port message was sent on 123 * @param data_pending Network server has more downlink packets pending 124 * @param rssi Received signal strength in dBm 125 * @param snr Signal to Noise ratio in dBm 126 * @param len Length of data received, will be 0 for ACKs 127 * @param data Data received, will be NULL for ACKs 128 */ 129 void (*cb)(uint8_t port, bool data_pending, 130 int16_t rssi, int8_t snr, 131 uint8_t len, const uint8_t *data); 132 /** Node for callback list */ 133 sys_snode_t node; 134 }; 135 136 /** 137 * @brief Add battery level callback function. 138 * 139 * Provide the LoRaWAN stack with a function to be called whenever a battery 140 * level needs to be read. As per LoRaWAN specification the callback needs to 141 * return "0: node is connected to an external power source, 142 * 1..254: battery level, where 1 is the minimum and 254 is the maximum 143 * value, 144 * 255: the node was not able to measure the battery level" 145 * 146 * Should no callback be provided the lorawan backend will report 255. 147 * 148 * @param battery_lvl_cb Pointer to the battery level function 149 * 150 * @return 0 if successful, negative errno code if failure 151 */ 152 int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void)); 153 154 /** 155 * @brief Register a callback to be run on downlink packets 156 * 157 * @param cb Pointer to structure containing callback parameters 158 */ 159 void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb); 160 161 /** 162 * @brief Register a callback to be called when the datarate changes 163 * 164 * The callback is called once upon successfully joining a network and again 165 * each time the datarate changes due to ADR. 166 * 167 * The callback function takes one parameter: 168 * - dr - updated datarate 169 * 170 * @param dr_cb Pointer to datarate update callback 171 */ 172 void lorawan_register_dr_changed_callback(void (*dr_cb)(enum lorawan_datarate)); 173 174 /** 175 * @brief Join the LoRaWAN network 176 * 177 * Join the LoRaWAN network using OTAA or AWB. 178 * 179 * @param config Configuration to be used 180 * 181 * @return 0 if successful, negative errno code if failure 182 */ 183 int lorawan_join(const struct lorawan_join_config *config); 184 185 /** 186 * @brief Start the LoRaWAN stack 187 * 188 * This function need to be called before joining the network. 189 * 190 * @return 0 if successful, negative errno code if failure 191 */ 192 int lorawan_start(void); 193 194 /** 195 * @brief Send data to the LoRaWAN network 196 * 197 * Send data to the connected LoRaWAN network. 198 * 199 * @param port Port to be used for sending data. Must be set if the 200 * payload is not empty. 201 * @param data Data buffer to be sent 202 * @param len Length of the buffer to be sent. Maximum length of this 203 * buffer is 255 bytes but the actual payload size varies with 204 * region and datarate. 205 * @param flags Flag used to determine the type of message being sent. It 206 * could be one of the lorawan_message_type. The default 207 * behaviour is unconfirmed message. 208 * 209 * @return 0 if successful, negative errno code if failure 210 */ 211 int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, uint8_t flags); 212 213 /** 214 * @brief Set the current device class 215 * 216 * Change the current device class. This function may be called before 217 * or after a network connection has been established. 218 * 219 * @param dev_class New device class 220 * 221 * @return 0 if successful, negative errno code if failure 222 */ 223 int lorawan_set_class(enum lorawan_class dev_class); 224 225 /** 226 * @brief Set the number of tries used for transmissions 227 * 228 * @param tries Number of tries to be used 229 * 230 * @return 0 if successful, negative errno code if failure 231 */ 232 int lorawan_set_conf_msg_tries(uint8_t tries); 233 234 /** 235 * @brief Enable Adaptive Data Rate (ADR) 236 * 237 * Control whether adaptive data rate (ADR) is enabled. When ADR is enabled, 238 * the data rate is treated as a default data rate that will be used if the 239 * ADR algorithm has not established a data rate. ADR should normally only 240 * be enabled for devices with stable RF conditions (i.e., devices in a mostly 241 * static location). 242 * 243 * @param enable Enable or Disable adaptive data rate. 244 */ 245 void lorawan_enable_adr(bool enable); 246 247 /** 248 * @brief Set the default data rate 249 * 250 * Change the default data rate. 251 * 252 * @param dr Data rate used for transmissions 253 * 254 * @return 0 if successful, negative errno code if failure 255 */ 256 int lorawan_set_datarate(enum lorawan_datarate dr); 257 258 /** 259 * @brief Get the minimum possible datarate 260 * 261 * The minimum possible datarate may change in response to a TxParamSetupReq 262 * command from the network server. 263 * 264 * @return Minimum possible data rate 265 */ 266 enum lorawan_datarate lorawan_get_min_datarate(void); 267 268 /** 269 * @brief Get the current payload sizes 270 * 271 * Query the current payload sizes. The maximum payload size varies with 272 * datarate, while the current payload size can be less due to MAC layer 273 * commands which are inserted into uplink packets. 274 * 275 * @param max_next_payload_size Maximum payload size for the next transmission 276 * @param max_payload_size Maximum payload size for this datarate 277 */ 278 void lorawan_get_payload_sizes(uint8_t *max_next_payload_size, 279 uint8_t *max_payload_size); 280 281 #ifdef __cplusplus 282 } 283 #endif 284 285 #endif /* ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_ */ 286