zephyr/include/lorawan/lorawan.h
Jordan Yates bbd53dcde0 lorawan: port oriented downlink callbacks
Add downlink callbacks on a per-port basis. A single message will be
handled as many times as users have registered matching ports. Callbacks
will also be run on "meta" downlink packets on port 0, such as confirmed
uplink acknowledgements.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
2021-04-30 13:05:10 -05:00

286 lines
7.4 KiB
C

/*
* Copyright (c) 2020 Manivannan Sadhasivam <mani@kernel.org>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_
#define ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_
/**
* @file
* @brief Public LoRaWAN APIs
*/
#include <device.h>
#include <sys/slist.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LoRaWAN class types.
*/
enum lorawan_class {
LORAWAN_CLASS_A = 0x00,
LORAWAN_CLASS_B = 0x01,
LORAWAN_CLASS_C = 0x02,
};
/**
* @brief LoRaWAN activation types.
*/
enum lorawan_act_type {
LORAWAN_ACT_OTAA = 0,
LORAWAN_ACT_ABP,
};
/**
* @brief LoRaWAN datarate types.
*/
enum lorawan_datarate {
LORAWAN_DR_0 = 0,
LORAWAN_DR_1,
LORAWAN_DR_2,
LORAWAN_DR_3,
LORAWAN_DR_4,
LORAWAN_DR_5,
LORAWAN_DR_6,
LORAWAN_DR_7,
LORAWAN_DR_8,
LORAWAN_DR_9,
LORAWAN_DR_10,
LORAWAN_DR_11,
LORAWAN_DR_12,
LORAWAN_DR_13,
LORAWAN_DR_14,
LORAWAN_DR_15,
};
/**
* @brief LoRaWAN message types.
*
* Note: The default message type is unconfirmed.
*/
enum lorawan_message_type {
LORAWAN_MSG_CONFIRMED = BIT(0),
};
/**
* @brief LoRaWAN join parameters for over-the-Air activation (OTAA)
*
* Note that all of the fields use LoRaWAN 1.1 terminology.
*
* All parameters are optional if a secure element is present in which
* case the values stored in the secure element will be used instead.
*/
struct lorawan_join_otaa {
uint8_t *join_eui;
uint8_t *nwk_key;
uint8_t *app_key;
};
struct lorawan_join_abp {
/** Device address on the network */
uint32_t dev_addr;
/** Application session key */
uint8_t *app_skey;
/** Network session key */
uint8_t *nwk_skey;
/** Application EUI */
uint8_t *app_eui;
};
struct lorawan_join_config {
union {
struct lorawan_join_otaa otaa;
struct lorawan_join_abp abp;
};
/** Device EUI. Optional if a secure element is present. */
uint8_t *dev_eui;
enum lorawan_act_type mode;
};
#define LW_RECV_PORT_ANY UINT16_MAX
struct lorawan_downlink_cb {
/* Port to handle messages for:
* Port 0: TX packet acknowledgements
* Ports 1-255: Standard downlink port
* LW_RECV_PORT_ANY: All downlinks
*/
uint16_t port;
/**
* @brief Callback function to run on downlink data
*
* @note Callbacks are run on the system workqueue,
* and should therefore be as short as possible.
*
* @param port Port message was sent on
* @param data_pending Network server has more downlink packets pending
* @param rssi Received signal strength in dBm
* @param snr Signal to Noise ratio in dBm
* @param len Length of data received, will be 0 for ACKs
* @param data Data received, will be NULL for ACKs
*/
void (*cb)(uint8_t port, bool data_pending,
int16_t rssi, int8_t snr,
uint8_t len, const uint8_t *data);
/** Node for callback list */
sys_snode_t node;
};
/**
* @brief Add battery level callback function.
*
* Provide the LoRaWAN stack with a function to be called whenever a battery
* level needs to be read. As per LoRaWAN specification the callback needs to
* return "0: node is connected to an external power source,
* 1..254: battery level, where 1 is the minimum and 254 is the maximum
* value,
* 255: the node was not able to measure the battery level"
*
* Should no callback be provided the lorawan backend will report 255.
*
* @param battery_lvl_cb Pointer to the battery level function
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void));
/**
* @brief Register a callback to be run on downlink packets
*
* @param cb Pointer to structure containing callback parameters
*/
void lorawan_register_downlink_callback(struct lorawan_downlink_cb *cb);
/**
* @brief Register a callback to be called when the datarate changes
*
* The callback is called once upon successfully joining a network and again
* each time the datarate changes due to ADR.
*
* The callback function takes one parameter:
* - dr - updated datarate
*
* @param dr_cb Pointer to datarate update callback
*/
void lorawan_register_dr_changed_callback(void (*dr_cb)(enum lorawan_datarate));
/**
* @brief Join the LoRaWAN network
*
* Join the LoRaWAN network using OTAA or AWB.
*
* @param config Configuration to be used
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_join(const struct lorawan_join_config *config);
/**
* @brief Start the LoRaWAN stack
*
* This function need to be called before joining the network.
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_start(void);
/**
* @brief Send data to the LoRaWAN network
*
* Send data to the connected LoRaWAN network.
*
* @param port Port to be used for sending data. Must be set if the
* payload is not empty.
* @param data Data buffer to be sent
* @param len Length of the buffer to be sent. Maximum length of this
* buffer is 255 bytes but the actual payload size varies with
* region and datarate.
* @param flags Flag used to determine the type of message being sent. It
* could be one of the lorawan_message_type. The default
* behaviour is unconfirmed message.
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, uint8_t flags);
/**
* @brief Set the current device class
*
* Change the current device class. This function may be called before
* or after a network connection has been established.
*
* @param dev_class New device class
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_set_class(enum lorawan_class dev_class);
/**
* @brief Set the number of tries used for transmissions
*
* @param tries Number of tries to be used
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_set_conf_msg_tries(uint8_t tries);
/**
* @brief Enable Adaptive Data Rate (ADR)
*
* Control whether adaptive data rate (ADR) is enabled. When ADR is enabled,
* the data rate is treated as a default data rate that will be used if the
* ADR algorithm has not established a data rate. ADR should normally only
* be enabled for devices with stable RF conditions (i.e., devices in a mostly
* static location).
*
* @param enable Enable or Disable adaptive data rate.
*/
void lorawan_enable_adr(bool enable);
/**
* @brief Set the default data rate
*
* Change the default data rate.
*
* @param dr Data rate used for transmissions
*
* @return 0 if successful, negative errno code if failure
*/
int lorawan_set_datarate(enum lorawan_datarate dr);
/**
* @brief Get the minimum possible datarate
*
* The minimum possible datarate may change in response to a TxParamSetupReq
* command from the network server.
*
* @return Minimum possible data rate
*/
enum lorawan_datarate lorawan_get_min_datarate(void);
/**
* @brief Get the current payload sizes
*
* Query the current payload sizes. The maximum payload size varies with
* datarate, while the current payload size can be less due to MAC layer
* commands which are inserted into uplink packets.
*
* @param max_next_payload_size Maximum payload size for the next transmission
* @param max_payload_size Maximum payload size for this datarate
*/
void lorawan_get_payload_sizes(uint8_t *max_next_payload_size,
uint8_t *max_payload_size);
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_LORAWAN_LORAWAN_H_ */