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