Line data Source code
1 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 : * @since 2.5
15 : * @version 0.1.0
16 : * @ingroup connectivity
17 : * @{
18 : */
19 :
20 : #include <zephyr/device.h>
21 : #include <zephyr/sys/slist.h>
22 :
23 : #ifdef __cplusplus
24 : extern "C" {
25 : #endif
26 :
27 : /**
28 : * @brief LoRaWAN class types.
29 : */
30 1 : enum lorawan_class {
31 : LORAWAN_CLASS_A = 0x00, /**< Class A device */
32 : LORAWAN_CLASS_B = 0x01, /**< Class B device */
33 : LORAWAN_CLASS_C = 0x02, /**< Class C device */
34 : };
35 :
36 : /**
37 : * @brief LoRaWAN activation types.
38 : */
39 1 : enum lorawan_act_type {
40 : LORAWAN_ACT_OTAA = 0, /**< Over-the-Air Activation (OTAA) */
41 : LORAWAN_ACT_ABP, /**< Activation by Personalization (ABP) */
42 : };
43 :
44 : /**
45 : * @brief LoRaWAN channels mask sizes.
46 : */
47 1 : enum lorawan_channels_mask_size {
48 : LORAWAN_CHANNELS_MASK_SIZE_AS923 = 1, /**< Region AS923 mask size */
49 : LORAWAN_CHANNELS_MASK_SIZE_AU915 = 6, /**< Region AU915 mask size */
50 : LORAWAN_CHANNELS_MASK_SIZE_CN470 = 6, /**< Region CN470 mask size */
51 : LORAWAN_CHANNELS_MASK_SIZE_CN779 = 1, /**< Region CN779 mask size */
52 : LORAWAN_CHANNELS_MASK_SIZE_EU433 = 1, /**< Region EU433 mask size */
53 : LORAWAN_CHANNELS_MASK_SIZE_EU868 = 1, /**< Region EU868 mask size */
54 : LORAWAN_CHANNELS_MASK_SIZE_KR920 = 1, /**< Region KR920 mask size */
55 : LORAWAN_CHANNELS_MASK_SIZE_IN865 = 1, /**< Region IN865 mask size */
56 : LORAWAN_CHANNELS_MASK_SIZE_US915 = 6, /**< Region US915 mask size */
57 : LORAWAN_CHANNELS_MASK_SIZE_RU864 = 1, /**< Region RU864 mask size */
58 : };
59 :
60 : /**
61 : * @brief LoRaWAN datarate types.
62 : */
63 1 : enum lorawan_datarate {
64 : LORAWAN_DR_0 = 0, /**< DR0 data rate */
65 : LORAWAN_DR_1, /**< DR1 data rate */
66 : LORAWAN_DR_2, /**< DR2 data rate */
67 : LORAWAN_DR_3, /**< DR3 data rate */
68 : LORAWAN_DR_4, /**< DR4 data rate */
69 : LORAWAN_DR_5, /**< DR5 data rate */
70 : LORAWAN_DR_6, /**< DR6 data rate */
71 : LORAWAN_DR_7, /**< DR7 data rate */
72 : LORAWAN_DR_8, /**< DR8 data rate */
73 : LORAWAN_DR_9, /**< DR9 data rate */
74 : LORAWAN_DR_10, /**< DR10 data rate */
75 : LORAWAN_DR_11, /**< DR11 data rate */
76 : LORAWAN_DR_12, /**< DR12 data rate */
77 : LORAWAN_DR_13, /**< DR13 data rate */
78 : LORAWAN_DR_14, /**< DR14 data rate */
79 : LORAWAN_DR_15, /**< DR15 data rate */
80 : };
81 :
82 : /**
83 : * @brief LoRaWAN region types.
84 : */
85 1 : enum lorawan_region {
86 : LORAWAN_REGION_AS923, /**< Asia 923 MHz frequency band */
87 : LORAWAN_REGION_AU915, /**< Australia 915 MHz frequency band */
88 : LORAWAN_REGION_CN470, /**< China 470 MHz frequency band */
89 : LORAWAN_REGION_CN779, /**< China 779 MHz frequency band */
90 : LORAWAN_REGION_EU433, /**< Europe 433 MHz frequency band */
91 : LORAWAN_REGION_EU868, /**< Europe 868 MHz frequency band */
92 : LORAWAN_REGION_KR920, /**< South Korea 920 MHz frequency band */
93 : LORAWAN_REGION_IN865, /**< India 865 MHz frequency band */
94 : LORAWAN_REGION_US915, /**< United States 915 MHz frequency band */
95 : LORAWAN_REGION_RU864, /**< Russia 864 MHz frequency band */
96 : };
97 :
98 : /**
99 : * @brief LoRaWAN message types.
100 : */
101 1 : enum lorawan_message_type {
102 : LORAWAN_MSG_UNCONFIRMED = 0, /**< Unconfirmed message */
103 : LORAWAN_MSG_CONFIRMED, /**< Confirmed message */
104 : };
105 :
106 : /**
107 : * @brief LoRaWAN downlink flags.
108 : */
109 0 : enum lorawan_dl_flags {
110 : LORAWAN_DATA_PENDING = BIT(0),
111 : LORAWAN_TIME_UPDATED = BIT(1),
112 : };
113 :
114 : /**
115 : * @brief LoRaWAN join parameters for over-the-Air activation (OTAA)
116 : *
117 : * Note that all of the fields use LoRaWAN 1.1 terminology.
118 : *
119 : * All parameters are optional if a secure element is present in which
120 : * case the values stored in the secure element will be used instead.
121 : */
122 1 : struct lorawan_join_otaa {
123 : /** Join EUI */
124 1 : uint8_t *join_eui;
125 : /** Network Key */
126 1 : uint8_t *nwk_key;
127 : /** Application Key */
128 1 : uint8_t *app_key;
129 : /**
130 : * Device Nonce
131 : *
132 : * Starting with LoRaWAN 1.0.4 the DevNonce must be monotonically
133 : * increasing for each OTAA join with the same EUI. The DevNonce
134 : * should be stored in non-volatile memory by the application.
135 : */
136 1 : uint16_t dev_nonce;
137 : };
138 :
139 : /**
140 : * @brief LoRaWAN join parameters for activation by personalization (ABP)
141 : */
142 1 : struct lorawan_join_abp {
143 : /** Device address on the network */
144 1 : uint32_t dev_addr;
145 : /** Application session key */
146 1 : uint8_t *app_skey;
147 : /** Network session key */
148 1 : uint8_t *nwk_skey;
149 : /** Application EUI */
150 1 : uint8_t *app_eui;
151 : };
152 :
153 : /**
154 : * @brief LoRaWAN join parameters
155 : */
156 1 : struct lorawan_join_config {
157 : /** Join parameters */
158 : union {
159 1 : struct lorawan_join_otaa otaa; /**< OTAA join parameters */
160 1 : struct lorawan_join_abp abp; /**< ABP join parameters */
161 1 : };
162 :
163 : /** Device EUI. Optional if a secure element is present. */
164 1 : uint8_t *dev_eui;
165 :
166 : /** Activation mode */
167 1 : enum lorawan_act_type mode;
168 : };
169 :
170 : /** Flag to indicate receiving on any port */
171 1 : #define LW_RECV_PORT_ANY UINT16_MAX
172 :
173 : /**
174 : * @brief LoRaWAN downlink callback parameters
175 : */
176 1 : struct lorawan_downlink_cb {
177 : /**
178 : * @brief Port to handle messages for.
179 : *
180 : * - Port 0: TX packet acknowledgements
181 : * - Ports 1-255: Standard downlink port
182 : * - LW_RECV_PORT_ANY: All downlinks
183 : */
184 1 : uint16_t port;
185 : /**
186 : * @brief Callback function to run on downlink data
187 : *
188 : * @note Callbacks are run on the system workqueue,
189 : * and should therefore be as short as possible.
190 : *
191 : * @param port Port message was sent on
192 : * @param flags Downlink data flags (see @ref lorawan_dl_flags)
193 : * @param rssi Received signal strength in dBm
194 : * @param snr Signal to Noise ratio in dBm
195 : * @param len Length of data received, will be 0 for ACKs
196 : * @param data Data received, will be NULL for ACKs
197 : */
198 1 : void (*cb)(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len,
199 : const uint8_t *data);
200 : /** Node for callback list */
201 1 : sys_snode_t node;
202 : };
203 :
204 : /**
205 : * @brief Defines the battery level callback handler function signature.
206 : *
207 : * @retval 0 if the node is connected to an external power source
208 : * @retval 1..254 battery level, where 1 is the minimum and 254 is the maximum value
209 : * @retval 255 if the node was not able to measure the battery level
210 : */
211 1 : typedef uint8_t (*lorawan_battery_level_cb_t)(void);
212 :
213 : /**
214 : * @brief Defines the datarate changed callback handler function signature.
215 : *
216 : * @param dr Updated datarate.
217 : */
218 1 : typedef void (*lorawan_dr_changed_cb_t)(enum lorawan_datarate dr);
219 :
220 : /**
221 : * @brief Defines the link check answer handler function signature.
222 : *
223 : * @param demod_margin The demodulation margin in db.
224 : * @param nb_gateways The number of gateways the device is connected to.
225 : */
226 1 : typedef void (*lorawan_link_check_ans_cb_t)(uint8_t demod_margin, uint8_t nb_gateways);
227 :
228 : /**
229 : * @brief Defines the user's descriptor callback handler function signature.
230 : *
231 : * The use of this callback is optional. When Fragmented Data Block Transport
232 : * is enabled, the application will be notified with the descriptor field present on
233 : * the FragSessionSetupReq command.
234 : *
235 : * @param descriptor Descriptor value given on the FragSessionSetupReq command.
236 : *
237 : * The meaning of Descriptor is application dependent. When doing a FUOTA
238 : * with a binary image, it may represent the version of the firmware
239 : * transported.
240 : *
241 : * @return 0 if successful. This represents, in the case that the descriptor is the firmware
242 : * version, that the end-device is able to receive binary firmware. Otherwise, a negative error code
243 : * (errno.h) indicating the reason for failure. Any negative error code will result in setting
244 : * the Wrong Descriptor status bit mask when sending FragSessionSetupAns to the Network Server.
245 : *
246 : */
247 1 : typedef int (*transport_descriptor_cb)(uint32_t descriptor);
248 :
249 : /**
250 : * @brief Register a battery level callback function.
251 : *
252 : * Provide the LoRaWAN stack with a function to be called whenever a battery
253 : * level needs to be read.
254 : *
255 : * Should no callback be provided the lorawan backend will report 255.
256 : *
257 : * @param cb Pointer to the battery level function
258 : */
259 1 : void lorawan_register_battery_level_callback(lorawan_battery_level_cb_t cb);
260 :
261 : /**
262 : * @brief Register a callback to be run on downlink packets
263 : *
264 : * @param cb Pointer to structure containing callback parameters
265 : */
266 1 : void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb);
267 :
268 : /**
269 : * @brief Register a callback to be called when the datarate changes
270 : *
271 : * The callback is called once upon successfully joining a network and again
272 : * each time the datarate changes due to ADR.
273 : *
274 : * @param cb Pointer to datarate update callback
275 : */
276 1 : void lorawan_register_dr_changed_callback(lorawan_dr_changed_cb_t cb);
277 :
278 : /**
279 : * @brief Register a callback to be called when getting answer
280 : * a to check link request.
281 : *
282 : * @param cb Pointer to link check ans callback
283 : */
284 1 : void lorawan_register_link_check_ans_callback(lorawan_link_check_ans_cb_t cb);
285 :
286 : /**
287 : * @brief Join the LoRaWAN network
288 : *
289 : * Join the LoRaWAN network using OTAA or AWB.
290 : *
291 : * @param config Configuration to be used
292 : *
293 : * @return 0 if successful, negative errno code if failure
294 : */
295 1 : int lorawan_join(const struct lorawan_join_config *config);
296 :
297 : /**
298 : * @brief Start the LoRaWAN stack
299 : *
300 : * This function need to be called before joining the network.
301 : *
302 : * @return 0 if successful, negative errno code if failure
303 : */
304 1 : int lorawan_start(void);
305 :
306 : /**
307 : * @brief Send data to the LoRaWAN network
308 : *
309 : * Send data to the connected LoRaWAN network.
310 : *
311 : * @param port Port to be used for sending data. Must be set if the
312 : * payload is not empty.
313 : * @param data Data buffer to be sent
314 : * @param len Length of the buffer to be sent. Maximum length of this
315 : * buffer is 255 bytes but the actual payload size varies with
316 : * region and datarate.
317 : * @param type Specifies if the message shall be confirmed or unconfirmed.
318 : * Must be one of @ref lorawan_message_type.
319 : *
320 : * @return 0 if successful, negative errno code if failure
321 : */
322 1 : int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, enum lorawan_message_type type);
323 :
324 : /**
325 : * @brief Set the current device class
326 : *
327 : * Change the current device class. This function may be called before
328 : * or after a network connection has been established.
329 : *
330 : * @param dev_class New device class
331 : *
332 : * @return 0 if successful, negative errno code if failure
333 : */
334 1 : int lorawan_set_class(enum lorawan_class dev_class);
335 :
336 : /**
337 : * @brief Set the number of tries used for transmissions
338 : *
339 : * @param tries Number of tries to be used
340 : *
341 : * @return 0 if successful, negative errno code if failure
342 : */
343 1 : int lorawan_set_conf_msg_tries(uint8_t tries);
344 :
345 : /**
346 : * @brief Enable Adaptive Data Rate (ADR)
347 : *
348 : * Control whether adaptive data rate (ADR) is enabled. When ADR is enabled,
349 : * the data rate is treated as a default data rate that will be used if the
350 : * ADR algorithm has not established a data rate. ADR should normally only
351 : * be enabled for devices with stable RF conditions (i.e., devices in a mostly
352 : * static location).
353 : *
354 : * @param enable Enable or Disable adaptive data rate.
355 : */
356 1 : void lorawan_enable_adr(bool enable);
357 :
358 : /**
359 : * @brief Set the channels mask.
360 : *
361 : * Change the default channels mask. When mask is not changed, all the channels
362 : * can be used for data transmission. Some Network Servers don't use all the channels,
363 : * in this case, the channels mask must be provided.
364 : *
365 : * @param channels_mask Buffer with channels mask to be used.
366 : * @param channels_mask_size Size of channels mask buffer.
367 : *
368 : * @retval 0 successful
369 : * @retval -EINVAL channels mask or channels mask size is wrong
370 : */
371 1 : int lorawan_set_channels_mask(uint16_t *channels_mask, size_t channels_mask_size);
372 :
373 : /**
374 : * @brief Set the default data rate
375 : *
376 : * Change the default data rate.
377 : *
378 : * @param dr Data rate used for transmissions
379 : *
380 : * @return 0 if successful, negative errno code if failure
381 : */
382 1 : int lorawan_set_datarate(enum lorawan_datarate dr);
383 :
384 : /**
385 : * @brief Get the minimum possible datarate
386 : *
387 : * The minimum possible datarate may change in response to a TxParamSetupReq
388 : * command from the network server.
389 : *
390 : * @return Minimum possible data rate
391 : */
392 1 : enum lorawan_datarate lorawan_get_min_datarate(void);
393 :
394 : /**
395 : * @brief Get the current payload sizes
396 : *
397 : * Query the current payload sizes. The maximum payload size varies with
398 : * datarate, while the current payload size can be less due to MAC layer
399 : * commands which are inserted into uplink packets.
400 : *
401 : * @param max_next_payload_size Maximum payload size for the next transmission
402 : * @param max_payload_size Maximum payload size for this datarate
403 : */
404 1 : void lorawan_get_payload_sizes(uint8_t *max_next_payload_size,
405 : uint8_t *max_payload_size);
406 :
407 : /**
408 : * @brief Set the region and frequency to be used
409 : *
410 : * Control the LoRa region and frequency settings. This should be called before
411 : * @a lorawan_start(). If you only have support for a single region selected via
412 : * Kconfig, this function does not need to be called at all.
413 : *
414 : * @param region The region to be selected
415 : * @return 0 if successful, negative errno otherwise
416 : */
417 1 : int lorawan_set_region(enum lorawan_region region);
418 :
419 : /**
420 : * @brief Request for time according to DeviceTimeReq MAC cmd
421 : *
422 : * Append MAC DevTimeReq command. It will be processed on next send
423 : * message or force sending empty message to request time immediately.
424 : *
425 : * @param force_request Immediately send an empty message to execute the request
426 : * @return 0 if successful, negative errno otherwise
427 : */
428 1 : int lorawan_request_device_time(bool force_request);
429 :
430 : /**
431 : * @brief Retrieve the current time from LoRaWAN stack updated by
432 : * DeviceTimeAns on MAC layer.
433 : *
434 : * This function uses the GPS epoch format, as used in all LoRaWAN services.
435 : *
436 : * The GPS epoch started on 1980-01-06T00:00:00Z, but has since diverged
437 : * from UTC, as it does not consider corrections like leap seconds.
438 : *
439 : * @param gps_time Synchronized time in GPS epoch format truncated to 32-bit.
440 : *
441 : * @return 0 if successful, -EAGAIN if the clock is not yet synchronized.
442 : */
443 1 : int lorawan_device_time_get(uint32_t *gps_time);
444 :
445 : /**
446 : * @brief Request for link check according to LinkCheckReq MAC cmd
447 : *
448 : * Append MAC LinkCheckReq command. It will be processed on next send
449 : * message or force sending empty message to request time immediately.
450 : *
451 : * @param force_request Immediately send an empty message to execute the request
452 : *
453 : * @return 0 if successful, negative errno otherwise
454 : */
455 1 : int lorawan_request_link_check(bool force_request);
456 :
457 : /**
458 : * @brief Run Application Layer Clock Synchronization service
459 : *
460 : * This service sends out its current time in a regular interval (configurable
461 : * via Kconfig, using @kconfig{CONFIG_LORAWAN_APP_CLOCK_SYNC_PERIODICITY}) and
462 : * receives a correction offset from the application server if the clock
463 : * deviation is considered too large.
464 : *
465 : * Clock synchronization is required for firmware upgrades over multicast
466 : * sessions, but can also be used independent of a FUOTA process.
467 : *
468 : * @kconfig_dep{CONFIG_LORAWAN_APP_CLOCK_SYNC}
469 : *
470 : * @return 0 if successful, negative errno otherwise.
471 : */
472 1 : int lorawan_clock_sync_run(void);
473 :
474 : /**
475 : * @brief Retrieve the current synchronized time
476 : *
477 : * This function uses the GPS epoch format, as used in all LoRaWAN services.
478 : *
479 : * The GPS epoch started on 1980-01-06T00:00:00Z, but has since diverged
480 : * from UTC, as it does not consider corrections like leap seconds.
481 : *
482 : * @kconfig_dep{CONFIG_LORAWAN_APP_CLOCK_SYNC}
483 : *
484 : * @param gps_time Synchronized time in GPS epoch format truncated to 32-bit.
485 : *
486 : * @return 0 if successful, -EAGAIN if the clock is not yet synchronized.
487 : */
488 1 : int lorawan_clock_sync_get(uint32_t *gps_time);
489 :
490 : /**
491 : * @brief Register a handle descriptor callback function.
492 : *
493 : * Provide to the fragmentation transport service a function to be called
494 : * whenever a FragSessionSetupReq is received and Descriptor field should be
495 : * handled.
496 : *
497 : * @kconfig_dep{CONFIG_LORAWAN_FRAG_TRANSPORT}
498 : *
499 : * @param cb Callback for notification.
500 : */
501 1 : void lorawan_frag_transport_register_descriptor_callback(transport_descriptor_cb cb);
502 :
503 : /**
504 : * @brief Run Fragmented Data Block Transport service
505 : *
506 : * This service receives fragmented data (usually firmware images) and
507 : * stores them in the image-1 flash partition.
508 : *
509 : * After all fragments have been received, the provided callback is invoked.
510 : *
511 : * @kconfig_dep{CONFIG_LORAWAN_FRAG_TRANSPORT}
512 : *
513 : * @param transport_finished_cb Callback for notification of finished data transfer.
514 : *
515 : * @return 0 if successful, negative errno otherwise.
516 : */
517 1 : int lorawan_frag_transport_run(void (*transport_finished_cb)(void));
518 :
519 : #ifdef __cplusplus
520 : }
521 : #endif
522 :
523 : /**
524 : * @}
525 : */
526 :
527 : #endif /* ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_ */
|