If you need urgent consulting help click here

LoRa and LoRaWAN


LoRa (abbrev. for Long Range) is a proprietary low-power wireless communication protocol developed by the Semtech Corporation.

LoRa acts as the physical layer (PHY) based on the chirp spread spectrum (CSS) modulation technique.

LoRaWAN (for Long Range Wide Area Network) defines a networking layer on top of the LoRa PHY.

Zephyr provides APIs for LoRa to send raw data packets directly over the wireless interface as well as APIs for LoRaWAN to connect the end device to the internet through a gateway.

The Zephyr implementation is based on Semtech’s LoRaMac-node library, which is included as a Zephyr module.

The LoRaWAN specification is published by the LoRa Alliance.

API Reference


group lora_api


enum lora_signal_bandwidth


enumerator BW_125_KHZ = 0
enumerator BW_250_KHZ
enumerator BW_500_KHZ
enum lora_datarate


enumerator SF_6 = 6
enumerator SF_7
enumerator SF_8
enumerator SF_9
enumerator SF_10
enumerator SF_11
enumerator SF_12
enum lora_coding_rate


enumerator CR_4_5 = 1
enumerator CR_4_6 = 2
enumerator CR_4_7 = 3
enumerator CR_4_8 = 4


static inline int lora_config(const struct device *dev, struct lora_modem_config *config)

Configure the LoRa modem.

  • dev – LoRa device

  • config – Data structure containing the intended configuration for the modem


0 on success, negative on error

static inline int lora_send(const struct device *dev, uint8_t *data, uint32_t data_len)

Send data over LoRa.


This blocks until transmission is complete.

  • dev – LoRa device

  • data – Data to be sent

  • data_len – Length of the data to be sent


0 on success, negative on error

static inline int lora_send_async(const struct device *dev, uint8_t *data, uint32_t data_len, struct k_poll_signal *async)

Asynchronously send data over LoRa.


This returns immediately after starting transmission, and locks the LoRa modem until the transmission completes.

  • dev – LoRa device

  • data – Data to be sent

  • data_len – Length of the data to be sent

  • async – A pointer to a valid and ready to be signaled struct k_poll_signal. (Note: if NULL this function will not notify the end of the transmission).


0 on success, negative on error

static inline int lora_recv(const struct device *dev, uint8_t *data, uint8_t size, k_timeout_t timeout, int16_t *rssi, int8_t *snr)

Receive data over LoRa.


This is a blocking call.

  • dev – LoRa device

  • data – Buffer to hold received data

  • size – Size of the buffer to hold the received data. Max size allowed is 255.

  • timeout – Duration to wait for a packet.

  • rssi – RSSI of received data

  • snr – SNR of received data


Length of the data received on success, negative on error

static inline int lora_recv_async(const struct device *dev, lora_recv_cb cb)

Receive data asynchronously over LoRa.

Receive packets continuously under the configuration previously setup by lora_config.

Reception is cancelled by calling this function again with cb = NULL. This can be done within the callback handler.

  • dev – Modem to receive data on.

  • cb – Callback to run on receiving data. If NULL, any pending asynchronous receptions will be cancelled.


0 when reception successfully setup, negative on error

static inline int lora_test_cw(const struct device *dev, uint32_t frequency, int8_t tx_power, uint16_t duration)

Transmit an unmodulated continuous wave at a given frequency.


Only use this functionality in a test setup where the transmission does not interfere with other devices.

  • dev – LoRa device

  • frequency – Output frequency (Hertz)

  • tx_power – TX power (dBm)

  • duration – Transmission duration in seconds.


0 on success, negative on error

struct lora_modem_config
#include <lora.h>


group lorawan_api




enum lorawan_class

LoRaWAN class types.


enumerator LORAWAN_CLASS_A = 0x00
enumerator LORAWAN_CLASS_B = 0x01
enumerator LORAWAN_CLASS_C = 0x02
enum lorawan_act_type

LoRaWAN activation types.


enumerator LORAWAN_ACT_OTAA = 0
enumerator LORAWAN_ACT_ABP
enum lorawan_datarate

LoRaWAN datarate types.


enumerator LORAWAN_DR_0 = 0
enumerator LORAWAN_DR_1
enumerator LORAWAN_DR_2
enumerator LORAWAN_DR_3
enumerator LORAWAN_DR_4
enumerator LORAWAN_DR_5
enumerator LORAWAN_DR_6
enumerator LORAWAN_DR_7
enumerator LORAWAN_DR_8
enumerator LORAWAN_DR_9
enumerator LORAWAN_DR_10
enumerator LORAWAN_DR_11
enumerator LORAWAN_DR_12
enumerator LORAWAN_DR_13
enumerator LORAWAN_DR_14
enumerator LORAWAN_DR_15
enum lorawan_message_type

LoRaWAN message types.




int lorawan_set_battery_level_callback(uint8_t (*battery_lvl_cb)(void))

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.

  • battery_lvl_cb – Pointer to the battery level function


0 if successful, negative errno code if failure

Register a callback to be run on downlink packets.

  • cb – Pointer to structure containing callback parameters

void lorawan_register_dr_changed_callback(void (*dr_cb)(enum lorawan_datarate))

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

  • dr_cb – Pointer to datarate update callback

int lorawan_join(const struct lorawan_join_config *config)

Join the LoRaWAN network.

Join the LoRaWAN network using OTAA or AWB.

  • config – Configuration to be used


0 if successful, negative errno code if failure

int lorawan_start(void)

Start the LoRaWAN stack.

This function need to be called before joining the network.


0 if successful, negative errno code if failure

int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, enum lorawan_message_type type)

Send data to the LoRaWAN network.

Send data to the connected LoRaWAN network.

  • port – Port to be used for sending data. Must be set if the payload is not empty.

  • data – Data buffer to be sent

  • 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.

  • type – Specifies if the message shall be confirmed or unconfirmed. Must be one of lorawan_message_type.


0 if successful, negative errno code if failure

int lorawan_set_class(enum lorawan_class dev_class)

Set the current device class.

Change the current device class. This function may be called before or after a network connection has been established.

  • dev_class – New device class


0 if successful, negative errno code if failure

int lorawan_set_conf_msg_tries(uint8_t tries)

Set the number of tries used for transmissions.

  • tries – Number of tries to be used


0 if successful, negative errno code if failure

void lorawan_enable_adr(bool enable)

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).

  • enable – Enable or Disable adaptive data rate.

int lorawan_set_datarate(enum lorawan_datarate dr)

Set the default data rate.

Change the default data rate.

  • dr – Data rate used for transmissions


0 if successful, negative errno code if failure

enum lorawan_datarate lorawan_get_min_datarate(void)

Get the minimum possible datarate.

The minimum possible datarate may change in response to a TxParamSetupReq command from the network server.


Minimum possible data rate

void lorawan_get_payload_sizes(uint8_t *max_next_payload_size, uint8_t *max_payload_size)

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.

  • max_next_payload_size – Maximum payload size for the next transmission

  • max_payload_size – Maximum payload size for this datarate

struct lorawan_join_otaa
#include <lorawan.h>

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.

Public Members

uint8_t *join_eui

Join EUI

uint8_t *nwk_key

Network Key

uint8_t *app_key

Application Key

uint32_t dev_nonce

Device Nonce

Starting with LoRaWAN 1.0.4 the DevNonce must be monotonically increasing for each OTAA join with the same EUI. The DevNonce should be stored in non-volatile memory by the application.

struct lorawan_join_abp
#include <lorawan.h>

Public Members

uint32_t dev_addr

Device address on the network

uint8_t *app_skey

Application session key

uint8_t *nwk_skey

Network session key

uint8_t *app_eui

Application EUI

struct lorawan_join_config
#include <lorawan.h>

Public Members

uint8_t *dev_eui

Device EUI. Optional if a secure element is present.

#include <lorawan.h>

Public Members

Callback function to run on downlink data.


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

Node for callback list