mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6059 from hasnainvirk/pr_branch
Enabling LoRaWAN technology in Mbed-OS 5.8pull/6087/head
commit
213d2b649e
|
@ -18,6 +18,9 @@
|
|||
#ifndef LORARADIO_H_
|
||||
#define LORARADIO_H_
|
||||
|
||||
#include "platform/Callback.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
/**
|
||||
* Structure to hold RF controls for LoRa Radio.
|
||||
* SX1276 have an extra control for the crystal (used in DOSCO-L072CZ)
|
||||
|
@ -131,17 +134,18 @@ typedef struct radio_settings {
|
|||
*
|
||||
*/
|
||||
typedef struct radio_events {
|
||||
/* Tx Done callback prototype.
|
||||
*
|
||||
/**
|
||||
* Callback when Transmission is done
|
||||
*/
|
||||
void (*tx_done) (void);
|
||||
mbed::Callback<void()> tx_done;
|
||||
|
||||
/* Tx Timeout callback prototype.
|
||||
*
|
||||
/**
|
||||
* Callback when Transmission is timed out
|
||||
*/
|
||||
void (*tx_timeout) (void);
|
||||
mbed::Callback<void()> tx_timeout;
|
||||
|
||||
/* Rx Done callback prototype.
|
||||
/**
|
||||
* Rx Done callback prototype.
|
||||
*
|
||||
* @param payload Received buffer pointer.
|
||||
* @param size Received buffer size.
|
||||
|
@ -150,29 +154,31 @@ typedef struct radio_events {
|
|||
* FSK : N/A (set to 0)
|
||||
* LoRa: SNR value in dB
|
||||
*/
|
||||
void (*rx_done) (uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
|
||||
mbed::Callback<void(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)> rx_done;
|
||||
|
||||
/* Rx Timeout callback prototype.
|
||||
*
|
||||
/**
|
||||
* Callback when Reception is timed out
|
||||
*/
|
||||
void (*rx_timeout) (void);
|
||||
mbed::Callback<void()> rx_timeout;
|
||||
|
||||
/* Rx Error callback prototype.
|
||||
*
|
||||
/**
|
||||
* Callback when Reception ends up in error
|
||||
*/
|
||||
void (*rx_error) (void);
|
||||
mbed::Callback<void()> rx_error;
|
||||
|
||||
/* FHSS Change Channel callback prototype.
|
||||
*
|
||||
* @param current_channel The index number of the current channel.
|
||||
*/
|
||||
void (*fhss_change_channel) (uint8_t current_channel);
|
||||
/**
|
||||
* FHSS Change Channel callback prototype.
|
||||
*
|
||||
* @param current_channel The index number of the current channel.
|
||||
*/
|
||||
mbed::Callback<void(uint8_t current_channel)> fhss_change_channel;
|
||||
|
||||
/* CAD Done callback prototype.
|
||||
/**
|
||||
* CAD Done callback prototype.
|
||||
*
|
||||
* @param channel_activity_detected Channel activity detected during the CAD.
|
||||
* @param channel_busy True, if Channel activity detected.
|
||||
*/
|
||||
void (*cad_done) (bool channel_activity_detected);
|
||||
mbed::Callback<void(bool channel_busy)> cad_done;
|
||||
} radio_events_t;
|
||||
|
||||
/**
|
|
@ -31,20 +31,20 @@ public:
|
|||
*
|
||||
* @param queue A pointer to EventQueue provided by the application.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error code on
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error code on
|
||||
* failure.
|
||||
*/
|
||||
virtual lora_mac_status_t initialize(events::EventQueue *queue) = 0;
|
||||
virtual lorawan_status_t initialize(events::EventQueue *queue) = 0;
|
||||
|
||||
/** Connect OTAA or ABP by setup.
|
||||
*
|
||||
* Connect by Over The Air Activation or Activation By Personalization.
|
||||
* The connection type is selected at the setup.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error code on
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error code on
|
||||
* failure.
|
||||
*/
|
||||
virtual lora_mac_status_t connect() = 0;
|
||||
virtual lorawan_status_t connect() = 0;
|
||||
|
||||
/** Connect OTAA or ABP by parameters
|
||||
*
|
||||
|
@ -53,46 +53,78 @@ public:
|
|||
* You need to define the parameters in the main application.
|
||||
*
|
||||
* @param connect Options how end-device will connect to gateway
|
||||
* @return LORA_MAC_STATUS_OK on success, negative error code
|
||||
* @return LORAWAN_STATUS_OK on success, negative error code
|
||||
* on failure
|
||||
*/
|
||||
virtual lora_mac_status_t connect(const lorawan_connect_t &connect) = 0;
|
||||
virtual lorawan_status_t connect(const lorawan_connect_t &connect) = 0;
|
||||
|
||||
/** Disconnects the current session.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error code on failure.
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t disconnect() = 0;
|
||||
virtual lorawan_status_t disconnect() = 0;
|
||||
|
||||
/** Validate the connectivity with the network.
|
||||
*
|
||||
* Application may use this API to submit a request to the stack for
|
||||
* validation of its connectivity to a Network Server. Under the hood, this
|
||||
* API schedules a Link Check Request command (LinkCheckReq) for the network
|
||||
* server and once the response, i.e., LinkCheckAns MAC command is received
|
||||
* from the Network Server, user provided method is called.
|
||||
*
|
||||
* This API is usable only when the link check response is callback set by
|
||||
* the application. See add_lora_app_callbacks API. If the above mentioned
|
||||
* callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown.
|
||||
*
|
||||
* First parameter to callback function is the demodulation margin and
|
||||
* the second parameter is the number of gateways that successfully received
|
||||
* the last request.
|
||||
*
|
||||
* A 'Link Check Request' MAC command remains set for every subsequent
|
||||
* transmission, until/unless application explicitly turns it off using
|
||||
* remove_link_check_request() API.
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK on successfully queuing a request, or
|
||||
* a negative error code on failure.
|
||||
*
|
||||
*/
|
||||
virtual lorawan_status_t add_link_check_request() = 0;
|
||||
|
||||
/** Detaches Link Request MAC command.
|
||||
*
|
||||
* Removes sticky MAC command for link check request.
|
||||
*/
|
||||
virtual void remove_link_check_request() = 0;
|
||||
|
||||
/** Sets up a particular data rate of choice
|
||||
*
|
||||
* @param data_rate Intended data rate e.g., DR_0, DR_1 etc.
|
||||
* Caution is advised as the macro DR_* can mean different
|
||||
* things while being in a different region.
|
||||
* @return LORA_MAC_STATUS_OK if everything goes well, otherwise
|
||||
* @return LORAWAN_STATUS_OK if everything goes well, otherwise
|
||||
* a negative error code.
|
||||
*/
|
||||
virtual lora_mac_status_t set_datarate(uint8_t data_rate) = 0;
|
||||
virtual lorawan_status_t set_datarate(uint8_t data_rate) = 0;
|
||||
|
||||
/** Enables adaptive data rate (ADR)
|
||||
*
|
||||
* Underlying LoRaPHY and LoRaMac layers handle the data rate automatically
|
||||
* for the user based upon radio conditions (network congestion).
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, negative error code
|
||||
* @return LORAWAN_STATUS_OK on success, negative error code
|
||||
* on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t enable_adaptive_datarate() = 0;
|
||||
virtual lorawan_status_t enable_adaptive_datarate() = 0;
|
||||
|
||||
/** Disables adaptive data rate
|
||||
*
|
||||
* When adaptive data rate (ADR) is disabled, user can either set a certain
|
||||
* data rate or the Mac layer will choose a default value.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, negative error code
|
||||
* @return LORAWAN_STATUS_OK on success, negative error code
|
||||
* on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t disable_adaptive_datarate() = 0;
|
||||
virtual lorawan_status_t disable_adaptive_datarate() = 0;
|
||||
|
||||
/** Sets up retry counter for confirmed messages
|
||||
*
|
||||
|
@ -108,25 +140,25 @@ public:
|
|||
*
|
||||
* @param count number of retries for confirmed messages
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or a negative error code
|
||||
* @return LORAWAN_STATUS_OK or a negative error code
|
||||
*/
|
||||
virtual lora_mac_status_t set_confirmed_msg_retries(uint8_t count) = 0;
|
||||
virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count) = 0;
|
||||
|
||||
/** Sets channel plan
|
||||
*
|
||||
* @param channel_plan The defined channel plans to be set.
|
||||
* @return 0 on success, a negative error code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t set_channel_plan(const lora_channelplan_t &channel_plan) = 0;
|
||||
virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan) = 0;
|
||||
|
||||
/** Gets the current channel plan.
|
||||
*
|
||||
* @param channel_plan The current channel information.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t get_channel_plan(lora_channelplan_t &channel_plan) = 0;
|
||||
virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan) = 0;
|
||||
|
||||
/** Removes currently active channel plan
|
||||
*
|
||||
|
@ -134,10 +166,10 @@ public:
|
|||
* allowed to be removed. So when a plan is abolished, only non-default
|
||||
* channels are removed.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, negative error
|
||||
* @return LORAWAN_STATUS_OK on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual lora_mac_status_t remove_channel_plan() = 0;
|
||||
virtual lorawan_status_t remove_channel_plan() = 0;
|
||||
|
||||
/** Removes a given single channel
|
||||
*
|
||||
|
@ -146,10 +178,10 @@ public:
|
|||
*
|
||||
* @param index The channel index
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, negative error
|
||||
* @return LORAWAN_STATUS_OK on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual lora_mac_status_t remove_channel(uint8_t index) = 0;
|
||||
virtual lorawan_status_t remove_channel(uint8_t index) = 0;
|
||||
|
||||
/** Send message to gateway
|
||||
*
|
||||
|
@ -182,7 +214,7 @@ public:
|
|||
*
|
||||
*
|
||||
* @return The number of bytes sent, or
|
||||
* LORA_MAC_STATUS_WOULD_BLOCK if another TX is
|
||||
* LORAWAN_STATUS_WOULD_BLOCK if another TX is
|
||||
* ongoing, or a negative error code on failure.
|
||||
*/
|
||||
virtual int16_t send(uint8_t port, const uint8_t* data,
|
||||
|
@ -223,7 +255,7 @@ public:
|
|||
* @return It could be one of these:
|
||||
* i) 0 if there is nothing else to read.
|
||||
* ii) Number of bytes written to user buffer.
|
||||
* iii) LORA_MAC_STATUS_WOULD_BLOCK if there is
|
||||
* iii) LORAWAN_STATUS_WOULD_BLOCK if there is
|
||||
* nothing available to read at the moment.
|
||||
* iv) A negative error code on failure.
|
||||
*/
|
||||
|
@ -298,7 +330,7 @@ public:
|
|||
* @param callbacks A pointer to the structure containing application
|
||||
* callbacks.
|
||||
*/
|
||||
virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0;
|
||||
virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0;
|
||||
};
|
||||
|
||||
#endif /* LORAWAN_BASE_H_ */
|
|
@ -28,7 +28,7 @@ inline LoRaWANStack& stk_obj()
|
|||
return LoRaWANStack::get_lorawan_stack();
|
||||
}
|
||||
|
||||
LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio)
|
||||
LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio) : _link_check_requested(false)
|
||||
{
|
||||
// Pass mac_handlers to radio to the radio driver after
|
||||
// binding radio driver to PHY layer
|
||||
|
@ -42,16 +42,16 @@ LoRaWANInterface::~LoRaWANInterface()
|
|||
{
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::initialize(EventQueue *queue)
|
||||
lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
|
||||
{
|
||||
if(!queue) {
|
||||
return LORA_MAC_STATUS_PARAMETER_INVALID;
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return stk_obj().initialize_mac_layer(queue);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::connect()
|
||||
lorawan_status_t LoRaWANInterface::connect()
|
||||
{
|
||||
// connection attempt without parameters.
|
||||
// System tries to look for configuration in mbed_lib.json that can be
|
||||
|
@ -61,10 +61,10 @@ lora_mac_status_t LoRaWANInterface::connect()
|
|||
|
||||
lorawan_connect_t connection_params;
|
||||
|
||||
if (OVER_THE_AIR_ACTIVATION != 0) {
|
||||
static uint8_t dev_eui[] = LORAWAN_DEVICE_EUI;
|
||||
static uint8_t app_eui[] = LORAWAN_APPLICATION_EUI;
|
||||
static uint8_t app_key[] = LORAWAN_APPLICATION_KEY;
|
||||
if (MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION) {
|
||||
static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
|
||||
static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
|
||||
static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
|
||||
/**
|
||||
*
|
||||
* OTAA join
|
||||
|
@ -73,14 +73,14 @@ lora_mac_status_t LoRaWANInterface::connect()
|
|||
connection_params.connection_u.otaa.app_eui = app_eui;
|
||||
connection_params.connection_u.otaa.dev_eui = dev_eui;
|
||||
connection_params.connection_u.otaa.app_key = app_key;
|
||||
connection_params.connection_u.otaa.nb_trials = LORAWAN_NB_TRIALS;
|
||||
connection_params.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS;
|
||||
|
||||
return connect(connection_params);
|
||||
} else {
|
||||
static uint8_t nwk_skey[] = LORAWAN_NWKSKEY;
|
||||
static uint8_t app_skey[] = LORAWAN_APPSKEY;
|
||||
static uint32_t dev_addr = LORAWAN_DEVICE_ADDRESS;
|
||||
static uint32_t nwk_id = (LORAWAN_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK);
|
||||
static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY;
|
||||
static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY;
|
||||
static uint32_t dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS;
|
||||
static uint32_t nwk_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -96,63 +96,73 @@ lora_mac_status_t LoRaWANInterface::connect()
|
|||
}
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
|
||||
lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
|
||||
{
|
||||
lora_mac_status_t mac_status;
|
||||
lorawan_status_t mac_status;
|
||||
|
||||
if (connect.connect_type == LORAWAN_CONNECTION_OTAA) {
|
||||
mac_status = stk_obj().join_request_by_otaa(connect);
|
||||
} else if (connect.connect_type == LORAWAN_CONNECTION_ABP) {
|
||||
mac_status = stk_obj().activation_by_personalization(connect);
|
||||
} else {
|
||||
return LORA_MAC_STATUS_PARAMETER_INVALID;
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return mac_status;
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::disconnect()
|
||||
lorawan_status_t LoRaWANInterface::disconnect()
|
||||
{
|
||||
stk_obj().shutdown();
|
||||
return LORA_MAC_STATUS_OK;
|
||||
return stk_obj().shutdown();
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
|
||||
lorawan_status_t LoRaWANInterface::add_link_check_request()
|
||||
{
|
||||
_link_check_requested = true;
|
||||
return stk_obj().set_link_check_request();
|
||||
}
|
||||
|
||||
void LoRaWANInterface::remove_link_check_request()
|
||||
{
|
||||
_link_check_requested = false;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
|
||||
{
|
||||
return stk_obj().set_channel_data_rate(data_rate);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
|
||||
lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
|
||||
{
|
||||
return stk_obj().set_confirmed_msg_retry(count);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::enable_adaptive_datarate()
|
||||
lorawan_status_t LoRaWANInterface::enable_adaptive_datarate()
|
||||
{
|
||||
return stk_obj().enable_adaptive_datarate(true);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::disable_adaptive_datarate()
|
||||
lorawan_status_t LoRaWANInterface::disable_adaptive_datarate()
|
||||
{
|
||||
return stk_obj().enable_adaptive_datarate(false);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::set_channel_plan(const lora_channelplan_t &channel_plan)
|
||||
lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan)
|
||||
{
|
||||
return stk_obj().add_channels(channel_plan);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::get_channel_plan(lora_channelplan_t &channel_plan)
|
||||
lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan)
|
||||
{
|
||||
return stk_obj().get_enabled_channels(channel_plan);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::remove_channel(uint8_t id)
|
||||
lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id)
|
||||
{
|
||||
return stk_obj().remove_a_channel(id);
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::remove_channel_plan()
|
||||
lorawan_status_t LoRaWANInterface::remove_channel_plan()
|
||||
{
|
||||
return stk_obj().drop_channel_list();
|
||||
}
|
||||
|
@ -160,10 +170,16 @@ lora_mac_status_t LoRaWANInterface::remove_channel_plan()
|
|||
int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data,
|
||||
uint16_t length, int flags)
|
||||
{
|
||||
if (_link_check_requested) {
|
||||
// add a link check request with normal data, until the application
|
||||
// explicitly removes it.
|
||||
add_link_check_request();
|
||||
}
|
||||
|
||||
if (data) {
|
||||
return stk_obj().handle_tx(port, data, length, flags);
|
||||
} else {
|
||||
return LORA_MAC_STATUS_PARAMETER_INVALID;
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,19 +189,18 @@ int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length,
|
|||
if (data && length > 0) {
|
||||
return stk_obj().handle_rx(port, data, length, flags);
|
||||
} else {
|
||||
return LORA_MAC_STATUS_PARAMETER_INVALID;
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
|
||||
lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
|
||||
{
|
||||
|
||||
if (!callbacks || !callbacks->events) {
|
||||
// Event Callback is mandatory
|
||||
return LORA_MAC_STATUS_PARAMETER_INVALID;
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
stk_obj().set_lora_callbacks(callbacks);
|
||||
|
||||
return LORA_MAC_STATUS_OK;
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
#define LORAWANINTERFACE_H_
|
||||
|
||||
#include "platform/Callback.h"
|
||||
#include "netsocket/LoRaWANBase.h"
|
||||
#include "lorawan/LoRaWANStack.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
#include "lorawan/LoRaRadio.h"
|
||||
#include "lorawan/LoRaWANBase.h"
|
||||
|
||||
class LoRaWANInterface: public LoRaWANBase {
|
||||
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
*
|
||||
* @return 0 on success, a negative error code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t initialize(events::EventQueue *ev_queue) ;
|
||||
virtual lorawan_status_t initialize(events::EventQueue *ev_queue) ;
|
||||
|
||||
/** Connect OTAA or ABP using Mbed-OS config system
|
||||
*
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
* You need to configure the connection properly via the Mbed OS configuration
|
||||
* system.
|
||||
*
|
||||
* When connecting via OTAA, the return code for success (LORA_MAC_STATUS_CONNECT_IN_PROGRESS) is negative.
|
||||
* When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
|
||||
* However, this is not a real error. It tells you that the connection is in progress and you will
|
||||
* be notified of the completion via an event. By default, after the Join Accept message
|
||||
* is received, base stations may provide the node with a CF-List that replaces
|
||||
|
@ -78,17 +78,17 @@ public:
|
|||
* is important, at least for ABP. That's why we try to restore frame counters from
|
||||
* session information after a disconnection.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or LORA_MAC_STATUS_CONNECT_IN_PROGRESS
|
||||
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS
|
||||
* on success, or a negative error code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t connect();
|
||||
virtual lorawan_status_t connect();
|
||||
|
||||
/** Connect OTAA or ABP with parameters
|
||||
*
|
||||
* All connection parameters are chosen by the user and provided in the
|
||||
* data structure passed down.
|
||||
*
|
||||
* When connecting via OTAA, the return code for success (LORA_MAC_STATUS_CONNECT_IN_PROGRESS) is negative.
|
||||
* When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative.
|
||||
* However, this is not a real error. It tells you that connection is in progress and you will
|
||||
* be notified of completion via an event. By default, after Join Accept message
|
||||
* is received, base stations may provide the node with a CF-List which replaces
|
||||
|
@ -118,17 +118,54 @@ public:
|
|||
*
|
||||
* @param connect Options for an end device connection to the gateway.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or LORA_MAC_STATUS_CONNECT_IN_PROGRESS,
|
||||
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
|
||||
* a negative error code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t connect(const lorawan_connect_t &connect);
|
||||
virtual lorawan_status_t connect(const lorawan_connect_t &connect);
|
||||
|
||||
/** Disconnect the current session.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error code on
|
||||
* failure.
|
||||
* @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
|
||||
*/
|
||||
virtual lora_mac_status_t disconnect();
|
||||
virtual lorawan_status_t disconnect();
|
||||
|
||||
/** Validate the connectivity with the network.
|
||||
*
|
||||
* Application may use this API to submit a request to the stack for
|
||||
* validation of its connectivity to a Network Server. Under the hood, this
|
||||
* API schedules a Link Check Request command (LinkCheckReq) for the network
|
||||
* server and once the response, i.e., LinkCheckAns MAC command is received
|
||||
* from the Network Server, user provided method is called.
|
||||
*
|
||||
* One way to use this API may be the validation of connectivity after a long
|
||||
* deep sleep. Mbed LoRaWANStack piggy-backs the MAC commands with data
|
||||
* frame payload so the application needs to try sending something and the Network
|
||||
* Server may respond during the RX slots.
|
||||
*
|
||||
* This API is usable only when the 'link_check_resp' callback is set by
|
||||
* the application. See add_lora_app_callbacks API. If the above mentioned
|
||||
* callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown.
|
||||
*
|
||||
* First parameter to callback function is the demodulation margin and
|
||||
* the second parameter is the number of gateways that successfully received
|
||||
* the last request.
|
||||
*
|
||||
* A 'Link Check Request' MAC command remains set for every subsequent
|
||||
* transmission, until/unless application explicitly turns it off using
|
||||
* remove_link_check_request() API.
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK on successfully queuing a request, or
|
||||
* a negative error code on failure.
|
||||
*
|
||||
*/
|
||||
virtual lorawan_status_t add_link_check_request();
|
||||
|
||||
/** Removes link check request sticky MAC command.
|
||||
*
|
||||
* Any already queued request may still get entertained. However, no new
|
||||
* requests will be made.
|
||||
*/
|
||||
virtual void remove_link_check_request();
|
||||
|
||||
/** Sets up a particular data rate
|
||||
*
|
||||
|
@ -138,28 +175,28 @@ public:
|
|||
* @param data_rate The intended data rate, for example DR_0 or DR_1.
|
||||
* Please note, that the macro DR_* can mean different
|
||||
* things in different regions.
|
||||
* @return LORA_MAC_STATUS_OK if everything goes well, otherwise
|
||||
* @return LORAWAN_STATUS_OK if everything goes well, otherwise
|
||||
* a negative error code.
|
||||
*/
|
||||
virtual lora_mac_status_t set_datarate(uint8_t data_rate);
|
||||
virtual lorawan_status_t set_datarate(uint8_t data_rate);
|
||||
|
||||
/** Enables adaptive data rate (ADR).
|
||||
*
|
||||
* The underlying LoRaPHY and LoRaMac layers handle the data rate automatically
|
||||
* for the user, based upon the radio conditions (network congestion).
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or negative error code otherwise.
|
||||
* @return LORAWAN_STATUS_OK or negative error code otherwise.
|
||||
*/
|
||||
virtual lora_mac_status_t enable_adaptive_datarate();
|
||||
virtual lorawan_status_t enable_adaptive_datarate();
|
||||
|
||||
/** Disables adaptive data rate.
|
||||
*
|
||||
* When adaptive data rate (ADR) is disabled, you can either set a certain
|
||||
* data rate or the MAC layer selects a default value.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or negative error code otherwise.
|
||||
* @return LORAWAN_STATUS_OK or negative error code otherwise.
|
||||
*/
|
||||
virtual lora_mac_status_t disable_adaptive_datarate();
|
||||
virtual lorawan_status_t disable_adaptive_datarate();
|
||||
|
||||
/** Sets up the retry counter for confirmed messages.
|
||||
*
|
||||
|
@ -174,9 +211,9 @@ public:
|
|||
*
|
||||
* @param count The number of retries for confirmed messages.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or a negative error code.
|
||||
* @return LORAWAN_STATUS_OK or a negative error code.
|
||||
*/
|
||||
virtual lora_mac_status_t set_confirmed_msg_retries(uint8_t count);
|
||||
virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count);
|
||||
|
||||
/** Sets the channel plan.
|
||||
*
|
||||
|
@ -188,6 +225,9 @@ public:
|
|||
* is already active, the request is silently ignored. A negative error
|
||||
* code is returned if there is any problem with parameters.
|
||||
*
|
||||
* Please note that this API can also be used to add a single channel to the
|
||||
* existing channel plan.
|
||||
*
|
||||
* There is no reverse mechanism in the 1.0.2 specification for a node to request
|
||||
* a particular channel. Only the network server can initiate such a request.
|
||||
* You need to ensure that the corresponding base station supports the channel or channels being added.
|
||||
|
@ -199,10 +239,10 @@ public:
|
|||
*
|
||||
* @param channel_plan The channel plan to set.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t set_channel_plan(const lora_channelplan_t &channel_plan);
|
||||
virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan);
|
||||
|
||||
/** Gets the channel plans from the LoRa stack.
|
||||
*
|
||||
|
@ -213,20 +253,20 @@ public:
|
|||
*
|
||||
* @param channel_plan The current channel plan information.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t get_channel_plan(lora_channelplan_t &channel_plan);
|
||||
virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan);
|
||||
|
||||
/** Removes an active channel plan.
|
||||
*
|
||||
* You cannot remove default channels (the channels the base stations are listening to).
|
||||
* When a plan is abolished, only the non-default channels are removed.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t remove_channel_plan();
|
||||
virtual lorawan_status_t remove_channel_plan();
|
||||
|
||||
/** Removes a single channel.
|
||||
*
|
||||
|
@ -234,10 +274,10 @@ public:
|
|||
*
|
||||
* @param index The channel index.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
virtual lora_mac_status_t remove_channel(uint8_t index);
|
||||
virtual lorawan_status_t remove_channel(uint8_t index);
|
||||
|
||||
/** Send message to gateway
|
||||
*
|
||||
|
@ -270,7 +310,7 @@ public:
|
|||
*
|
||||
*
|
||||
* @return The number of bytes sent, or
|
||||
* LORA_MAC_STATUS_WOULD_BLOCK if another TX is
|
||||
* LORAWAN_STATUS_WOULD_BLOCK if another TX is
|
||||
* ongoing, or a negative error code on failure.
|
||||
*/
|
||||
virtual int16_t send(uint8_t port, const uint8_t* data, uint16_t length,
|
||||
|
@ -311,7 +351,7 @@ public:
|
|||
* @return It could be one of these:
|
||||
* i) 0 if there is nothing else to read.
|
||||
* ii) Number of bytes written to user buffer.
|
||||
* iii) LORA_MAC_STATUS_WOULD_BLOCK if there is
|
||||
* iii) LORAWAN_STATUS_WOULD_BLOCK if there is
|
||||
* nothing available to read at the moment.
|
||||
* iv) A negative error code on failure.
|
||||
*/
|
||||
|
@ -361,7 +401,7 @@ public:
|
|||
* int main()
|
||||
* {
|
||||
* lorawan.initialize(&queue);
|
||||
* cbs.lorawan_events = mbed::callback(my_event_handler);
|
||||
* cbs.events = mbed::callback(my_event_handler);
|
||||
* lorawan.add_app_callbacks(&cbs);
|
||||
* lorawan.connect();
|
||||
* }
|
||||
|
@ -386,7 +426,10 @@ public:
|
|||
* @param callbacks A pointer to the structure containing application
|
||||
* callbacks.
|
||||
*/
|
||||
virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks);
|
||||
virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks);
|
||||
|
||||
private:
|
||||
bool _link_check_requested;
|
||||
};
|
||||
|
||||
#endif /* LORAWANINTERFACE_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,6 +35,42 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "LoRaRadio.h"
|
||||
|
||||
#ifdef MBED_CONF_LORA_PHY
|
||||
#if MBED_CONF_LORA_PHY == 0
|
||||
#include "lorawan/lorastack/phy/LoRaPHYEU868.h"
|
||||
#define LoRaPHY_region LoRaPHYEU868
|
||||
#elif MBED_CONF_LORA_PHY == 1
|
||||
#include "lorawan/lorastack/phy/LoRaPHYAS923.h"
|
||||
#define LoRaPHY_region LoRaPHYAS923
|
||||
#elif MBED_CONF_LORA_PHY == 2
|
||||
#include "lorawan/lorastack/phy/LoRaPHYAU915.h"
|
||||
#define LoRaPHY_region LoRaPHYAU915;
|
||||
#elif MBED_CONF_LORA_PHY == 3
|
||||
#include "lorawan/lorastack/phy/LoRaPHYCN470.h"
|
||||
#define LoRaPHY_region LoRaPHYCN470
|
||||
#elif MBED_CONF_LORA_PHY == 4
|
||||
#include "lorawan/lorastack/phy/LoRaPHYCN779.h"
|
||||
#define LoRaPHY_region LoRaPHYCN779
|
||||
#elif MBED_CONF_LORA_PHY == 5
|
||||
#include "lorawan/lorastack/phy/LoRaPHYEU433.h"
|
||||
#define LoRaPHY_region LoRaPHYEU433
|
||||
#elif MBED_CONF_LORA_PHY == 6
|
||||
#include "lorawan/lorastack/phy/LoRaPHYIN865.h"
|
||||
#define LoRaPHY_region LoRaPHYIN865
|
||||
#elif MBED_CONF_LORA_PHY == 7
|
||||
#include "lorawan/lorastack/phy/LoRaPHYKR920.h"
|
||||
#define LoRaPHY_region LoRaPHYKR920
|
||||
#elif MBED_CONF_LORA_PHY == 8
|
||||
#include "lorawan/lorastack/phy/LoRaPHYUS915.h"
|
||||
#define LoRaPHY_region LoRaPHYUS915
|
||||
#elif MBED_CONF_LORA_PHY == 9
|
||||
#include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h"
|
||||
#define LoRaPHY_region LoRaPHYUS915Hybrid
|
||||
#endif //MBED_CONF_LORA_PHY == VALUE
|
||||
#else
|
||||
#error "Must set LoRa PHY layer parameters."
|
||||
#endif //MBED_CONF_LORA_PHY
|
||||
|
||||
/**
|
||||
* A mask for the network ID.
|
||||
*/
|
||||
|
@ -61,13 +97,13 @@ public:
|
|||
|
||||
/** End device initialization.
|
||||
* @param queue A pointer to an EventQueue passed from the application.
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error code on failure.
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error code on failure.
|
||||
*/
|
||||
lora_mac_status_t initialize_mac_layer(events::EventQueue *queue);
|
||||
lorawan_status_t initialize_mac_layer(events::EventQueue *queue);
|
||||
|
||||
/** Sets all callbacks for the application.
|
||||
*
|
||||
* \param callbacks A pointer to the structure carrying callbacks.
|
||||
* @param callbacks A pointer to the structure carrying callbacks.
|
||||
*/
|
||||
void set_lora_callbacks(lorawan_app_callbacks_t *callbacks);
|
||||
|
||||
|
@ -90,35 +126,35 @@ public:
|
|||
*
|
||||
* @param channel_plan A list of channels or a single channel.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
lora_mac_status_t add_channels(const lora_channelplan_t &channel_plan);
|
||||
lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan);
|
||||
|
||||
/** Removes a channel from the list.
|
||||
*
|
||||
* @param channel_id Index of the channel being removed
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
lora_mac_status_t remove_a_channel(uint8_t channel_id);
|
||||
lorawan_status_t remove_a_channel(uint8_t channel_id);
|
||||
|
||||
/** Removes a previously set channel plan.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
lora_mac_status_t drop_channel_list();
|
||||
lorawan_status_t drop_channel_list();
|
||||
|
||||
/** Gets a list of currently enabled channels .
|
||||
*
|
||||
* @param channel_plan The channel plan structure to store final result.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
lora_mac_status_t get_enabled_channels(lora_channelplan_t &channel_plan);
|
||||
lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan);
|
||||
|
||||
/** Sets up a retry counter for confirmed messages.
|
||||
*
|
||||
|
@ -128,9 +164,9 @@ public:
|
|||
*
|
||||
* @param count The number of retries for confirmed messages.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or a negative error code.
|
||||
* @return LORAWAN_STATUS_OK or a negative error code.
|
||||
*/
|
||||
lora_mac_status_t set_confirmed_msg_retry(uint8_t count);
|
||||
lorawan_status_t set_confirmed_msg_retry(uint8_t count);
|
||||
|
||||
/** Sets up the data rate.
|
||||
*
|
||||
|
@ -141,26 +177,26 @@ public:
|
|||
* Note that the macro DR_* can mean different
|
||||
* things in different regions.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK if everything goes well, otherwise
|
||||
* @return LORAWAN_STATUS_OK if everything goes well, otherwise
|
||||
* a negative error code.
|
||||
*/
|
||||
lora_mac_status_t set_channel_data_rate(uint8_t data_rate);
|
||||
lorawan_status_t set_channel_data_rate(uint8_t data_rate);
|
||||
|
||||
/** Enables ADR.
|
||||
*
|
||||
* @param adr_enabled 0 ADR disabled, 1 ADR enabled.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK on success, a negative error
|
||||
* @return LORAWAN_STATUS_OK on success, a negative error
|
||||
* code on failure.
|
||||
*/
|
||||
lora_mac_status_t enable_adaptive_datarate(bool adr_enabled);
|
||||
lorawan_status_t enable_adaptive_datarate(bool adr_enabled);
|
||||
|
||||
/** Commissions a LoRa device.
|
||||
*
|
||||
* @param commission_data A structure representing all the commission
|
||||
* information.
|
||||
*/
|
||||
void commission_device(const lora_dev_commission_t &commission_data);
|
||||
void commission_device(const lorawan_dev_commission_t &commission_data);
|
||||
|
||||
/** End device OTAA join.
|
||||
*
|
||||
|
@ -169,11 +205,11 @@ public:
|
|||
*
|
||||
* @param params The `lorawan_connect_t` type structure.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or
|
||||
* LORA_MAC_STATUS_CONNECT_IN_PROGRESS on success,
|
||||
* @return LORAWAN_STATUS_OK or
|
||||
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
|
||||
* or a negative error code on failure.
|
||||
*/
|
||||
lora_mac_status_t join_request_by_otaa(const lorawan_connect_t ¶ms);
|
||||
lorawan_status_t join_request_by_otaa(const lorawan_connect_t ¶ms);
|
||||
|
||||
/** End device ABP join.
|
||||
*
|
||||
|
@ -182,11 +218,11 @@ public:
|
|||
*
|
||||
* @param params The `lorawan_connect_t` type structure.
|
||||
*
|
||||
* @return LORA_MAC_STATUS_OK or
|
||||
* LORA_MAC_STATUS_CONNECT_IN_PROGRESS on success,
|
||||
* @return LORAWAN_STATUS_OK or
|
||||
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
|
||||
* or a negative error code on failure.
|
||||
*/
|
||||
lora_mac_status_t activation_by_personalization(const lorawan_connect_t ¶ms);
|
||||
lorawan_status_t activation_by_personalization(const lorawan_connect_t ¶ms);
|
||||
|
||||
/** Send message to gateway
|
||||
*
|
||||
|
@ -219,7 +255,7 @@ public:
|
|||
*
|
||||
*
|
||||
* @return The number of bytes sent, or
|
||||
* LORA_MAC_STATUS_WOULD_BLOCK if another TX is
|
||||
* LORAWAN_STATUS_WOULD_BLOCK if another TX is
|
||||
* ongoing, or a negative error code on failure.
|
||||
*/
|
||||
int16_t handle_tx(uint8_t port, const uint8_t* data,
|
||||
|
@ -260,18 +296,36 @@ public:
|
|||
* @return It could be one of these:
|
||||
* i) 0 if there is nothing else to read.
|
||||
* ii) Number of bytes written to user buffer.
|
||||
* iii) LORA_MAC_STATUS_WOULD_BLOCK if there is
|
||||
* iii) LORAWAN_STATUS_WOULD_BLOCK if there is
|
||||
* nothing available to read at the moment.
|
||||
* iv) A negative error code on failure.
|
||||
*/
|
||||
int16_t handle_rx(const uint8_t port, uint8_t* data,
|
||||
uint16_t length, uint8_t flags);
|
||||
|
||||
/** Send Link Check Request MAC command.
|
||||
*
|
||||
*
|
||||
* This API schedules a Link Check Request command (LinkCheckReq) for the network
|
||||
* server and once the response, i.e., LinkCheckAns MAC command is received
|
||||
* from the Network Server, an event is generated.
|
||||
*
|
||||
* A callback function for the link check response must be set prior to using
|
||||
* this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown.
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK on successfully queuing a request, or
|
||||
* a negative error code on failure.
|
||||
*
|
||||
*/
|
||||
lorawan_status_t set_link_check_request();
|
||||
|
||||
/** Shuts down the LoRaWAN protocol.
|
||||
*
|
||||
* In response to the user call for disconnection, the stack shuts down itself.
|
||||
*
|
||||
* @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
|
||||
*/
|
||||
void shutdown();
|
||||
lorawan_status_t shutdown();
|
||||
|
||||
private:
|
||||
LoRaWANStack();
|
||||
|
@ -286,7 +340,7 @@ private:
|
|||
* State machine for stack controller layer.
|
||||
* Needs to be wriggled for every state change
|
||||
*/
|
||||
lora_mac_status_t lora_state_machine();
|
||||
lorawan_status_t lora_state_machine();
|
||||
|
||||
/**
|
||||
* Sets the current state of the device.
|
||||
|
@ -296,57 +350,38 @@ private:
|
|||
*/
|
||||
void set_device_state(device_states_t new_state);
|
||||
|
||||
/**
|
||||
* This function is used only for compliance testing
|
||||
*/
|
||||
void prepare_special_tx_frame(uint8_t port);
|
||||
|
||||
/**
|
||||
* Hands over the packet to Mac layer by posting an MCPS request.
|
||||
*/
|
||||
lora_mac_status_t send_frame_to_mac();
|
||||
lorawan_status_t send_frame_to_mac();
|
||||
|
||||
/**
|
||||
* Callback function for MCPS confirm. Mac layer calls this function once
|
||||
* an MCPS confirmation is received. This method translates Mac layer data
|
||||
* Callback function for MLME indication. Mac layer calls this function once
|
||||
* an MLME indication is received. This method translates Mac layer data
|
||||
* structure into stack layer data structure.
|
||||
*/
|
||||
void mcps_confirm(McpsConfirm_t *mcps_confirm);
|
||||
|
||||
/**
|
||||
* Callback function for MCPS indication. Mac layer calls this function once
|
||||
* an MCPS indication is received. This method translates Mac layer data
|
||||
* structure into stack layer data structure.
|
||||
*/
|
||||
void mcps_indication(McpsIndication_t *mcps_indication);
|
||||
|
||||
/**
|
||||
* Callback function for MLME confirm. Mac layer calls this function once
|
||||
* an MLME confirmation is received. This method translates Mac layer data
|
||||
* structure into stack layer data structure.
|
||||
*/
|
||||
void mlme_confirm(MlmeConfirm_t *mlme_confirm);
|
||||
void mlme_indication_handler(loramac_mlme_indication_t *mlmeIndication);
|
||||
|
||||
/**
|
||||
* Handles an MLME request coming from the upper layers and delegates
|
||||
* it to the Mac layer, for example, a Join request goes as an MLME request
|
||||
* to the Mac layer.
|
||||
*/
|
||||
lora_mac_status_t mlme_request_handler(lora_mac_mlme_req_t *mlme_request);
|
||||
lorawan_status_t mlme_request_handler(loramac_mlme_req_t *mlme_request);
|
||||
|
||||
/**
|
||||
* Handles an MLME confirmation coming from the Mac layer and uses it to
|
||||
* update the state for example, a Join Accept triggers an MLME confirmation,
|
||||
* that eventually comes here and we take necessary steps accordingly.
|
||||
*/
|
||||
void mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm);
|
||||
void mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm);
|
||||
|
||||
/**
|
||||
* Handles an MCPS request while attempting to hand over a packet from
|
||||
* upper layers to Mac layer. For example in response to send_frame_to_mac(),
|
||||
* an MCPS request is generated.
|
||||
*/
|
||||
lora_mac_status_t mcps_request_handler(lora_mac_mcps_req_t *mcps_request);
|
||||
lorawan_status_t mcps_request_handler(loramac_mcps_req_t *mcps_request);
|
||||
|
||||
/**
|
||||
* Handles an MCPS confirmation coming from the Mac layer in response to an
|
||||
|
@ -354,7 +389,7 @@ private:
|
|||
* e.g., letting the application know that ack was not received in case of
|
||||
* a CONFIRMED message or scheduling error etc.
|
||||
*/
|
||||
void mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm);
|
||||
void mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm);
|
||||
|
||||
/**
|
||||
* Handles an MCPS indication coming from the Mac layer, e.g., once we
|
||||
|
@ -362,22 +397,22 @@ private:
|
|||
* and consequently this handler posts an event to the application that
|
||||
* there is something available to read.
|
||||
*/
|
||||
void mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indication);
|
||||
void mcps_indication_handler(loramac_mcps_indication_t *mcps_indication);
|
||||
|
||||
/**
|
||||
* Sets a MIB request, i.e., update a particular parameter etc.
|
||||
*/
|
||||
lora_mac_status_t mib_set_request(lora_mac_mib_request_confirm_t *mib_set_params);
|
||||
lorawan_status_t mib_set_request(loramac_mib_req_confirm_t *mib_set_params);
|
||||
|
||||
/**
|
||||
* Requests the MIB to inquire about a particular parameter.
|
||||
*/
|
||||
lora_mac_status_t mib_get_request(lora_mac_mib_request_confirm_t *mib_get_params);
|
||||
lorawan_status_t mib_get_request(loramac_mib_req_confirm_t *mib_get_params);
|
||||
|
||||
/**
|
||||
* Sets up user application port
|
||||
*/
|
||||
lora_mac_status_t set_application_port(uint8_t port);
|
||||
lorawan_status_t set_application_port(uint8_t port);
|
||||
|
||||
/**
|
||||
* Helper function to figure out if the user defined data size is possible
|
||||
|
@ -389,22 +424,30 @@ private:
|
|||
*/
|
||||
uint16_t check_possible_tx_size(uint16_t size);
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
/**
|
||||
* Used only for compliance testing
|
||||
* This function is used only for compliance testing
|
||||
*/
|
||||
void compliance_test_handler(lora_mac_mcps_indication_t *mcps_indication);
|
||||
void prepare_special_tx_frame(uint8_t port);
|
||||
|
||||
/**
|
||||
* Used only for compliance testing
|
||||
*/
|
||||
lora_mac_status_t send_compliance_test_frame_to_mac();
|
||||
void compliance_test_handler(loramac_mcps_indication_t *mcps_indication);
|
||||
|
||||
/**
|
||||
* converts error codes from Mac layer to controller layer
|
||||
* Used only for compliance testing
|
||||
*/
|
||||
lora_mac_status_t error_type_converter(LoRaMacStatus_t type);
|
||||
lorawan_status_t send_compliance_test_frame_to_mac();
|
||||
#endif
|
||||
|
||||
LoRaWANTimeHandler _lora_time;
|
||||
LoRaMac _loramac;
|
||||
LoRaPHY_region _lora_phy;
|
||||
loramac_primitives_t LoRaMacPrimitives;
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE];
|
||||
compliance_test_t _compliance_test;
|
||||
#endif
|
||||
|
||||
|
@ -412,8 +455,8 @@ private:
|
|||
lorawan_app_callbacks_t _callbacks;
|
||||
radio_events_t *_mac_handlers;
|
||||
lorawan_session_t _lw_session;
|
||||
lora_mac_tx_message_t _tx_msg;
|
||||
lora_mac_rx_message_t _rx_msg;
|
||||
loramac_tx_message_t _tx_msg;
|
||||
loramac_rx_message_t _rx_msg;
|
||||
uint8_t _app_port;
|
||||
uint8_t _num_retry;
|
||||
events::EventQueue *_queue;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,324 +37,642 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_H__
|
||||
#define __LORAMAC_H__
|
||||
#ifndef MBED_LORAWAN_MAC_H__
|
||||
#define MBED_LORAWAN_MAC_H__
|
||||
|
||||
#include "lorawan/system/LoRaWANTimer.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
#include "lorastack/phy/LoRaPHY.h"
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "lorastack/mac/LoRaMacCommand.h"
|
||||
#include "events/EventQueue.h"
|
||||
#include "lorastack/mac/LoRaMacMlme.h"
|
||||
#include "lorastack/mac/LoRaMacMcps.h"
|
||||
#include "lorastack/mac/LoRaMacMib.h"
|
||||
#include "lorastack/mac/LoRaMacChannelPlan.h"
|
||||
|
||||
/*!
|
||||
* Check the MAC layer state every MAC_STATE_CHECK_TIMEOUT in ms.
|
||||
*/
|
||||
#define MAC_STATE_CHECK_TIMEOUT 1000
|
||||
class LoRaMac {
|
||||
|
||||
/*!
|
||||
* The maximum number of times the MAC layer tries to get an acknowledge.
|
||||
*/
|
||||
#define MAX_ACK_RETRIES 8
|
||||
public:
|
||||
|
||||
/*!
|
||||
* The frame direction definition for uplink communications.
|
||||
*/
|
||||
#define UP_LINK 0
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
LoRaMac(LoRaWANTimeHandler &lora_time);
|
||||
|
||||
/*!
|
||||
* The frame direction definition for downlink communications.
|
||||
*/
|
||||
#define DOWN_LINK 1
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~LoRaMac();
|
||||
|
||||
/**
|
||||
* @brief LoRaMAC layer initialization
|
||||
*
|
||||
* @details In addition to the initialization of the LoRaMAC layer, this
|
||||
* function initializes the callback primitives of the MCPS and
|
||||
* MLME services. Every data field of \ref loramac_primitives_t must be
|
||||
* set to a valid callback function.
|
||||
*
|
||||
* @param primitives [in] A pointer to the structure defining the LoRaMAC
|
||||
* event functions. Refer to \ref loramac_primitives_t.
|
||||
*
|
||||
* @param phy [in] A pointer to the selected PHY layer.
|
||||
*
|
||||
* @param queue [in] A pointer to the application provided EventQueue.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t initialize(loramac_primitives_t *primitives, LoRaPHY *phy,
|
||||
events::EventQueue *queue);
|
||||
|
||||
/*!
|
||||
* LoRaMAC max EIRP (dBm) table.
|
||||
*/
|
||||
static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 };
|
||||
/**
|
||||
* @brief Disconnect LoRaMac layer
|
||||
*
|
||||
* @details Cancels all outstanding requests and sets LoRaMac's
|
||||
* internal state to idle.
|
||||
*/
|
||||
void disconnect(void);
|
||||
|
||||
/**
|
||||
* @brief Queries the LoRaMAC whether it is possible to send the next frame with
|
||||
* a given payload size. The LoRaMAC takes the scheduled MAC commands into
|
||||
* account and reports when the frame can be sent.
|
||||
*
|
||||
* @param size [in] The size of the applicable payload to be sent next.
|
||||
* @param tx_info [out] The structure \ref loramac_tx_info_t contains
|
||||
* information on the actual maximum payload possible
|
||||
* (according to the configured datarate or the next
|
||||
* datarate according to ADR), and the maximum frame
|
||||
* size, taking the scheduled MAC commands into account.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. When the parameters are
|
||||
* not valid, the function returns \ref LORAWAN_STATUS_PARAMETER_INVALID.
|
||||
* In case of a length error caused by the applicable payload in combination
|
||||
* with the MAC commands, the function returns \ref LORAWAN_STATUS_LENGTH_ERROR.
|
||||
* Please note that if the size of the MAC commands in the queue do
|
||||
* not fit into the payload size on the related datarate, the LoRaMAC will
|
||||
* omit the MAC commands.
|
||||
* If the query is valid, and the LoRaMAC is able to send the frame,
|
||||
* the function returns \ref LORAWAN_STATUS_OK.
|
||||
*/
|
||||
lorawan_status_t query_tx_possible(uint8_t size, loramac_tx_info_t* tx_info);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC layer initialization
|
||||
*
|
||||
* \details In addition to the initialization of the LoRaMAC layer, this
|
||||
* function initializes the callback primitives of the MCPS and
|
||||
* MLME services. Every data field of \ref LoRaMacPrimitives_t must be
|
||||
* set to a valid callback function.
|
||||
*
|
||||
* \param primitives [in] - A pointer to the structure defining the LoRaMAC
|
||||
* event functions. Refer to \ref LoRaMacPrimitives_t.
|
||||
*
|
||||
* \param callbacks [in] - A pointer to the structure defining the LoRaMAC
|
||||
* callback functions. Refer to \ref LoRaMacCallback_t.
|
||||
*
|
||||
* \param phy [in]- A pointer to the selected PHY layer.
|
||||
*
|
||||
* \param queue [in]- A pointer to the application provided EventQueue.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
* \ref LORAMAC_STATUS_REGION_NOT_SUPPORTED.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacInitialization(LoRaMacPrimitives_t *primitives,
|
||||
LoRaMacCallback_t *callbacks,
|
||||
LoRaPHY *phy,
|
||||
events::EventQueue *queue);
|
||||
/**
|
||||
* @brief Adds a channel plan to the system.
|
||||
*
|
||||
* @details Adds a whole channel plan or a single new channel if the plan
|
||||
* contains only one channel and 'plan.nb_channels' is set to 1.
|
||||
* Please note that this functionality is not available in all regions.
|
||||
* Information on the allowed ranges is available at the
|
||||
* LoRaWAN Regional Parameters V1.0.2rB.
|
||||
*
|
||||
* @param plan [in] A reference to application provided channel plan.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t add_channel_plan(const lorawan_channelplan_t& plan);
|
||||
|
||||
/*!
|
||||
* \brief Queries the LoRaMAC whether it is possible to send the next frame with
|
||||
* a given payload size. The LoRaMAC takes the scheduled MAC commands into
|
||||
* account and reports when the frame can be sent.
|
||||
*
|
||||
* \param size [in]- The size of the applicable payload to be sent next.
|
||||
* \param txInfo [out] - The structure \ref LoRaMacTxInfo_t contains
|
||||
* information on the actual maximum payload possible
|
||||
* (according to the configured datarate or the next
|
||||
* datarate according to ADR), and the maximum frame
|
||||
* size, taking the scheduled MAC commands into account.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. When the parameters are
|
||||
* not valid, the function returns \ref LORAMAC_STATUS_PARAMETER_INVALID.
|
||||
* In case of a length error caused by the applicable payload in combination
|
||||
* with the MAC commands, the function returns \ref LORAMAC_STATUS_LENGTH_ERROR.
|
||||
* Please note that if the size of the MAC commands in the queue do
|
||||
* not fit into the payload size on the related datarate, the LoRaMAC will
|
||||
* omit the MAC commands.
|
||||
* If the query is valid, and the LoRaMAC is able to send the frame,
|
||||
* the function returns \ref LORAMAC_STATUS_OK.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo );
|
||||
/**
|
||||
* @brief Removes a channel plan from the system.
|
||||
*
|
||||
* @details Removes the whole active channel plan except the 'Default Channels'.
|
||||
* Please note that this functionality is not available in all regions.
|
||||
* Information on the allowed ranges is available at the
|
||||
* LoRaWAN Regional Parameters V1.0.2rB.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t remove_channel_plan();
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC channel add service.
|
||||
*
|
||||
* \details Adds a new channel to the channel list and activates the ID in
|
||||
* the channel mask. Please note that this functionality is not available
|
||||
* in all regions. Information on the allowed ranges is available at the LoRaWAN Regional Parameters V1.0.2rB.
|
||||
*
|
||||
* \param id [in] - The ID of the channel.
|
||||
*
|
||||
* \param params [in] - The channel parameters to set.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params );
|
||||
/**
|
||||
* @brief Access active channel plan.
|
||||
*
|
||||
* @details Provides access to the current active channel plan.
|
||||
*
|
||||
* @param plan [out] A reference to application provided channel plan data
|
||||
* structure which will be filled in with active channel
|
||||
* plan.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t get_channel_plan(lorawan_channelplan_t& plan);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC channel remove service.
|
||||
*
|
||||
* \details Deactivates the ID in the channel mask.
|
||||
*
|
||||
* \param id - Id of the channel.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id );
|
||||
/**
|
||||
* @brief Remove a given channel from the active plan.
|
||||
*
|
||||
* @details Deactivates the given channel.
|
||||
*
|
||||
* @param id Id of the channel.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t remove_single_channel(uint8_t id);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel link service.
|
||||
*
|
||||
* \details Links a multicast channel into the linked list.
|
||||
*
|
||||
* \param [in] channelParam - The multicast channel parameters to link.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam );
|
||||
/**
|
||||
* @brief LoRaMAC multicast channel link service.
|
||||
*
|
||||
* @details Links a multicast channel into the linked list.
|
||||
*
|
||||
* @param [in] channel_param The multicast channel parameters to link.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t multicast_channel_link(multicast_params_t *channel_param);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel unlink service.
|
||||
*
|
||||
* \details Unlinks a multicast channel from the linked list.
|
||||
*
|
||||
* \param [in] channelParam - The multicast channel parameters to unlink.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam );
|
||||
/**
|
||||
* @brief LoRaMAC multicast channel unlink service.
|
||||
*
|
||||
* @details Unlinks a multicast channel from the linked list.
|
||||
*
|
||||
* @param [in] channel_param The multicast channel parameters to unlink.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t multicast_channel_unlink(multicast_params_t *channel_param);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MIB-GET.
|
||||
*
|
||||
* \details The MAC information base service to get the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to get the
|
||||
* parameter `AdrEnable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
* \code
|
||||
* MibRequestConfirm_t mibReq;
|
||||
* mibReq.Type = MIB_ADR;
|
||||
*
|
||||
* if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK )
|
||||
* {
|
||||
* // LoRaMAC updated the parameter mibParam.AdrEnable
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mibGet - The MIB-GET request to perform. Refer to \ref MibRequestConfirm_t.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet );
|
||||
/**
|
||||
* @brief Get parameter values from MIB service.
|
||||
*
|
||||
* @details The MAC information base service to get the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to get the
|
||||
* parameter `AdrEnable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* loramac_mib_req_confirm_t mib_get;
|
||||
* mib_get.type = MIB_ADR;
|
||||
*
|
||||
* if (mib_get_request_confirm(&mib_get) == LORAWAN_STATUS_OK) {
|
||||
* // LoRaMAC updated the parameter mibParam.AdrEnable
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @param [in] mib_get The MIB-GET request to perform. Refer to
|
||||
* \ref loramac_mib_req_confirm_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation.
|
||||
* The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t mib_get_request_confirm(loramac_mib_req_confirm_t *mib_get);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MIB-SET.
|
||||
*
|
||||
* \details The MAC information base service to set the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to set the
|
||||
* parameter `AdrEnable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
*
|
||||
* \code
|
||||
* MibRequestConfirm_t mibReq;
|
||||
* mibReq.Type = MIB_ADR;
|
||||
* mibReq.Param.AdrEnable = true;
|
||||
*
|
||||
* if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK )
|
||||
* {
|
||||
* // LoRaMAC updated the parameter
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mibSet - The MIB-SET request to perform. Refer to \ref MibRequestConfirm_t.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet );
|
||||
/**
|
||||
* @brief Set attributes for MAC layer using MIB service.
|
||||
*
|
||||
* @details The MAC information base service to set the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to set the
|
||||
* parameter `adr_enable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* loramac_mib_req_confirm_t mib_set;
|
||||
* mib_set.Type = MIB_ADR;
|
||||
* mib_set.param.adr_enable = true;
|
||||
*
|
||||
* if (mib_set_request_confirm(&mib_set) == LORAWAN_STATUS_OK) {
|
||||
* // LoRaMAC updated the parameter
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @param [in] mib_set The MIB-SET request to perform. Refer to
|
||||
* \ref loramac_mib_req_confirm_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t mib_set_request_confirm(loramac_mib_req_confirm_t *mib_set);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MLME request
|
||||
*
|
||||
* \details The MAC layer management entity handles the management services. The
|
||||
* following code-snippet shows how to use the API to perform a
|
||||
* network join request.
|
||||
*
|
||||
* \code
|
||||
* static uint8_t DevEui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t AppEui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t AppKey[] =
|
||||
* {
|
||||
* 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
|
||||
* 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
|
||||
* };
|
||||
*
|
||||
* MlmeReq_t mlmeReq;
|
||||
* mlmeReq.Type = MLME_JOIN;
|
||||
* mlmeReq.Req.Join.DevEui = DevEui;
|
||||
* mlmeReq.Req.Join.AppEui = AppEui;
|
||||
* mlmeReq.Req.Join.AppKey = AppKey;
|
||||
*
|
||||
* if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK )
|
||||
* {
|
||||
* // Service started successfully. Waiting for the Mlme-Confirm event
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mlmeRequest - The MLME request to perform. Refer to \ref MlmeReq_t.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
* \ref LORAMAC_STATUS_NO_NETWORK_JOINED
|
||||
* \ref LORAMAC_STATUS_LENGTH_ERROR
|
||||
* \ref LORAMAC_STATUS_DEVICE_OFF
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest );
|
||||
/**
|
||||
* @brief Set forth an MLME request.
|
||||
*
|
||||
* @details The MAC layer management entity handles the management services. The
|
||||
* following code-snippet shows how to use the API to perform a
|
||||
* network join request.
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* static uint8_t dev_eui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t app_eui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t app_key[] =
|
||||
* {
|
||||
* 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
|
||||
* 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
|
||||
* };
|
||||
*
|
||||
* loramac_mlme_req_t mlme_req;
|
||||
* mlme_req.Type = MLME_JOIN;
|
||||
* mlme_req.req.join.dev_eui = dev_eui;
|
||||
* mlme_req.req.join.app_eui = app_eui;
|
||||
* mlme_req.req.join.app_key = app_key;
|
||||
*
|
||||
* if (LoRaMacMlmeRequest(&mlme_req) == LORAWAN_STATUS_OK) {
|
||||
* // Service started successfully. Waiting for the Mlme-Confirm event
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @param [in] request The MLME request to perform.
|
||||
* Refer to \ref loramac_mlme_req_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
* \ref LORAWAN_STATUS_NO_NETWORK_JOINED
|
||||
* \ref LORAWAN_STATUS_LENGTH_ERROR
|
||||
* \ref LORAWAN_STATUS_DEVICE_OFF
|
||||
*/
|
||||
lorawan_status_t mlme_request(loramac_mlme_req_t *request);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MCPS request
|
||||
*
|
||||
* \details The MAC Common Part Sublayer handles the data services. The following
|
||||
* code-snippet shows how to use the API to send an unconfirmed
|
||||
* LoRaMAC frame.
|
||||
*
|
||||
* \code
|
||||
* uint8_t myBuffer[] = { 1, 2, 3 };
|
||||
*
|
||||
* McpsReq_t mcpsReq;
|
||||
* mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
* mcpsReq.Req.Unconfirmed.fPort = 1;
|
||||
* mcpsReq.Req.Unconfirmed.fBuffer = myBuffer;
|
||||
* mcpsReq.Req.Unconfirmed.fBufferSize = sizeof( myBuffer );
|
||||
*
|
||||
* if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
|
||||
* {
|
||||
* // Service started successfully. Waiting for the MCPS-Confirm event
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref McpsReq_t.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
* \ref LORAMAC_STATUS_NO_NETWORK_JOINED
|
||||
* \ref LORAMAC_STATUS_LENGTH_ERROR
|
||||
* \ref LORAMAC_STATUS_DEVICE_OFF
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest );
|
||||
/**
|
||||
* @brief Set forth an MCPS request.
|
||||
*
|
||||
* @details The MAC Common Part Sublayer handles the data services. The following
|
||||
* code-snippet shows how to use the API to send an unconfirmed
|
||||
* LoRaMAC frame.
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* uint8_t buffer[] = {1, 2, 3};
|
||||
*
|
||||
* loramac_mcps_req_t request;
|
||||
* request.type = MCPS_UNCONFIRMED;
|
||||
* request.req.unconfirmed.fport = 1;
|
||||
* request.req.unconfirmed.f_buffer = buffer;
|
||||
* request.req.unconfirmed.f_buffer_size = sizeof(buffer);
|
||||
*
|
||||
* if (mcps_request(&request) == LORAWAN_STATUS_OK) {
|
||||
* // Service started successfully. Waiting for the MCPS-Confirm event
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @param [in] request The MCPS request to perform.
|
||||
* Refer to \ref loramac_mcps_req_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
* \ref LORAWAN_STATUS_NO_NETWORK_JOINED
|
||||
* \ref LORAWAN_STATUS_LENGTH_ERROR
|
||||
* \ref LORAWAN_STATUS_DEVICE_OFF
|
||||
*/
|
||||
lorawan_status_t mcps_request(loramac_mcps_req_t *request);
|
||||
|
||||
/**
|
||||
* \brief LoRaMAC layer provides its callback functions for
|
||||
* PHY layer
|
||||
*
|
||||
* \return Pointer to callback functions for radio events
|
||||
*/
|
||||
radio_events_t *GetPhyEventHandlers();
|
||||
/**
|
||||
* @brief LoRaMAC layer provides its callback functions for
|
||||
* PHY layer.
|
||||
*
|
||||
* @return Pointer to callback functions for radio events
|
||||
*/
|
||||
radio_events_t *get_phy_event_handlers();
|
||||
|
||||
/**
|
||||
* @brief Configures the events to trigger an MLME-Indication with
|
||||
* a MLME type of MLME_SCHEDULE_UPLINK.
|
||||
*/
|
||||
void set_mlme_schedule_ul_indication(void);
|
||||
|
||||
/**
|
||||
* @brief Schedules the frame for sending.
|
||||
*
|
||||
* @details Prepares a full MAC frame and schedules it for physical
|
||||
* transmission.
|
||||
*
|
||||
* @param [in] mac_hdr MAC frame header field
|
||||
* @param [in] fport Payload port
|
||||
* @param [in] fbuffer MAC frame data buffer to be sent
|
||||
* @param [in] fbuffer_size MAC frame data buffer size
|
||||
*
|
||||
* @return status Status of the operation. LORAWAN_STATUS_OK in case
|
||||
* of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
lorawan_status_t send(loramac_mhdr_t *mac_hdr, uint8_t fport, void *fbuffer,
|
||||
uint16_t fbuffer_size);
|
||||
|
||||
/**
|
||||
* @brief Puts the system in continuous transmission mode
|
||||
*
|
||||
* @remark Uses the radio parameters set on the previous transmission.
|
||||
*
|
||||
* @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
|
||||
*
|
||||
* @return status Status of the operation. LORAWAN_STATUS_OK in case
|
||||
* of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
lorawan_status_t set_tx_continuous_wave(uint16_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Puts the system in continuous transmission mode
|
||||
*
|
||||
* @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
|
||||
* @param [in] frequency RF frequency to be set.
|
||||
* @param [in] power RF output power to be set.
|
||||
*
|
||||
* @return status Status of the operation. LORAWAN_STATUS_OK in case
|
||||
* of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
lorawan_status_t set_tx_continuous_wave1(uint16_t timeout, uint32_t frequency, uint8_t power);
|
||||
|
||||
/**
|
||||
* @brief Resets MAC specific parameters to default
|
||||
*/
|
||||
void reset_mac_parameters(void);
|
||||
|
||||
/**
|
||||
* @brief Opens up a continuous RX 2 window. This is used for
|
||||
* class c devices.
|
||||
*/
|
||||
void open_continuous_rx2_window(void);
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
/**
|
||||
* \brief LoRaMAC set tx timer.
|
||||
*
|
||||
* \details Sets up a timer for next transmission (application specific timers).
|
||||
*
|
||||
* \param [in] NextTxTime - Periodic time for next uplink.
|
||||
public: // Test interface
|
||||
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacSetTxTimer( uint32_t NextTxTime );
|
||||
/**
|
||||
* \brief LoRaMAC set tx timer.
|
||||
*
|
||||
* \details Sets up a timer for next transmission (application specific timers).
|
||||
*
|
||||
* \param [in] NextTxTime - Periodic time for next uplink.
|
||||
|
||||
/**
|
||||
* \brief LoRaMAC stop tx timer.
|
||||
*
|
||||
* \details Stops the next tx timer.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \ref LORAMAC_STATUS_OK
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacStopTxTimer( );
|
||||
* \retval `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacSetTxTimer( uint32_t NextTxTime );
|
||||
|
||||
/**
|
||||
* \brief LoRaMAC stop tx timer.
|
||||
*
|
||||
* \details Stops the next tx timer.
|
||||
*
|
||||
* \retval `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacStopTxTimer( );
|
||||
|
||||
/**
|
||||
* \brief Enabled or disables the reception windows
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] enable - Enabled or disables the reception windows
|
||||
*/
|
||||
void LoRaMacTestRxWindowsOn( bool enable );
|
||||
|
||||
/**
|
||||
* \brief Enables the MIC field test
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] txPacketCounter - Fixed Tx packet counter value
|
||||
*/
|
||||
void LoRaMacTestSetMic( uint16_t txPacketCounter );
|
||||
|
||||
/**
|
||||
* \brief Enabled or disables the duty cycle
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] enable - Enabled or disables the duty cycle
|
||||
*/
|
||||
void LoRaMacTestSetDutyCycleOn( bool enable );
|
||||
|
||||
/**
|
||||
* \brief Sets the channel index
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] channel - Channel index
|
||||
*/
|
||||
void LoRaMacTestSetChannel( uint8_t channel );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Timer to handle the application data transmission duty cycle
|
||||
*/
|
||||
timer_event_t tx_next_packet_timer;
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_H__
|
||||
private:
|
||||
/**
|
||||
* Function to be executed on Radio Tx Done event
|
||||
*/
|
||||
void on_radio_tx_done(void);
|
||||
|
||||
/**
|
||||
* This function prepares the MAC to abort the execution of function
|
||||
* on_radio_rx_done() in case of a reception error.
|
||||
*/
|
||||
void prepare_rx_done_abort(void);
|
||||
|
||||
/**
|
||||
* Function to be executed on Radio Rx Done event
|
||||
*/
|
||||
void on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
||||
int8_t snr);
|
||||
|
||||
/**
|
||||
* Function executed on Radio Tx Timeout event
|
||||
*/
|
||||
void on_radio_tx_timeout(void);
|
||||
|
||||
/**
|
||||
* Function executed on Radio Rx error event
|
||||
*/
|
||||
void on_radio_rx_error(void);
|
||||
|
||||
/**
|
||||
* Function executed on Radio Rx Timeout event
|
||||
*/
|
||||
void on_radio_rx_timeout(void);
|
||||
|
||||
/**
|
||||
*Function executed on Resend Frame timer event.
|
||||
*/
|
||||
void on_mac_state_check_timer_event(void);
|
||||
|
||||
/**
|
||||
* Function executed on duty cycle delayed Tx timer event
|
||||
*/
|
||||
void on_tx_delayed_timer_event(void);
|
||||
|
||||
/**
|
||||
* Function executed on first Rx window timer event
|
||||
*/
|
||||
void on_rx_window1_timer_event(void);
|
||||
|
||||
/**
|
||||
* Function executed on second Rx window timer event
|
||||
*/
|
||||
void on_rx_window2_timer_event(void);
|
||||
|
||||
/**
|
||||
* Function executed on AckTimeout timer event
|
||||
*/
|
||||
void on_ack_timeout_timer_event(void);
|
||||
|
||||
/**
|
||||
* Initializes and opens the reception window
|
||||
*/
|
||||
void rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time);
|
||||
|
||||
/**
|
||||
* Validates if the payload fits into the frame, taking the datarate
|
||||
* into account.
|
||||
*
|
||||
* Please Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0.2
|
||||
*/
|
||||
bool validate_payload_length(uint8_t length, int8_t datarate, uint8_t fopts_len);
|
||||
|
||||
/**
|
||||
* Prepares MAC frame on the behest of send() API.
|
||||
*/
|
||||
lorawan_status_t prepare_frame(loramac_mhdr_t *mac_hdr,
|
||||
loramac_frame_ctrl_t *fctrl, uint8_t fport,
|
||||
void *fbuffer, uint16_t fbuffer_size);
|
||||
|
||||
/**
|
||||
* Schedules a transmission on the behest of send() API.
|
||||
*/
|
||||
lorawan_status_t schedule_tx(void);
|
||||
|
||||
/**
|
||||
* Calculates the back-off time for the band of a channel.
|
||||
* Takes in the last used channel id as a parameter.
|
||||
*/
|
||||
void calculate_backOff(uint8_t channel_id);
|
||||
|
||||
/**
|
||||
* Hands over the MAC frame to PHY layer.
|
||||
*/
|
||||
lorawan_status_t send_frame_on_channel(uint8_t channel);
|
||||
|
||||
/**
|
||||
* Checks for Port validity.
|
||||
*/
|
||||
bool is_fPort_allowed(uint8_t fPort);
|
||||
|
||||
/**
|
||||
* Prototypes for ISR handlers
|
||||
*/
|
||||
void handle_cad_done(bool cad);
|
||||
void handle_tx_done(void);
|
||||
void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
||||
int8_t snr);
|
||||
void handle_rx_error(void);
|
||||
void handle_rx_timeout(void);
|
||||
void handle_tx_timeout(void);
|
||||
void handle_fhss_change_channel(uint8_t cur_channel);
|
||||
void handle_rx1_timer_event(void);
|
||||
void handle_rx2_timer_event(void);
|
||||
void handle_ack_timeout(void);
|
||||
void handle_delayed_tx_timer_event(void);
|
||||
void handle_mac_state_check_timer_event(void);
|
||||
void handle_next_tx_timer_event(void);
|
||||
|
||||
private:
|
||||
/**
|
||||
* LoRa PHY layer object storage
|
||||
*/
|
||||
LoRaPHY *lora_phy;
|
||||
|
||||
/**
|
||||
* MAC command handle
|
||||
*/
|
||||
LoRaMacCommand mac_commands;
|
||||
|
||||
/**
|
||||
* MLME subsystem handle
|
||||
*/
|
||||
LoRaMacMlme mlme;
|
||||
|
||||
/**
|
||||
* MCPS subsystem handle
|
||||
*/
|
||||
LoRaMacMcps mcps;
|
||||
|
||||
/**
|
||||
* MCPS subsystem handle
|
||||
*/
|
||||
LoRaMacMib mib;
|
||||
|
||||
/**
|
||||
* Channel planning subsystem
|
||||
*/
|
||||
LoRaMacChannelPlan channel_plan;
|
||||
|
||||
/**
|
||||
* Timer subsystem handle
|
||||
*/
|
||||
LoRaWANTimeHandler &_lora_time;
|
||||
|
||||
/**
|
||||
* Central MAC layer data storage
|
||||
*/
|
||||
loramac_protocol_params _params;
|
||||
|
||||
/**
|
||||
* Radio event callback handlers for MAC
|
||||
*/
|
||||
radio_events_t radio_events;
|
||||
|
||||
/**
|
||||
* LoRaMac upper layer event functions
|
||||
*/
|
||||
loramac_primitives_t *mac_primitives;
|
||||
|
||||
/**
|
||||
* EventQueue object storage
|
||||
*/
|
||||
events::EventQueue *ev_queue;
|
||||
};
|
||||
|
||||
#endif // MBED_LORAWAN_MAC_H__
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "lorastack/mac/LoRaMacChannelPlan.h"
|
||||
|
||||
LoRaMacChannelPlan::LoRaMacChannelPlan() : _lora_phy(NULL), _mib(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoRaMacChannelPlan::~LoRaMacChannelPlan()
|
||||
{
|
||||
}
|
||||
|
||||
void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy, LoRaMacMib *mib)
|
||||
{
|
||||
_lora_phy = phy;
|
||||
_mib = mib;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan)
|
||||
{
|
||||
channel_params_t mac_layer_ch_params;
|
||||
lorawan_status_t status;
|
||||
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phy_param;
|
||||
uint8_t max_num_channels;
|
||||
|
||||
// Check if the PHY layer supports custom channel plans or not.
|
||||
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
|
||||
if (!phy_param.value) {
|
||||
return LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Check first how many channels the selected PHY layer supports
|
||||
get_phy.attribute = PHY_MAX_NB_CHANNELS;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
max_num_channels = (uint8_t) phy_param.value;
|
||||
|
||||
// check if user is setting more channels than supported
|
||||
if (plan.nb_channels > max_num_channels) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < plan.nb_channels; i++) {
|
||||
|
||||
mac_layer_ch_params.band = plan.channels[i].ch_param.band;
|
||||
|
||||
mac_layer_ch_params.dr_range.fields.max = plan.channels[i].ch_param.dr_range.fields.max;
|
||||
mac_layer_ch_params.dr_range.fields.min = plan.channels[i].ch_param.dr_range.fields.min;
|
||||
mac_layer_ch_params.dr_range.value = plan.channels[i].ch_param.dr_range.value;
|
||||
mac_layer_ch_params.frequency = plan.channels[i].ch_param.frequency;
|
||||
mac_layer_ch_params.rx1_frequency = plan.channels[i].ch_param.rx1_frequency;
|
||||
|
||||
status = _lora_phy->add_channel(&mac_layer_ch_params, plan.channels[i].id);
|
||||
|
||||
if (status != LORAWAN_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
|
||||
loramac_protocol_params *params)
|
||||
{
|
||||
if (params == NULL) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
loramac_mib_req_confirm_t mib_confirm;
|
||||
lorawan_status_t status;
|
||||
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phy_param;
|
||||
uint8_t max_num_channels;
|
||||
uint16_t *channel_mask;
|
||||
uint8_t count = 0;
|
||||
|
||||
// Check if the PHY layer supports custom channel plans or not.
|
||||
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
|
||||
if (!phy_param.value) {
|
||||
return LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Check first how many channels the selected PHY layer supports
|
||||
get_phy.attribute = PHY_MAX_NB_CHANNELS;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
max_num_channels = (uint8_t) phy_param.value;
|
||||
|
||||
// Now check the Default channel mask
|
||||
get_phy.attribute = PHY_CHANNEL_MASK;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
channel_mask = phy_param.channel_mask;
|
||||
|
||||
// Request Mib to get channels
|
||||
memset(&mib_confirm, 0, sizeof(mib_confirm));
|
||||
mib_confirm.type = MIB_CHANNELS;
|
||||
|
||||
status = _mib->get_request(&mib_confirm, params);
|
||||
|
||||
if (status != LORAWAN_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < max_num_channels; i++) {
|
||||
// skip the channels which are not enabled
|
||||
if (_lora_phy->mask_bit_test(channel_mask, i) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// otherwise add them to the channel_plan struct
|
||||
plan.channels[count].id = i;
|
||||
plan.channels[count].ch_param.frequency = mib_confirm.param.channel_list[i].frequency;
|
||||
plan.channels[count].ch_param.dr_range.value = mib_confirm.param.channel_list[i].dr_range.value;
|
||||
plan.channels[count].ch_param.dr_range.fields.min = mib_confirm.param.channel_list[i].dr_range.fields.min;
|
||||
plan.channels[count].ch_param.dr_range.fields.max = mib_confirm.param.channel_list[i].dr_range.fields.max;
|
||||
plan.channels[count].ch_param.band = mib_confirm.param.channel_list[i].band;
|
||||
plan.channels[count].ch_param.rx1_frequency = mib_confirm.param.channel_list[i].rx1_frequency;
|
||||
count++;
|
||||
}
|
||||
|
||||
plan.nb_channels = count;
|
||||
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacChannelPlan::remove_plan()
|
||||
{
|
||||
lorawan_status_t status = LORAWAN_STATUS_OK;
|
||||
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phy_param;
|
||||
uint8_t max_num_channels;
|
||||
uint16_t *channel_mask;
|
||||
uint16_t *default_channel_mask;
|
||||
|
||||
// Check if the PHY layer supports custom channel plans or not.
|
||||
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
|
||||
if (!phy_param.value) {
|
||||
return LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Check first how many channels the selected PHY layer supports
|
||||
get_phy.attribute = PHY_MAX_NB_CHANNELS;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
max_num_channels = (uint8_t) phy_param.value;
|
||||
|
||||
// Now check the channel mask for enabled channels
|
||||
get_phy.attribute = PHY_CHANNEL_MASK;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
channel_mask = phy_param.channel_mask;
|
||||
|
||||
// Now check the channel mask for default channels
|
||||
get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
default_channel_mask = phy_param.channel_mask;
|
||||
|
||||
for (uint8_t i = 0; i < max_num_channels; i++) {
|
||||
// skip any default channels
|
||||
if (_lora_phy->mask_bit_test(default_channel_mask, i) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip any channels which are not currently enabled
|
||||
if (_lora_phy->mask_bit_test(channel_mask, i) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
status = remove_single_channel(i);
|
||||
|
||||
if (status != LORAWAN_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id)
|
||||
{
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phy_param;
|
||||
uint8_t max_num_channels;
|
||||
|
||||
// Check if the PHY layer supports custom channel plans or not.
|
||||
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
|
||||
if (!phy_param.value) {
|
||||
return LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Check first how many channels the selected PHY layer supports
|
||||
get_phy.attribute = PHY_MAX_NB_CHANNELS;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
max_num_channels = (uint8_t) phy_param.value;
|
||||
|
||||
// According to specification channel IDs start from 0 and last valid
|
||||
// channel ID is N-1 where N=MAX_NUM_CHANNELS.
|
||||
// So any ID which is larger or equal to the Max number of channels is invalid
|
||||
if (channel_id >= max_num_channels) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
if (_lora_phy->remove_channel(channel_id) == false) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
_lora_phy->put_radio_to_sleep();
|
||||
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
\code
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
\endcode
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MBED_LORAWAN_LORAMACCHANNELPLAN_H_
|
||||
#define MBED_LORAWAN_LORAMACCHANNELPLAN_H_
|
||||
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "lorastack/phy/LoRaPHY.h"
|
||||
#include "lorastack/mac/LoRaMacMib.h"
|
||||
|
||||
class LoRaMacChannelPlan {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* Sets local handles to NULL. These handles will be set when the subsystem
|
||||
* is activated by the MAC layer.
|
||||
*/
|
||||
LoRaMacChannelPlan();
|
||||
|
||||
/** Destructor
|
||||
*
|
||||
* Does nothing
|
||||
*/
|
||||
~LoRaMacChannelPlan();
|
||||
|
||||
/** Activates Channel Planning subsystem
|
||||
*
|
||||
* Stores pointers to PHY layer MIB subsystem
|
||||
*
|
||||
* @param phy pointer to PHY layer
|
||||
* @param mib pointer to MIB subsystem
|
||||
*/
|
||||
void activate_channelplan_subsystem(LoRaPHY *phy,LoRaMacMib *mib);
|
||||
|
||||
/** Set a given channel plan
|
||||
*
|
||||
* Used to set application provided channel plan. This API can be used to
|
||||
* set a single channel as well to the existing channel plan.
|
||||
*
|
||||
* @param plan a reference to application channel plan. PHY layer takes a
|
||||
* copy of the channel parameters provided within.
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t set_plan(const lorawan_channelplan_t& plan);
|
||||
|
||||
/** Access the active channel plan
|
||||
*
|
||||
* Used to get active channel plan.
|
||||
*
|
||||
* @param plan a reference to application provided channel plan structure
|
||||
* which gets filled in with active channel plan data.
|
||||
*
|
||||
* @param params pointer to active MAC layer parameters.
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t get_plan(lorawan_channelplan_t& plan, loramac_protocol_params *params);
|
||||
|
||||
/** Remove the active channel plan
|
||||
*
|
||||
* Drops the whole channel list except the 'Default Channels' ofcourse.
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t remove_plan();
|
||||
|
||||
/** Remove a single channel from the plan
|
||||
*
|
||||
* @param id the channel id which needs to be removed
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t remove_single_channel(uint8_t id);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Local handles
|
||||
*/
|
||||
LoRaPHY *_lora_phy;
|
||||
LoRaMacMib * _mib;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* MBED_LORAWAN_LORAMACCHANNELPLAN_H_ */
|
|
@ -0,0 +1,424 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC layer implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include "LoRaMacCommand.h"
|
||||
#include "LoRaMac.h"
|
||||
|
||||
#if defined(FEATURE_COMMON_PAL)
|
||||
#include "mbed_trace.h"
|
||||
#define TRACE_GROUP "LMACC"
|
||||
#else
|
||||
#define tr_debug(...) (void(0)) //dummies if feature common pal is not added
|
||||
#define tr_info(...) (void(0)) //dummies if feature common pal is not added
|
||||
#define tr_error(...) (void(0)) //dummies if feature common pal is not added
|
||||
#endif //defined(FEATURE_COMMON_PAL)
|
||||
|
||||
/**
|
||||
* LoRaMAC max EIRP (dBm) table.
|
||||
*/
|
||||
static const uint8_t max_eirp_table[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 };
|
||||
|
||||
|
||||
LoRaMacCommand::LoRaMacCommand(LoRaMac& lora_mac)
|
||||
: _lora_mac(lora_mac)
|
||||
{
|
||||
mac_cmd_in_next_tx = false;
|
||||
mac_cmd_buf_idx = 0;
|
||||
mac_cmd_buf_idx_to_repeat = 0;
|
||||
|
||||
memset(mac_cmd_buffer, 0, sizeof(mac_cmd_buffer));
|
||||
memset(mac_cmd_buffer_to_repeat, 0, sizeof(mac_cmd_buffer_to_repeat));
|
||||
}
|
||||
|
||||
LoRaMacCommand::~LoRaMacCommand()
|
||||
{
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacCommand::add_mac_command(uint8_t cmd, uint8_t p1,
|
||||
uint8_t p2)
|
||||
{
|
||||
lorawan_status_t status = LORAWAN_STATUS_BUSY;
|
||||
// The maximum buffer length must take MAC commands to re-send into account.
|
||||
const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH
|
||||
- mac_cmd_buf_idx_to_repeat;
|
||||
|
||||
switch (cmd) {
|
||||
case MOTE_MAC_LINK_CHECK_REQ:
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this command
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_LINK_ADR_ANS:
|
||||
if (mac_cmd_buf_idx < (bufLen - 1)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Margin
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_DUTY_CYCLE_ANS:
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this answer
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS:
|
||||
if (mac_cmd_buf_idx < (bufLen - 1)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Status: Datarate ACK, Channel ACK
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
// This is a sticky MAC command answer. Setup indication
|
||||
_lora_mac.set_mlme_schedule_ul_indication();
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_DEV_STATUS_ANS:
|
||||
if (mac_cmd_buf_idx < (bufLen - 2)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// 1st byte Battery
|
||||
// 2nd byte Margin
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p2;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_NEW_CHANNEL_ANS:
|
||||
if (mac_cmd_buf_idx < (bufLen - 1)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Status: Datarate range OK, Channel frequency OK
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS:
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this answer
|
||||
// This is a sticky MAC command answer. Setup indication
|
||||
_lora_mac.set_mlme_schedule_ul_indication();
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_TX_PARAM_SETUP_ANS:
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this answer
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_DL_CHANNEL_ANS:
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Status: Uplink frequency exists, Channel frequency OK
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
// This is a sticky MAC command answer. Setup indication
|
||||
_lora_mac.set_mlme_schedule_ul_indication();
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
}
|
||||
if (status == LORAWAN_STATUS_OK) {
|
||||
mac_cmd_in_next_tx = true;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::clear_command_buffer()
|
||||
{
|
||||
mac_cmd_buf_idx = 0;
|
||||
}
|
||||
|
||||
uint8_t LoRaMacCommand::get_mac_cmd_length() const
|
||||
{
|
||||
return mac_cmd_buf_idx;
|
||||
}
|
||||
|
||||
uint8_t *LoRaMacCommand::get_mac_commands_buffer()
|
||||
{
|
||||
return mac_cmd_buffer;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::parse_mac_commands_to_repeat()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t cmd_cnt = 0;
|
||||
|
||||
for (i = 0; i < mac_cmd_buf_idx; i++) {
|
||||
switch (mac_cmd_buffer[i]) {
|
||||
// STICKY
|
||||
case MOTE_MAC_DL_CHANNEL_ANS:
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS: { // 1 byte payload
|
||||
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i++];
|
||||
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i];
|
||||
break;
|
||||
}
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS: { // 0 byte payload
|
||||
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i];
|
||||
break;
|
||||
}
|
||||
// NON-STICKY
|
||||
case MOTE_MAC_DEV_STATUS_ANS: { // 2 bytes payload
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
case MOTE_MAC_LINK_ADR_ANS:
|
||||
case MOTE_MAC_NEW_CHANNEL_ANS: { // 1 byte payload
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
case MOTE_MAC_TX_PARAM_SETUP_ANS:
|
||||
case MOTE_MAC_DUTY_CYCLE_ANS:
|
||||
case MOTE_MAC_LINK_CHECK_REQ: { // 0 byte payload
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd_cnt > 0) {
|
||||
mac_cmd_in_next_tx = true;
|
||||
} else {
|
||||
mac_cmd_in_next_tx = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LoRaMacCommand::clear_repeat_buffer()
|
||||
{
|
||||
mac_cmd_buf_idx_to_repeat = 0;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::copy_repeat_commands_to_buffer()
|
||||
{
|
||||
// Copy the MAC commands which must be re-send into the MAC command buffer
|
||||
memcpy(&mac_cmd_buffer[mac_cmd_buf_idx], mac_cmd_buffer_to_repeat, mac_cmd_buf_idx_to_repeat);
|
||||
mac_cmd_buf_idx += mac_cmd_buf_idx_to_repeat;
|
||||
}
|
||||
|
||||
uint8_t LoRaMacCommand::get_repeat_commands_length() const
|
||||
{
|
||||
return mac_cmd_buf_idx_to_repeat;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::clear_mac_commands_in_next_tx()
|
||||
{
|
||||
mac_cmd_in_next_tx = false;
|
||||
}
|
||||
|
||||
bool LoRaMacCommand::is_mac_command_in_next_tx() const
|
||||
{
|
||||
return mac_cmd_in_next_tx;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload,
|
||||
uint8_t mac_index,
|
||||
uint8_t commands_size,
|
||||
uint8_t snr,
|
||||
loramac_mlme_confirm_t& mlme_conf,
|
||||
lora_mac_system_params_t &mac_sys_params,
|
||||
LoRaPHY &lora_phy)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
lorawan_status_t ret_value = LORAWAN_STATUS_OK;
|
||||
|
||||
while (mac_index < commands_size) {
|
||||
// Decode Frame MAC commands
|
||||
switch (payload[mac_index++]) {
|
||||
case SRV_MAC_LINK_CHECK_ANS:
|
||||
mlme_conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
mlme_conf.demod_margin = payload[mac_index++];
|
||||
mlme_conf.nb_gateways = payload[mac_index++];
|
||||
break;
|
||||
case SRV_MAC_LINK_ADR_REQ: {
|
||||
adr_req_params_t linkAdrReq;
|
||||
int8_t linkAdrDatarate = DR_0;
|
||||
int8_t linkAdrTxPower = TX_POWER_0;
|
||||
uint8_t linkAdrNbRep = 0;
|
||||
uint8_t linkAdrNbBytesParsed = 0;
|
||||
|
||||
// Fill parameter structure
|
||||
linkAdrReq.payload = &payload[mac_index - 1];
|
||||
linkAdrReq.payload_size = commands_size - (mac_index - 1);
|
||||
linkAdrReq.adr_enabled = mac_sys_params.adr_on;
|
||||
linkAdrReq.ul_dwell_time = mac_sys_params.uplink_dwell_time;
|
||||
linkAdrReq.current_datarate = mac_sys_params.channel_data_rate;
|
||||
linkAdrReq.current_tx_power = mac_sys_params.channel_tx_power;
|
||||
linkAdrReq.current_nb_rep = mac_sys_params.retry_num;
|
||||
|
||||
// Process the ADR requests
|
||||
status = lora_phy.link_ADR_request(&linkAdrReq,
|
||||
&linkAdrDatarate,
|
||||
&linkAdrTxPower,
|
||||
&linkAdrNbRep,
|
||||
&linkAdrNbBytesParsed);
|
||||
|
||||
if ((status & 0x07) == 0x07) {
|
||||
mac_sys_params.channel_data_rate = linkAdrDatarate;
|
||||
mac_sys_params.channel_tx_power = linkAdrTxPower;
|
||||
mac_sys_params.retry_num = linkAdrNbRep;
|
||||
}
|
||||
|
||||
// Add the answers to the buffer
|
||||
for (uint8_t i = 0; i < (linkAdrNbBytesParsed / 5); i++) {
|
||||
ret_value = add_mac_command(MOTE_MAC_LINK_ADR_ANS, status, 0);
|
||||
}
|
||||
// Update MAC index
|
||||
mac_index += linkAdrNbBytesParsed - 1;
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DUTY_CYCLE_REQ:
|
||||
mac_sys_params.max_duty_cycle = payload[mac_index++];
|
||||
mac_sys_params.aggregated_duty_cycle = 1 << mac_sys_params.max_duty_cycle;
|
||||
ret_value = add_mac_command(MOTE_MAC_DUTY_CYCLE_ANS, 0, 0);
|
||||
break;
|
||||
case SRV_MAC_RX_PARAM_SETUP_REQ: {
|
||||
rx_param_setup_req_t rxParamSetupReq;
|
||||
|
||||
rxParamSetupReq.dr_offset = (payload[mac_index] >> 4) & 0x07;
|
||||
rxParamSetupReq.datarate = payload[mac_index] & 0x0F;
|
||||
mac_index++;
|
||||
|
||||
rxParamSetupReq.frequency = (uint32_t) payload[mac_index++];
|
||||
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++]
|
||||
<< 8;
|
||||
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++]
|
||||
<< 16;
|
||||
rxParamSetupReq.frequency *= 100;
|
||||
|
||||
// Perform request on region
|
||||
status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq);
|
||||
|
||||
if ((status & 0x07) == 0x07) {
|
||||
mac_sys_params.rx2_channel.datarate =
|
||||
rxParamSetupReq.datarate;
|
||||
mac_sys_params.rx2_channel.frequency =
|
||||
rxParamSetupReq.frequency;
|
||||
mac_sys_params.rx1_dr_offset = rxParamSetupReq.dr_offset;
|
||||
}
|
||||
ret_value = add_mac_command(MOTE_MAC_RX_PARAM_SETUP_ANS, status,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DEV_STATUS_REQ: {
|
||||
uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
|
||||
// we don't have a mechanism at the moment to measure
|
||||
// battery levels
|
||||
ret_value = add_mac_command(MOTE_MAC_DEV_STATUS_ANS,
|
||||
batteryLevel, snr);
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_NEW_CHANNEL_REQ: {
|
||||
new_channel_req_params_t newChannelReq;
|
||||
channel_params_t chParam;
|
||||
|
||||
newChannelReq.channel_id = payload[mac_index++];
|
||||
newChannelReq.new_channel = &chParam;
|
||||
|
||||
chParam.frequency = (uint32_t) payload[mac_index++];
|
||||
chParam.frequency |= (uint32_t) payload[mac_index++] << 8;
|
||||
chParam.frequency |= (uint32_t) payload[mac_index++] << 16;
|
||||
chParam.frequency *= 100;
|
||||
chParam.rx1_frequency = 0;
|
||||
chParam.dr_range.value = payload[mac_index++];
|
||||
|
||||
status = lora_phy.request_new_channel(&newChannelReq);
|
||||
|
||||
ret_value = add_mac_command(MOTE_MAC_NEW_CHANNEL_ANS, status, 0);
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_RX_TIMING_SETUP_REQ: {
|
||||
uint8_t delay = payload[mac_index++] & 0x0F;
|
||||
|
||||
if (delay == 0) {
|
||||
delay++;
|
||||
}
|
||||
mac_sys_params.recv_delay1 = delay * 1000;
|
||||
mac_sys_params.recv_delay2 = mac_sys_params.recv_delay1 + 1000;
|
||||
ret_value = add_mac_command(MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0);
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_TX_PARAM_SETUP_REQ: {
|
||||
tx_param_setup_req_t txParamSetupReq;
|
||||
uint8_t eirpDwellTime = payload[mac_index++];
|
||||
|
||||
txParamSetupReq.ul_dwell_time = 0;
|
||||
txParamSetupReq.dl_dwell_time = 0;
|
||||
|
||||
if ((eirpDwellTime & 0x20) == 0x20) {
|
||||
txParamSetupReq.dl_dwell_time = 1;
|
||||
}
|
||||
if ((eirpDwellTime & 0x10) == 0x10) {
|
||||
txParamSetupReq.ul_dwell_time = 1;
|
||||
}
|
||||
txParamSetupReq.max_eirp = eirpDwellTime & 0x0F;
|
||||
|
||||
// Check the status for correctness
|
||||
if (lora_phy.accept_tx_param_setup_req(&txParamSetupReq)) {
|
||||
// Accept command
|
||||
mac_sys_params.uplink_dwell_time =
|
||||
txParamSetupReq.ul_dwell_time;
|
||||
mac_sys_params.downlink_dwell_time =
|
||||
txParamSetupReq.dl_dwell_time;
|
||||
mac_sys_params.max_eirp =
|
||||
max_eirp_table[txParamSetupReq.max_eirp];
|
||||
// Add command response
|
||||
ret_value = add_mac_command(MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DL_CHANNEL_REQ: {
|
||||
dl_channel_req_params_t dlChannelReq;
|
||||
|
||||
dlChannelReq.channel_id = payload[mac_index++];
|
||||
dlChannelReq.rx1_frequency = (uint32_t) payload[mac_index++];
|
||||
dlChannelReq.rx1_frequency |= (uint32_t) payload[mac_index++] << 8;
|
||||
dlChannelReq.rx1_frequency |= (uint32_t) payload[mac_index++] << 16;
|
||||
dlChannelReq.rx1_frequency *= 100;
|
||||
|
||||
status = lora_phy.dl_channel_request(&dlChannelReq);
|
||||
|
||||
ret_value = add_mac_command(MOTE_MAC_DL_CHANNEL_ANS, status, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Unknown command. ABORT MAC commands processing
|
||||
ret_value = LORAWAN_STATUS_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
bool LoRaMacCommand::is_sticky_mac_command_pending()
|
||||
{
|
||||
if (mac_cmd_buf_idx_to_repeat > 0) {
|
||||
// Sticky MAC commands pending
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* \file LoRaMacCommand.h
|
||||
*
|
||||
* \brief LoRa MAC layer implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \defgroup LORAMAC LoRa MAC layer implementation
|
||||
* This module specifies the API implementation of the LoRaMAC layer.
|
||||
* This is a placeholder for a detailed description of the LoRaMac
|
||||
* layer and the supported features.
|
||||
*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMACCOMMAND_H__
|
||||
#define __LORAMACCOMMAND_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "lorawan/lorastack/phy/LoRaPHY.h"
|
||||
|
||||
/*!
|
||||
* Maximum MAC commands buffer size
|
||||
*/
|
||||
#define LORA_MAC_COMMAND_MAX_LENGTH 128
|
||||
|
||||
class LoRaMac;
|
||||
|
||||
class LoRaMacCommand {
|
||||
|
||||
public:
|
||||
LoRaMacCommand(LoRaMac &lora_mac);
|
||||
~LoRaMacCommand();
|
||||
|
||||
/**
|
||||
* @brief Adds a new MAC command to be sent.
|
||||
*
|
||||
* @remark MAC layer internal function
|
||||
*
|
||||
* @param [in] cmd MAC command to be added
|
||||
* [MOTE_MAC_LINK_CHECK_REQ,
|
||||
* MOTE_MAC_LINK_ADR_ANS,
|
||||
* MOTE_MAC_DUTY_CYCLE_ANS,
|
||||
* MOTE_MAC_RX2_PARAM_SET_ANS,
|
||||
* MOTE_MAC_DEV_STATUS_ANS
|
||||
* MOTE_MAC_NEW_CHANNEL_ANS]
|
||||
* @param [in] p1 1st parameter (optional depends on the command)
|
||||
* @param [in] p2 2nd parameter (optional depends on the command)
|
||||
*
|
||||
* @return status Function status [0: OK, 1: Unknown command, 2: Buffer full]
|
||||
*/
|
||||
lorawan_status_t add_mac_command(uint8_t cmd, uint8_t p1, uint8_t p2);
|
||||
|
||||
/**
|
||||
* @brief Clear MAC command buffer.
|
||||
*/
|
||||
void clear_command_buffer(void);
|
||||
|
||||
/**
|
||||
* @brief Get the length of MAC commands
|
||||
*
|
||||
* @return status Length of used MAC buffer (bytes)
|
||||
*/
|
||||
uint8_t get_mac_cmd_length() const;
|
||||
|
||||
/**
|
||||
* @brief Get MAC command buffer
|
||||
*
|
||||
* @return Pointer to MAC command buffer
|
||||
*/
|
||||
uint8_t *get_mac_commands_buffer();
|
||||
|
||||
/**
|
||||
* @brief Parses the MAC commands which must be resent.
|
||||
*/
|
||||
void parse_mac_commands_to_repeat();
|
||||
|
||||
/**
|
||||
* @brief Clear MAC command repeat buffer.
|
||||
*/
|
||||
void clear_repeat_buffer();
|
||||
|
||||
/**
|
||||
* @brief Copy MAC commands from repeat buffer to actual MAC command buffer.
|
||||
*/
|
||||
void copy_repeat_commands_to_buffer();
|
||||
|
||||
/**
|
||||
* @brief Get the length of MAC commands in repeat buffer
|
||||
*
|
||||
* @return status Length of used MAC Repeat buffer (bytes)
|
||||
*/
|
||||
uint8_t get_repeat_commands_length() const;
|
||||
|
||||
/**
|
||||
* @brief Clear MAC commands in next TX.
|
||||
*/
|
||||
void clear_mac_commands_in_next_tx();
|
||||
|
||||
/**
|
||||
* @brief Check if MAC command buffer has commands to be sent in next TX
|
||||
*
|
||||
* @return status True: buffer has MAC commands to be sent, false: no commands in buffer]
|
||||
*/
|
||||
bool is_mac_command_in_next_tx() const;
|
||||
|
||||
/**
|
||||
* @brief Decodes MAC commands in the fOpts field and in the payload
|
||||
*
|
||||
* @return status Function status. LORAWAN_STATUS_OK if command successful.
|
||||
*/
|
||||
lorawan_status_t process_mac_commands(uint8_t *payload, uint8_t mac_index,
|
||||
uint8_t commands_size, uint8_t snr,
|
||||
loramac_mlme_confirm_t& mlme_conf,
|
||||
lora_mac_system_params_t& mac_params,
|
||||
LoRaPHY& lora_phy);
|
||||
|
||||
/**
|
||||
* @brief Verifies if sticky MAC commands are pending.
|
||||
*
|
||||
* @return [true: sticky MAC commands pending, false: No MAC commands pending]
|
||||
*/
|
||||
bool is_sticky_mac_command_pending();
|
||||
|
||||
private:
|
||||
LoRaMac& _lora_mac;
|
||||
|
||||
/**
|
||||
* Indicates if the MAC layer wants to send MAC commands
|
||||
*/
|
||||
bool mac_cmd_in_next_tx;
|
||||
|
||||
/**
|
||||
* Contains the current Mac command buffer index in 'mac_cmd_buffer'
|
||||
*/
|
||||
uint8_t mac_cmd_buf_idx;
|
||||
|
||||
/**
|
||||
* Contains the current Mac command buffer index for MAC commands to repeat in
|
||||
* 'mac_cmd_buffer_to_repeat'
|
||||
*/
|
||||
uint8_t mac_cmd_buf_idx_to_repeat;
|
||||
|
||||
/**
|
||||
* Buffer containing the MAC layer commands
|
||||
*/
|
||||
uint8_t mac_cmd_buffer[LORA_MAC_COMMAND_MAX_LENGTH];
|
||||
|
||||
/**
|
||||
* Buffer containing the MAC layer commands which must be repeated
|
||||
*/
|
||||
uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH];
|
||||
};
|
||||
|
||||
#endif //__LORAMACCOMMAND_H__
|
|
@ -41,251 +41,253 @@
|
|||
/**
|
||||
* MIC field computation initial data
|
||||
*/
|
||||
static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t mic_block_b0[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* Contains the computed MIC field.
|
||||
*
|
||||
* \remark Only the 4 first bytes are used
|
||||
*/
|
||||
static uint8_t Mic[16];
|
||||
static uint8_t computed_mic[16];
|
||||
|
||||
/**
|
||||
* Encryption aBlock and sBlock
|
||||
*/
|
||||
static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t a_block[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static uint8_t s_block[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* AES computation context variable
|
||||
*/
|
||||
static mbedtls_aes_context AesContext;
|
||||
static mbedtls_aes_context aes_ctx;
|
||||
|
||||
/**
|
||||
* CMAC computation context variable
|
||||
*/
|
||||
static mbedtls_cipher_context_t AesCmacCtx[1];
|
||||
static mbedtls_cipher_context_t aes_cmac_ctx[1];
|
||||
|
||||
#define AES_CMAC_KEY_LENGTH 16
|
||||
|
||||
/**
|
||||
* \brief Computes the LoRaMAC frame MIC field
|
||||
*
|
||||
* \param [in] buffer Data buffer
|
||||
* \param [in] size Data buffer size
|
||||
* \param [in] key AES key to be used
|
||||
* \param [in] address Frame address
|
||||
* \param [in] dir Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter Frame sequence counter
|
||||
* \param [out] mic Computed MIC field
|
||||
*/
|
||||
int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic )
|
||||
int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
|
||||
MicBlockB0[5] = dir;
|
||||
mic_block_b0[5] = dir;
|
||||
|
||||
MicBlockB0[6] = ( address ) & 0xFF;
|
||||
MicBlockB0[7] = ( address >> 8 ) & 0xFF;
|
||||
MicBlockB0[8] = ( address >> 16 ) & 0xFF;
|
||||
MicBlockB0[9] = ( address >> 24 ) & 0xFF;
|
||||
mic_block_b0[6] = (address) & 0xFF;
|
||||
mic_block_b0[7] = (address >> 8) & 0xFF;
|
||||
mic_block_b0[8] = (address >> 16) & 0xFF;
|
||||
mic_block_b0[9] = (address >> 24) & 0xFF;
|
||||
|
||||
MicBlockB0[10] = ( sequenceCounter ) & 0xFF;
|
||||
MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF;
|
||||
MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF;
|
||||
MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF;
|
||||
mic_block_b0[10] = (seq_counter) & 0xFF;
|
||||
mic_block_b0[11] = (seq_counter >> 8) & 0xFF;
|
||||
mic_block_b0[12] = (seq_counter >> 16) & 0xFF;
|
||||
mic_block_b0[13] = (seq_counter >> 24) & 0xFF;
|
||||
|
||||
MicBlockB0[15] = size & 0xFF;
|
||||
mic_block_b0[15] = size & 0xFF;
|
||||
|
||||
mbedtls_cipher_init(aes_cmac_ctx);
|
||||
|
||||
mbedtls_cipher_init(AesCmacCtx);
|
||||
const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
|
||||
if (NULL != cipher_info) {
|
||||
ret = mbedtls_cipher_setup(AesCmacCtx, cipher_info);
|
||||
ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(AesCmacCtx, key, AES_CMAC_KEY_LENGTH*8);
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key,
|
||||
AES_CMAC_KEY_LENGTH * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0,
|
||||
LORAMAC_MIC_BLOCK_B0_SIZE);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(AesCmacCtx, buffer, size & 0xFF);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_finish(AesCmacCtx, Mic);
|
||||
ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
*mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
|
||||
*mic = (uint32_t) ((uint32_t) computed_mic[3] << 24
|
||||
| (uint32_t) computed_mic[2] << 16
|
||||
| (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]);
|
||||
} else {
|
||||
ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_cipher_free( AesCmacCtx );
|
||||
exit: mbedtls_cipher_free(aes_cmac_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer )
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t bufferIndex = 0;
|
||||
uint16_t ctr = 1;
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&AesContext);
|
||||
ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
aBlock[5] = dir;
|
||||
a_block[5] = dir;
|
||||
|
||||
aBlock[6] = ( address ) & 0xFF;
|
||||
aBlock[7] = ( address >> 8 ) & 0xFF;
|
||||
aBlock[8] = ( address >> 16 ) & 0xFF;
|
||||
aBlock[9] = ( address >> 24 ) & 0xFF;
|
||||
a_block[6] = (address) & 0xFF;
|
||||
a_block[7] = (address >> 8) & 0xFF;
|
||||
a_block[8] = (address >> 16) & 0xFF;
|
||||
a_block[9] = (address >> 24) & 0xFF;
|
||||
|
||||
aBlock[10] = ( sequenceCounter ) & 0xFF;
|
||||
aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;
|
||||
aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;
|
||||
aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;
|
||||
a_block[10] = (seq_counter) & 0xFF;
|
||||
a_block[11] = (seq_counter >> 8) & 0xFF;
|
||||
a_block[12] = (seq_counter >> 16) & 0xFF;
|
||||
a_block[13] = (seq_counter >> 24) & 0xFF;
|
||||
|
||||
while( size >= 16 )
|
||||
{
|
||||
aBlock[15] = ( ( ctr ) & 0xFF );
|
||||
while (size >= 16) {
|
||||
a_block[15] = ((ctr) & 0xFF);
|
||||
ctr++;
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, aBlock, sBlock);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block,
|
||||
s_block);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
|
||||
for (i = 0; i < 16; i++) {
|
||||
enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i];
|
||||
}
|
||||
size -= 16;
|
||||
bufferIndex += 16;
|
||||
}
|
||||
|
||||
if( size > 0 )
|
||||
{
|
||||
aBlock[15] = ( ( ctr ) & 0xFF );
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, aBlock, sBlock);
|
||||
if (size > 0) {
|
||||
a_block[15] = ((ctr) & 0xFF);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block,
|
||||
s_block);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
{
|
||||
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
|
||||
for (i = 0; i < size; i++) {
|
||||
enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i];
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&AesContext);
|
||||
exit: mbedtls_aes_free(&aes_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer )
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer)
|
||||
{
|
||||
return LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer );
|
||||
return encrypt_payload(buffer, size, key, address, dir, seq_counter,
|
||||
dec_buffer);
|
||||
}
|
||||
|
||||
int LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic )
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t *mic)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_cipher_init(AesCmacCtx);
|
||||
mbedtls_cipher_init(aes_cmac_ctx);
|
||||
const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
|
||||
if (NULL != cipher_info) {
|
||||
ret = mbedtls_cipher_setup(AesCmacCtx, cipher_info);
|
||||
ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(AesCmacCtx, key, AES_CMAC_KEY_LENGTH*8);
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key,
|
||||
AES_CMAC_KEY_LENGTH * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(AesCmacCtx, buffer, size & 0xFF);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_finish(AesCmacCtx, Mic);
|
||||
ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
*mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
|
||||
*mic = (uint32_t) ((uint32_t) computed_mic[3] << 24
|
||||
| (uint32_t) computed_mic[2] << 16
|
||||
| (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]);
|
||||
} else {
|
||||
ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_cipher_free(AesCmacCtx);
|
||||
exit: mbedtls_cipher_free(aes_cmac_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer )
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint8_t *dec_buffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&AesContext);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, buffer, decBuffer);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer,
|
||||
dec_buffer);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
// Check if optional CFList is included
|
||||
if( size >= 16 )
|
||||
{
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, buffer + 16, decBuffer + 16);
|
||||
if (size >= 16) {
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer + 16,
|
||||
dec_buffer + 16);
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&AesContext);
|
||||
exit: mbedtls_aes_free(&aes_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey )
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
||||
uint16_t dev_nonce, uint8_t *nwk_skey,
|
||||
uint8_t *app_skey)
|
||||
{
|
||||
uint8_t nonce[16];
|
||||
uint8_t *pDevNonce = ( uint8_t * )&devNonce;
|
||||
uint8_t *p_dev_nonce = (uint8_t *) &dev_nonce;
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&AesContext);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
memset( nonce, 0, sizeof( nonce ) );
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
nonce[0] = 0x01;
|
||||
memcpy( nonce + 1, appNonce, 6 );
|
||||
memcpy( nonce + 7, pDevNonce, 2 );
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, nonce, nwkSKey);
|
||||
memcpy(nonce + 1, app_nonce, 6);
|
||||
memcpy(nonce + 7, p_dev_nonce, 2);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, nwk_skey);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
memset( nonce, 0, sizeof( nonce ) );
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
nonce[0] = 0x02;
|
||||
memcpy( nonce + 1, appNonce, 6 );
|
||||
memcpy( nonce + 7, pDevNonce, 2 );
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, nonce, appSKey);
|
||||
memcpy(nonce + 1, app_nonce, 6);
|
||||
memcpy(nonce + 7, p_dev_nonce, 2);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, app_skey);
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&AesContext);
|
||||
exit: mbedtls_aes_free(&aes_ctx);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
@ -294,54 +296,56 @@ exit:
|
|||
// user knows what is wrong and in addition to that these ensure that
|
||||
// Mbed-OS compiles properly under normal conditions where LoRaWAN in conjunction
|
||||
// with mbedTLS is not being used.
|
||||
int LoRaMacComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t dir, uint32_t, uint32_t * )
|
||||
int compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t dir, uint32_t, uint32_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORA_MAC_STATUS_CRYPTO_FAIL;
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t * )
|
||||
int encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORA_MAC_STATUS_CRYPTO_FAIL;
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t * )
|
||||
int decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORA_MAC_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
int LoRaMacJoinComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t * )
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORA_MAC_STATUS_CRYPTO_FAIL;
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * )
|
||||
int compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORA_MAC_STATUS_CRYPTO_FAIL;
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacJoinComputeSKeys( const uint8_t *, const uint8_t *, uint16_t , uint8_t *, uint8_t * )
|
||||
int decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORA_MAC_STATUS_CRYPTO_FAIL;
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int compute_skeys_for_join_frame(const uint8_t *, const uint8_t *, uint16_t ,
|
||||
uint8_t *, uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,84 +29,94 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
/**
|
||||
* Computes the LoRaMAC frame MIC field
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] address - Frame address
|
||||
* \param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter - Frame sequence counter
|
||||
* \param [out] mic - Computed MIC field
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] mic - Computed MIC field
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic );
|
||||
int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC payload encryption
|
||||
* Performs payload encryption
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] address - Frame address
|
||||
* \param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter - Frame sequence counter
|
||||
* \param [out] encBuffer - Encrypted buffer
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] enc_buffer - Encrypted buffer
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer );
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC payload decryption
|
||||
* Performs payload decryption
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] address - Frame address
|
||||
* \param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter - Frame sequence counter
|
||||
* \param [out] decBuffer - Decrypted buffer
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer );
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC Join Request frame MIC field
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [out] mic - Computed MIC field
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [out] mic - Computed MIC field
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*
|
||||
*/
|
||||
int LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic );
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t *mic);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [out] decBuffer - Decrypted buffer
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer );
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint8_t *dec_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] appNonce - Application nonce
|
||||
* \param [in] devNonce - Device nonce
|
||||
* \param [out] nwkSKey - Network session key
|
||||
* \param [out] appSKey - Application session key
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] app_nonce - Application nonce
|
||||
* @param [in] dev_nonce - Device nonce
|
||||
* @param [out] nwk_skey - Network session key
|
||||
* @param [out] app_skey - Application session key
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey );
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
||||
uint16_t dev_nonce, uint8_t *nwk_skey,
|
||||
uint8_t *app_skey );
|
||||
|
||||
#endif // MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "LoRaMac.h"
|
||||
#include "lorastack/mac/LoRaMacMcps.h"
|
||||
|
||||
LoRaMacMcps::LoRaMacMcps()
|
||||
: _lora_mac(NULL), _lora_phy(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoRaMacMcps::~LoRaMacMcps()
|
||||
{
|
||||
}
|
||||
|
||||
void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy)
|
||||
{
|
||||
_lora_mac = mac;
|
||||
_lora_phy = phy;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
|
||||
loramac_protocol_params *params)
|
||||
{
|
||||
|
||||
if (mcpsRequest == NULL || _lora_phy == NULL || _lora_mac == NULL) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phyParam;
|
||||
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
loramac_mhdr_t machdr;
|
||||
verification_params_t verify;
|
||||
uint8_t fport = 0;
|
||||
void *fbuffer;
|
||||
uint16_t fbuffer_size;
|
||||
int8_t datarate = DR_0;
|
||||
bool ready_to_send = false;
|
||||
|
||||
machdr.value = 0;
|
||||
|
||||
// Before performing any MCPS request, clear the confirmation structure
|
||||
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
|
||||
|
||||
confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
|
||||
// ack_timeout_retry_counter must be reset every time a new request (unconfirmed or confirmed) is performed.
|
||||
params->ack_timeout_retry_counter = 1;
|
||||
|
||||
switch (mcpsRequest->type) {
|
||||
case MCPS_UNCONFIRMED: {
|
||||
ready_to_send = true;
|
||||
params->max_ack_timeout_retries = 1;
|
||||
|
||||
machdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP;
|
||||
fport = mcpsRequest->req.unconfirmed.fport;
|
||||
fbuffer = mcpsRequest->f_buffer;
|
||||
fbuffer_size = mcpsRequest->f_buffer_size;
|
||||
datarate = mcpsRequest->req.unconfirmed.data_rate;
|
||||
break;
|
||||
}
|
||||
case MCPS_CONFIRMED: {
|
||||
ready_to_send = true;
|
||||
params->max_ack_timeout_retries = mcpsRequest->req.confirmed.nb_trials;
|
||||
|
||||
machdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP;
|
||||
fport = mcpsRequest->req.confirmed.fport;
|
||||
fbuffer = mcpsRequest->f_buffer;
|
||||
fbuffer_size = mcpsRequest->f_buffer_size;
|
||||
datarate = mcpsRequest->req.confirmed.data_rate;
|
||||
break;
|
||||
}
|
||||
case MCPS_PROPRIETARY: {
|
||||
ready_to_send = true;
|
||||
params->max_ack_timeout_retries = 1;
|
||||
|
||||
machdr.bits.mtype = FRAME_TYPE_PROPRIETARY;
|
||||
fbuffer = mcpsRequest->f_buffer;
|
||||
fbuffer_size = mcpsRequest->f_buffer_size;
|
||||
datarate = mcpsRequest->req.proprietary.data_rate;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter fPorts
|
||||
// TODO: Does not work with PROPRIETARY messages
|
||||
// if( IsFPortAllowed( fPort ) == false )
|
||||
// {
|
||||
// return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
// }
|
||||
|
||||
// Get the minimum possible datarate
|
||||
get_phy.attribute = PHY_MIN_TX_DR;
|
||||
phyParam = _lora_phy->get_phy_params(&get_phy);
|
||||
|
||||
// Apply the minimum possible datarate.
|
||||
// Some regions have limitations for the minimum datarate.
|
||||
datarate = MAX(datarate, (int8_t)phyParam.value);
|
||||
|
||||
if (ready_to_send == true) {
|
||||
if (params->sys_params.adr_on == false) {
|
||||
verify.datarate = datarate;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_TX_DR) == true) {
|
||||
params->sys_params.channel_data_rate = verify.datarate;
|
||||
} else {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
status = _lora_mac->send(&machdr, fport, fbuffer, fbuffer_size);
|
||||
if (status == LORAWAN_STATUS_OK) {
|
||||
confirmation.req_type = mcpsRequest->type;
|
||||
params->flags.bits.mcps_req = 1;
|
||||
} else {
|
||||
params->is_node_ack_requested = false;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MBED_OS_LORAWAN_MAC_MCPS_H_
|
||||
#define MBED_OS_LORAWAN_MAC_MCPS_H_
|
||||
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "lorastack/phy/LoRaPHY.h"
|
||||
|
||||
// forward declaration
|
||||
class LoRaMac;
|
||||
|
||||
class LoRaMacMcps {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* Sets local handles to NULL. These handles will be set when the subsystem
|
||||
* is activated by the MAC layer.
|
||||
*/
|
||||
LoRaMacMcps();
|
||||
|
||||
/** Destructor
|
||||
*
|
||||
* Does nothing
|
||||
*/
|
||||
~LoRaMacMcps();
|
||||
|
||||
/** Activating MCPS subsystem
|
||||
*
|
||||
* Stores pointers to MAC and PHY layer handles
|
||||
*
|
||||
* @param mac pointer to MAC layer
|
||||
* @param phy pointer to PHY layer
|
||||
*/
|
||||
void activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy);
|
||||
|
||||
/** Sets up an MCPS Request
|
||||
*
|
||||
* Sets up an MCPS request and sends it through to the central MAC control.
|
||||
* It also modifies or uses protocol information provided in the MAC
|
||||
* protocol data structure.
|
||||
*
|
||||
* @param mcpsRequest pointer to MCPS request structure
|
||||
* @param params pointer to MAC protocol parameters
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t set_request(loramac_mcps_req_t *mcpsRequest, loramac_protocol_params *params);
|
||||
|
||||
/** Grants access to MCPS confirmation data
|
||||
*
|
||||
* @return a reference to MCPS confirm data structure
|
||||
*/
|
||||
inline loramac_mcps_confirm_t& get_confirmation()
|
||||
{
|
||||
return confirmation;
|
||||
}
|
||||
|
||||
/** Grants access to MCPS indication data
|
||||
*
|
||||
* @return a reference to MCPS indication data structure
|
||||
*/
|
||||
inline loramac_mcps_indication_t& get_indication()
|
||||
{
|
||||
return indication;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Pointers to MAC and PHY handles
|
||||
*/
|
||||
LoRaMac *_lora_mac;
|
||||
LoRaPHY *_lora_phy;
|
||||
|
||||
/**
|
||||
* Structure to hold MCPS indication data.
|
||||
*/
|
||||
loramac_mcps_indication_t indication;
|
||||
|
||||
/**
|
||||
* Structure to hold MCPS confirm data.
|
||||
*/
|
||||
loramac_mcps_confirm_t confirmation;
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAWAN_MAC_MCPS_H_ */
|
|
@ -0,0 +1,462 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "lorastack/mac/LoRaMac.h"
|
||||
#include "lorastack/mac/LoRaMacMib.h"
|
||||
|
||||
LoRaMacMib::LoRaMacMib()
|
||||
: _lora_mac(NULL), _lora_phy(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoRaMacMib::~LoRaMacMib()
|
||||
{
|
||||
}
|
||||
|
||||
void LoRaMacMib::activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy)
|
||||
{
|
||||
_lora_mac = mac;
|
||||
_lora_phy = phy;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
|
||||
loramac_protocol_params *params)
|
||||
{
|
||||
if (mibSet == NULL || _lora_phy == NULL || _lora_mac == NULL) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
lorawan_status_t status = LORAWAN_STATUS_OK;
|
||||
verification_params_t verify;
|
||||
|
||||
|
||||
switch (mibSet->type) {
|
||||
case MIB_DEVICE_CLASS: {
|
||||
params->dev_class = mibSet->param.dev_class;
|
||||
switch (params->dev_class) {
|
||||
case CLASS_A: {
|
||||
// Set the radio into sleep to setup a defined state
|
||||
_lora_phy->put_radio_to_sleep();
|
||||
break;
|
||||
}
|
||||
case CLASS_B: {
|
||||
break;
|
||||
}
|
||||
case CLASS_C: {
|
||||
// Set the is_node_ack_requested indicator to default
|
||||
params->is_node_ack_requested = false;
|
||||
// Set the radio into sleep mode in case we are still in RX mode
|
||||
_lora_phy->put_radio_to_sleep();
|
||||
// Compute Rx2 windows parameters in case the RX2 datarate has changed
|
||||
_lora_phy->compute_rx_win_params(
|
||||
params->sys_params.rx2_channel.datarate,
|
||||
params->sys_params.min_rx_symb,
|
||||
params->sys_params.max_sys_rx_error,
|
||||
¶ms->rx_window2_config);
|
||||
_lora_mac->open_continuous_rx2_window();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_NETWORK_JOINED: {
|
||||
params->is_nwk_joined = mibSet->param.is_nwk_joined;
|
||||
break;
|
||||
}
|
||||
case MIB_ADR: {
|
||||
params->sys_params.adr_on = mibSet->param.is_adr_enable;
|
||||
break;
|
||||
}
|
||||
case MIB_NET_ID: {
|
||||
params->net_id = mibSet->param.net_id;
|
||||
break;
|
||||
}
|
||||
case MIB_DEV_ADDR: {
|
||||
params->dev_addr = mibSet->param.dev_addr;
|
||||
break;
|
||||
}
|
||||
case MIB_NWK_SKEY: {
|
||||
if (mibSet->param.nwk_skey != NULL) {
|
||||
memcpy(params->keys.nwk_skey, mibSet->param.nwk_skey,
|
||||
sizeof(params->keys.nwk_skey));
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_APP_SKEY: {
|
||||
if (mibSet->param.app_skey != NULL) {
|
||||
memcpy(params->keys.app_skey, mibSet->param.app_skey,
|
||||
sizeof(params->keys.app_skey));
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_PUBLIC_NETWORK: {
|
||||
params->is_nwk_public = mibSet->param.enable_public_nwk;
|
||||
_lora_phy->setup_public_network_mode(params->is_nwk_public);
|
||||
break;
|
||||
}
|
||||
case MIB_REPEATER_SUPPORT: {
|
||||
params->is_repeater_supported = mibSet->param.enable_repeater_support;
|
||||
break;
|
||||
}
|
||||
case MIB_RX2_CHANNEL: {
|
||||
verify.datarate = mibSet->param.rx2_channel.datarate;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_RX_DR) == true) {
|
||||
params->sys_params.rx2_channel = mibSet->param.rx2_channel;
|
||||
|
||||
if ((params->dev_class == CLASS_C)
|
||||
&& (params->is_nwk_joined == true)) {
|
||||
// We can only compute the RX window parameters directly, if we are already
|
||||
// in class c mode and joined. We cannot setup an RX window in case of any other
|
||||
// class type.
|
||||
// Set the radio into sleep mode in case we are still in RX mode
|
||||
_lora_phy->put_radio_to_sleep();
|
||||
// Compute Rx2 windows parameters
|
||||
_lora_phy->compute_rx_win_params(
|
||||
params->sys_params.rx2_channel.datarate,
|
||||
params->sys_params.min_rx_symb,
|
||||
params->sys_params.max_sys_rx_error,
|
||||
¶ms->rx_window2_config);
|
||||
|
||||
_lora_mac->open_continuous_rx2_window();
|
||||
}
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_RX2_DEFAULT_CHANNEL: {
|
||||
verify.datarate = mibSet->param.rx2_channel.datarate;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_RX_DR) == true) {
|
||||
params->sys_params.rx2_channel = mibSet->param.default_rx2_channel;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DEFAULT_MASK:
|
||||
case MIB_CHANNELS_MASK: {
|
||||
// channel masks must not be tempered with.
|
||||
// They should be manipulated only on request with certain
|
||||
// APIs like add_channel() and remove_channel()
|
||||
// You should be able to get these MIB parameters, not set
|
||||
status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_NB_REP: {
|
||||
if ((mibSet->param.channel_nb_rep >= 1)
|
||||
&& (mibSet->param.channel_nb_rep <= 15)) {
|
||||
params->sys_params.retry_num = mibSet->param.channel_nb_rep;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_MAX_RX_WINDOW_DURATION: {
|
||||
params->sys_params.max_rx_win_time = mibSet->param.max_rx_window;
|
||||
break;
|
||||
}
|
||||
case MIB_RECEIVE_DELAY_1: {
|
||||
params->sys_params.recv_delay1 = mibSet->param.recv_delay1;
|
||||
break;
|
||||
}
|
||||
case MIB_RECEIVE_DELAY_2: {
|
||||
params->sys_params.recv_delay2 = mibSet->param.recv_delay2;
|
||||
break;
|
||||
}
|
||||
case MIB_JOIN_ACCEPT_DELAY_1: {
|
||||
params->sys_params.join_accept_delay1 = mibSet->param.join_accept_delay1;
|
||||
break;
|
||||
}
|
||||
case MIB_JOIN_ACCEPT_DELAY_2: {
|
||||
params->sys_params.join_accept_delay2 = mibSet->param.join_accept_delay2;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DEFAULT_DATARATE: {
|
||||
verify.datarate = mibSet->param.default_channel_data_rate;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) {
|
||||
params->sys_params.channel_data_rate = verify.datarate;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DATARATE: {
|
||||
verify.datarate = mibSet->param.channel_data_rate;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_TX_DR) == true) {
|
||||
params->sys_params.channel_data_rate = verify.datarate;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DEFAULT_TX_POWER: {
|
||||
verify.tx_power = mibSet->param.default_channel_tx_pwr;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) {
|
||||
params->sys_params.channel_tx_power = verify.tx_power;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_TX_POWER: {
|
||||
verify.tx_power = mibSet->param.channel_tx_pwr;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_TX_POWER) == true) {
|
||||
params->sys_params.channel_tx_power = verify.tx_power;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MIB_UPLINK_COUNTER: {
|
||||
params->ul_frame_counter = mibSet->param.ul_frame_counter;
|
||||
break;
|
||||
}
|
||||
case MIB_DOWNLINK_COUNTER: {
|
||||
params->dl_frame_counter = mibSet->param.dl_frame_counter;
|
||||
break;
|
||||
}
|
||||
case MIB_SYSTEM_MAX_RX_ERROR: {
|
||||
params->sys_params.max_sys_rx_error = mibSet->param.max_rx_sys_error;
|
||||
break;
|
||||
}
|
||||
case MIB_MIN_RX_SYMBOLS: {
|
||||
params->sys_params.min_rx_symb = mibSet->param.min_rx_symb;
|
||||
break;
|
||||
}
|
||||
case MIB_ANTENNA_GAIN: {
|
||||
params->sys_params.antenna_gain = mibSet->param.antenna_gain;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
||||
loramac_protocol_params *params)
|
||||
{
|
||||
lorawan_status_t status = LORAWAN_STATUS_OK;
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phy_param;
|
||||
rx2_channel_params rx2_channel;
|
||||
|
||||
if( mibGet == NULL )
|
||||
{
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
switch( mibGet->type )
|
||||
{
|
||||
case MIB_DEVICE_CLASS:
|
||||
{
|
||||
mibGet->param.dev_class = params->dev_class;
|
||||
break;
|
||||
}
|
||||
case MIB_NETWORK_JOINED:
|
||||
{
|
||||
mibGet->param.is_nwk_joined = params->is_nwk_joined;
|
||||
break;
|
||||
}
|
||||
case MIB_ADR:
|
||||
{
|
||||
mibGet->param.is_adr_enable = params->sys_params.adr_on;
|
||||
break;
|
||||
}
|
||||
case MIB_NET_ID:
|
||||
{
|
||||
mibGet->param.net_id = params->net_id;
|
||||
break;
|
||||
}
|
||||
case MIB_DEV_ADDR:
|
||||
{
|
||||
mibGet->param.dev_addr = params->dev_addr;
|
||||
break;
|
||||
}
|
||||
case MIB_NWK_SKEY:
|
||||
{
|
||||
mibGet->param.nwk_skey =params->keys.nwk_skey;
|
||||
break;
|
||||
}
|
||||
case MIB_APP_SKEY:
|
||||
{
|
||||
mibGet->param.app_skey = params->keys.app_skey;
|
||||
break;
|
||||
}
|
||||
case MIB_PUBLIC_NETWORK:
|
||||
{
|
||||
mibGet->param.enable_public_nwk = params->is_nwk_public;
|
||||
break;
|
||||
}
|
||||
case MIB_REPEATER_SUPPORT:
|
||||
{
|
||||
mibGet->param.enable_repeater_support = params->is_repeater_supported;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS:
|
||||
{
|
||||
get_phy.attribute = PHY_CHANNELS;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
|
||||
mibGet->param.channel_list = phy_param.channel_params;
|
||||
break;
|
||||
}
|
||||
case MIB_RX2_CHANNEL:
|
||||
{
|
||||
mibGet->param.rx2_channel = params->sys_params.rx2_channel;
|
||||
break;
|
||||
}
|
||||
case MIB_RX2_DEFAULT_CHANNEL:
|
||||
{
|
||||
get_phy.attribute = PHY_DEF_RX2_DR;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
rx2_channel.datarate = phy_param.value;
|
||||
|
||||
get_phy.attribute = PHY_DEF_RX2_FREQUENCY;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
rx2_channel.frequency = phy_param.value;
|
||||
|
||||
mibGet->param.rx2_channel = rx2_channel;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DEFAULT_MASK:
|
||||
{
|
||||
get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
|
||||
mibGet->param.default_channel_mask = phy_param.channel_mask;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_MASK:
|
||||
{
|
||||
get_phy.attribute = PHY_CHANNEL_MASK;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
|
||||
mibGet->param.channel_mask = phy_param.channel_mask;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_NB_REP:
|
||||
{
|
||||
mibGet->param.channel_nb_rep = params->sys_params.retry_num;
|
||||
break;
|
||||
}
|
||||
case MIB_MAX_RX_WINDOW_DURATION:
|
||||
{
|
||||
mibGet->param.max_rx_window = params->sys_params.max_rx_win_time;
|
||||
break;
|
||||
}
|
||||
case MIB_RECEIVE_DELAY_1:
|
||||
{
|
||||
mibGet->param.recv_delay1 = params->sys_params.recv_delay1;
|
||||
break;
|
||||
}
|
||||
case MIB_RECEIVE_DELAY_2:
|
||||
{
|
||||
mibGet->param.recv_delay2 = params->sys_params.recv_delay2;
|
||||
break;
|
||||
}
|
||||
case MIB_JOIN_ACCEPT_DELAY_1:
|
||||
{
|
||||
mibGet->param.join_accept_delay1 = params->sys_params.join_accept_delay1;
|
||||
break;
|
||||
}
|
||||
case MIB_JOIN_ACCEPT_DELAY_2:
|
||||
{
|
||||
mibGet->param.join_accept_delay2 = params->sys_params.join_accept_delay2;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DEFAULT_DATARATE:
|
||||
{
|
||||
get_phy.attribute = PHY_DEF_TX_DR;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
mibGet->param.default_channel_data_rate = phy_param.value;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DATARATE:
|
||||
{
|
||||
mibGet->param.channel_data_rate = params->sys_params.channel_data_rate;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DEFAULT_TX_POWER:
|
||||
{
|
||||
get_phy.attribute = PHY_DEF_TX_POWER;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
mibGet->param.default_channel_tx_pwr = phy_param.value;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_TX_POWER:
|
||||
{
|
||||
mibGet->param.channel_tx_pwr = params->sys_params.channel_tx_power;
|
||||
break;
|
||||
}
|
||||
case MIB_UPLINK_COUNTER:
|
||||
{
|
||||
mibGet->param.ul_frame_counter = params->ul_frame_counter;
|
||||
break;
|
||||
}
|
||||
case MIB_DOWNLINK_COUNTER:
|
||||
{
|
||||
mibGet->param.dl_frame_counter = params->dl_frame_counter;
|
||||
break;
|
||||
}
|
||||
case MIB_MULTICAST_CHANNEL:
|
||||
{
|
||||
mibGet->param.multicast_list = params->multicast_channels;
|
||||
break;
|
||||
}
|
||||
case MIB_SYSTEM_MAX_RX_ERROR:
|
||||
{
|
||||
mibGet->param.max_rx_sys_error = params->sys_params.max_sys_rx_error;
|
||||
break;
|
||||
}
|
||||
case MIB_MIN_RX_SYMBOLS:
|
||||
{
|
||||
mibGet->param.min_rx_symb = params->sys_params.min_rx_symb;
|
||||
break;
|
||||
}
|
||||
case MIB_ANTENNA_GAIN:
|
||||
{
|
||||
mibGet->param.antenna_gain = params->sys_params.antenna_gain;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MBED_OS_LORAWAN_MAC_MIB_H_
|
||||
#define MBED_OS_LORAWAN_MAC_MIB_H_
|
||||
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "lorastack/phy/LoRaPHY.h"
|
||||
|
||||
// forward declaration
|
||||
class LoRaMac;
|
||||
|
||||
class LoRaMacMib {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* Sets local handles to NULL. These handles will be set when the subsystem
|
||||
* is activated by the MAC layer.
|
||||
*/
|
||||
LoRaMacMib();
|
||||
|
||||
/** Destructor
|
||||
*
|
||||
* Does nothing
|
||||
*/
|
||||
~LoRaMacMib();
|
||||
|
||||
/** Activating MLME subsystem
|
||||
*
|
||||
* Stores pointers to MAC and PHY layer handles
|
||||
*
|
||||
* @param mac pointer to MAC layer
|
||||
* @param phy pointer to PHY layer
|
||||
*/
|
||||
void activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy);
|
||||
|
||||
/** Sets up a MIB Request
|
||||
*
|
||||
* Used to configure MAC protocol parameters using appropriate
|
||||
* key/value pair in the MIB request structure. Use this API to set
|
||||
* any system wide configurable parameter exposed by MIB service.
|
||||
*
|
||||
* @param mibSet [in] pointer to MIB request structure
|
||||
* @param params pointer to MAC protocol parameters which will be modified
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t set_request(loramac_mib_req_confirm_t *mibSet,
|
||||
loramac_protocol_params *params);
|
||||
|
||||
/** Provides access to the given MIB parameter
|
||||
*
|
||||
* Used to extract information about system wide MAC protocol parameters
|
||||
* which are exposed by MIB service.
|
||||
*
|
||||
* @param mibGet [out] pointer to MIB request structure which will be filled in
|
||||
* @param params pointer to MAC protocol parameters
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t get_request(loramac_mib_req_confirm_t *mibGet,
|
||||
loramac_protocol_params *params);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Pointers to MAC and PHY handles
|
||||
*/
|
||||
LoRaMac *_lora_mac;
|
||||
LoRaPHY *_lora_phy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* MBED_OS_LORAWAN_MAC_MIB_H_ */
|
|
@ -0,0 +1,151 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "LoRaMac.h"
|
||||
#include "lorastack/mac/LoRaMacMlme.h"
|
||||
|
||||
LoRaMacMlme::LoRaMacMlme()
|
||||
: _lora_mac(NULL), _lora_phy(NULL), _mac_cmd(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoRaMacMlme::~LoRaMacMlme()
|
||||
{
|
||||
}
|
||||
|
||||
void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy,
|
||||
LoRaMacCommand *cmd)
|
||||
{
|
||||
_lora_mac = mac;
|
||||
_lora_phy = phy;
|
||||
_mac_cmd = cmd;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *request,
|
||||
loramac_protocol_params *params)
|
||||
{
|
||||
if (request && params && _lora_mac && _lora_phy && _mac_cmd) {
|
||||
|
||||
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
loramac_mhdr_t machdr;
|
||||
|
||||
verification_params_t verify;
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phy_param;
|
||||
|
||||
|
||||
if (params->mac_state != LORAMAC_IDLE) {
|
||||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
// Before setting a new MLME request, clear the MLME confirmation
|
||||
// structure
|
||||
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
|
||||
|
||||
confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
|
||||
switch (request->type) {
|
||||
case MLME_JOIN: {
|
||||
if ((params->mac_state & LORAMAC_TX_DELAYED)
|
||||
== LORAMAC_TX_DELAYED) {
|
||||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
if ((request->req.join.dev_eui == NULL)
|
||||
|| (request->req.join.app_eui == NULL)
|
||||
|| (request->req.join.app_key == NULL)
|
||||
|| (request->req.join.nb_trials == 0)) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
// Verify the parameter NbTrials for the join procedure
|
||||
verify.nb_join_trials = request->req.join.nb_trials;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) {
|
||||
// Value not supported, get default
|
||||
get_phy.attribute = PHY_DEF_NB_JOIN_TRIALS;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
request->req.join.nb_trials = (uint8_t) phy_param.value;
|
||||
}
|
||||
|
||||
params->flags.bits.mlme_req = 1;
|
||||
confirmation.req_type = request->type;
|
||||
|
||||
params->keys.dev_eui = request->req.join.dev_eui;
|
||||
params->keys.app_eui = request->req.join.app_eui;
|
||||
params->keys.app_key = request->req.join.app_key;
|
||||
params->max_join_request_trials = request->req.join.nb_trials;
|
||||
|
||||
// Reset variable JoinRequestTrials
|
||||
params->join_request_trial_counter = 0;
|
||||
|
||||
// Setup header information
|
||||
machdr.value = 0;
|
||||
machdr.bits.mtype = FRAME_TYPE_JOIN_REQ;
|
||||
|
||||
_lora_mac->reset_mac_parameters();
|
||||
|
||||
params->sys_params.channel_data_rate =
|
||||
_lora_phy->get_alternate_DR(params->join_request_trial_counter + 1);
|
||||
|
||||
status = _lora_mac->send(&machdr, 0, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case MLME_LINK_CHECK: {
|
||||
params->flags.bits.mlme_req = 1;
|
||||
// LoRaMac will send this command piggy-backed
|
||||
confirmation.req_type = request->type;
|
||||
|
||||
status = _mac_cmd->add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
||||
break;
|
||||
}
|
||||
case MLME_TXCW: {
|
||||
confirmation.req_type = request->type;
|
||||
params->flags.bits.mlme_req = 1;
|
||||
status = _lora_mac->set_tx_continuous_wave(request->req.cw_tx_mode.timeout);
|
||||
break;
|
||||
}
|
||||
case MLME_TXCW_1: {
|
||||
confirmation.req_type = request->type;
|
||||
params->flags.bits.mlme_req = 1;
|
||||
status = _lora_mac->set_tx_continuous_wave1(request->req.cw_tx_mode.timeout,
|
||||
request->req.cw_tx_mode.frequency,
|
||||
request->req.cw_tx_mode.power);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != LORAWAN_STATUS_OK) {
|
||||
params->is_node_ack_requested = false;
|
||||
params->flags.bits.mlme_req = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MBED_OS_LORAWAN_MAC_MLME_H_
|
||||
#define MBED_OS_LORAWAN_MAC_MLME_H_
|
||||
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "lorastack/phy/LoRaPHY.h"
|
||||
#include "lorastack/mac/LoRaMacCommand.h"
|
||||
|
||||
// forward declaration
|
||||
class LoRaMac;
|
||||
|
||||
class LoRaMacMlme {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* Sets local handles to NULL. These handles will be set when the subsystem
|
||||
* is activated by the MAC layer.
|
||||
*/
|
||||
LoRaMacMlme();
|
||||
|
||||
/** Destructor
|
||||
*
|
||||
* Does nothing
|
||||
*/
|
||||
~LoRaMacMlme();
|
||||
|
||||
/** Activating MLME subsystem
|
||||
*
|
||||
* Stores pointers to MAC and PHY layer handles
|
||||
*
|
||||
* @param mac pointer to MAC layer
|
||||
* @param phy pointer to PHY layer
|
||||
* @param cmd pointer to MAC commands
|
||||
*/
|
||||
void activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy, LoRaMacCommand *cmd);
|
||||
|
||||
/** Sets up an MLME Request
|
||||
*
|
||||
* Sets up an MLME request, e.g., a Join Request and sends it through
|
||||
* to the central MAC control. It also modifies or uses protocol information
|
||||
* provided in the MAC protocol data structure.
|
||||
*
|
||||
* @param request pointer to MLME request structure
|
||||
* @param params pointer to MAC protocol parameters
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t set_request(loramac_mlme_req_t *request, loramac_protocol_params *params);
|
||||
|
||||
/** Grants access to MLME confirmation data
|
||||
*
|
||||
* @return a reference to MLME confirm data structure
|
||||
*/
|
||||
inline loramac_mlme_confirm_t& get_confirmation()
|
||||
{
|
||||
return confirmation;
|
||||
}
|
||||
|
||||
/** Grants access to MLME indication data
|
||||
*
|
||||
* @return a reference to MLME indication data structure
|
||||
*/
|
||||
inline loramac_mlme_indication_t& get_indication()
|
||||
{
|
||||
return indication;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Pointers to MAC and PHY handles
|
||||
*/
|
||||
LoRaMac *_lora_mac;
|
||||
LoRaPHY *_lora_phy;
|
||||
LoRaMacCommand *_mac_cmd;
|
||||
|
||||
/**
|
||||
* Structure to hold MLME indication data.
|
||||
*/
|
||||
loramac_mlme_indication_t indication;
|
||||
|
||||
/**
|
||||
* Structure to hold MLME confirm data.
|
||||
*/
|
||||
loramac_mlme_confirm_t confirmation;
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAWAN_MAC_MLME_H_ */
|
|
@ -1,68 +0,0 @@
|
|||
/**
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC layer test function implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
|
||||
|
||||
Copyright (c) 2017, Arm Limited and affiliates.
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __LORAMACTEST_H__
|
||||
#define __LORAMACTEST_H__
|
||||
|
||||
/**
|
||||
* \brief Enabled or disables the reception windows
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] enable - Enabled or disables the reception windows
|
||||
*/
|
||||
void LoRaMacTestRxWindowsOn( bool enable );
|
||||
|
||||
/**
|
||||
* \brief Enables the MIC field test
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] txPacketCounter - Fixed Tx packet counter value
|
||||
*/
|
||||
void LoRaMacTestSetMic( uint16_t txPacketCounter );
|
||||
|
||||
/**
|
||||
* \brief Enabled or disables the duty cycle
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] enable - Enabled or disables the duty cycle
|
||||
*/
|
||||
void LoRaMacTestSetDutyCycleOn( bool enable );
|
||||
|
||||
/**
|
||||
* \brief Sets the channel index
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [in] channel - Channel index
|
||||
*/
|
||||
void LoRaMacTestSetChannel( uint8_t channel );
|
||||
|
||||
#endif // __LORAMACTEST_H__
|
File diff suppressed because it is too large
Load Diff
|
@ -34,112 +34,192 @@
|
|||
#ifndef MBED_OS_LORAPHY_BASE_
|
||||
#define MBED_OS_LORAPHY_BASE_
|
||||
|
||||
#include "lorawan/LoRaRadio.h"
|
||||
#include "lorawan/system/LoRaWANTimer.h"
|
||||
#include "lorawan/lorastack/phy/lora_phy_ds.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
class LoRaPHY {
|
||||
class LoRaPHY : private mbed::NonCopyable<LoRaPHY> {
|
||||
|
||||
public:
|
||||
LoRaPHY();
|
||||
virtual ~LoRaPHY();
|
||||
|
||||
/** Stores a reference to Radio object.
|
||||
*
|
||||
* Application is responsible for constructing a 'LoRaRadio' object
|
||||
* which is passed down to the PHY layer.
|
||||
*
|
||||
* @param radio a reference to radio driver object
|
||||
*/
|
||||
void set_radio_instance(LoRaRadio& radio);
|
||||
|
||||
/** Puts radio in sleep mode.
|
||||
*
|
||||
* Requests the radio driver to enter sleep mode.
|
||||
*/
|
||||
void put_radio_to_sleep(void);
|
||||
|
||||
/** Puts radio in standby mode.
|
||||
*
|
||||
* Requests the radio driver to enter standby mode.
|
||||
*/
|
||||
void put_radio_to_standby(void);
|
||||
|
||||
/** Puts radio in receive mode.
|
||||
*
|
||||
* Requests the radio driver to enter receive mode for a given time or to
|
||||
* enter continuous reception mode.
|
||||
*
|
||||
* @param is_rx_continuous if true, sets the radio to enter continuous
|
||||
* reception mode.
|
||||
*
|
||||
* @param max_rx_window duration of receive window
|
||||
*/
|
||||
void setup_rx_window(bool is_rx_continuous, uint32_t max_rx_window);
|
||||
|
||||
void setup_tx_cont_wave_mode(uint16_t timeout, uint32_t frequency,
|
||||
uint8_t power);
|
||||
|
||||
/** Delegates MAC layer request to transmit packet.
|
||||
*
|
||||
* @param buf a pointer to the data which needs to be transmitted
|
||||
*
|
||||
* @param size size of the data in bytes
|
||||
*/
|
||||
void handle_send(uint8_t *buf, uint8_t size);
|
||||
|
||||
/** Enables/Disables public network mode.
|
||||
*
|
||||
* Public and private LoRaWAN network constitute different preambles and
|
||||
* Net IDs. This API isused to tell the radio which network mode is in use.
|
||||
*
|
||||
* @param set true or false
|
||||
*/
|
||||
void setup_public_network_mode(bool set);
|
||||
|
||||
/** Provides a random number from radio.
|
||||
*
|
||||
* Returns a 32-bit random unsigned integer value based upon RSSI
|
||||
* measurements.
|
||||
*
|
||||
* @return a 32-bit long random number
|
||||
*
|
||||
*/
|
||||
uint32_t get_radio_rng();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
/** Calculates and applies duty cycle back-off time.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
* Explicitly updates the band time-off.
|
||||
*
|
||||
* \retval A structure containing the PHY parameter.
|
||||
* @param [in] backoff_params A pointer to backoff parameters.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ) = 0;
|
||||
void calculate_backoff(backoff_params_t* backoff_params);
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
/**
|
||||
* Tests if a channel is on or off in the channel mask
|
||||
*/
|
||||
inline bool mask_bit_test(const uint16_t *mask, unsigned bit) {
|
||||
return mask[bit/16] & (1U << (bit % 16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a channel is on or off in the channel mask
|
||||
*/
|
||||
inline void mask_bit_set(uint16_t *mask, unsigned bit) {
|
||||
mask[bit/16] |= (1U << (bit % 16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a channel is on or off in the channel mask
|
||||
*/
|
||||
inline void mask_bit_clear(uint16_t *mask, unsigned bit) {
|
||||
mask[bit/16] &= ~(1U << (bit % 16));
|
||||
}
|
||||
|
||||
/** Entertain a new channel request MAC command.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
* MAC command subsystem processes the new channel request coming form
|
||||
* the network server and then MAC layer asks the PHY layer to entertain
|
||||
* the request.
|
||||
*
|
||||
* @param [in] new_channel_req A pointer to the new_channel_req_params_t.
|
||||
*
|
||||
* @return bit mask, according to the LoRaWAN spec 1.0.2.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ) = 0;
|
||||
virtual uint8_t request_new_channel(new_channel_req_params_t* new_channel_req);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
/** Grants access to PHY layer parameters.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
* This is essentially a PHY layer parameter retrieval system.
|
||||
* A request is made for a certain parameter by setting an appropriate
|
||||
* attribute.
|
||||
*
|
||||
* @param [in] get_phy A pointer to get_phy_params_t
|
||||
*
|
||||
* @return A structure containing the requested PHY parameter value.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type ) = 0;
|
||||
virtual phy_param_t get_phy_params(get_phy_params_t* get_phy);
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
/** Process PHY layer state after a successful transmission.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
* Updates times of the last transmission for the particular channel and
|
||||
* band upon which last transmission took place.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute for which the verification is needed.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
* @param [in] tx_done A pointer to set_band_txdone_params_t
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ) = 0;
|
||||
virtual void set_last_tx_done(set_band_txdone_params_t* tx_done);
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
/** Enables default channels only.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
* Falls back to a channel mask where only default channels are enabled, all
|
||||
* other channels are disabled.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ) = 0;
|
||||
virtual void restore_default_channels();
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
/** Verify if a parameter is eligible.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
* @param verify A pointer to the verification_params_t that contains
|
||||
* parameters which we need to check for validity.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
* @param phy_attr The attribute for which the verification is needed.
|
||||
*
|
||||
* @return True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ) = 0;
|
||||
virtual bool verify(verification_params_t* verify, phy_attributes_t phy_attr);
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
/** Processes the incoming CF-list.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
* Handles the payload containing CF-list and enables channels defined
|
||||
* therein.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
* @param cflist_params A pointer to cflist_params_t.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter ) = 0;
|
||||
virtual void apply_cf_list(cflist_params_t* cflist_params);
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
/** Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
* @param restore_channel_mask A boolean set restore channel mask in case
|
||||
* of failure.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
* @param dr_out The calculated datarate for the next TX.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
* @param tx_power_out The TX power for the next TX.
|
||||
*
|
||||
* @param adr_ack_counter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* @return True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ) = 0;
|
||||
bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
|
||||
int8_t& tx_power_out, uint32_t& adr_ack_counter);
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
/** Configure radio reception.
|
||||
*
|
||||
* @param [in] config A pointer to the RX configuration.
|
||||
*
|
||||
* @param [out] datarate The datarate index set.
|
||||
*
|
||||
* @return True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(rx_config_params_t* config, int8_t* datarate);
|
||||
|
||||
/** Computing Receive Windows
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
|
@ -179,499 +259,258 @@ public:
|
|||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
* @param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
* @param [in] min_rx_symbols The minimum number of symbols required to
|
||||
* detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
* @param [in] rx_error The maximum timing error of the receiver
|
||||
* in milliseconds. The receiver will turn on
|
||||
* in a [-rxError : +rxError] ms interval around
|
||||
* RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
* @param [out] rx_conf_params Pointer to the structure that needs to be
|
||||
* filled with receive window parameters.
|
||||
*
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams) = 0;
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir ) = 0;
|
||||
virtual void compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols,
|
||||
uint32_t rx_error,
|
||||
rx_config_params_t *rx_conf_params);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
/** Configure radio transmission.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
* @param [in] tx_config Structure containing tx parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
* @param [out] tx_power The TX power which will be set.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
* @param [out] tx_toa The time-on-air of the frame.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* @return True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed ) = 0;
|
||||
virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power,
|
||||
lorawan_time_t* tx_toa);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
/** Processes a Link ADR Request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
* @param [in] params A pointer ADR request parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* @param [out] dr_out The datarate applied.
|
||||
*
|
||||
* @param [out] tx_power_out The TX power applied.
|
||||
*
|
||||
* @param [out] nb_rep_out The number of repetitions to apply.
|
||||
*
|
||||
* @param [out] nb_bytes_parsed The number of bytes parsed.
|
||||
*
|
||||
* @return The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ) = 0;
|
||||
virtual uint8_t link_ADR_request(adr_req_params_t* params,
|
||||
int8_t* dr_out, int8_t* tx_power_out,
|
||||
uint8_t* nb_rep_out,
|
||||
uint8_t* nb_bytes_parsed);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a New Channel Request.
|
||||
/** Accept or rejects RxParamSetupReq MAC command
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
* The function processes a RX parameter setup request in response to
|
||||
* server MAC command for RX setup.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* @param [in] params A pointer to rx parameter setup request.
|
||||
*
|
||||
* @return The status of the operation, according to the LoRaWAN specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ) = 0;
|
||||
virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
/** Makes decision whether to accept or reject TxParamSetupReq MAC command
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
* @param [in] params A pointer to tx parameter setup request.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
* @return True to let the MAC know that the request is
|
||||
* accepted and MAC can apply TX parameters received
|
||||
* form Network Server. Otherwise false is returned.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ) = 0;
|
||||
virtual bool accept_tx_param_setup_req(tx_param_setup_req_t* params);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
/** Processes a DlChannelReq MAC command.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
* @param [in] params A pointer to downlink channel request.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* @return The status of the operation, according to the LoRaWAN specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ) = 0;
|
||||
virtual uint8_t dl_channel_request(dl_channel_req_params_t* params);
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
/** Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
* @param nb_trials Number of trials to be made on one given data rate.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
* @return The datarate to apply .
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ) = 0;
|
||||
virtual int8_t get_alternate_DR(uint8_t nb_trials);
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
/** Searches and sets the next available channel.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
* If there are multiple channels found available, one of them is selected
|
||||
* randomly.
|
||||
*
|
||||
* @param [in] nextChanParams Parameters for the next channel.
|
||||
*
|
||||
* @param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* @param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* @param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* @return Function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ) = 0;
|
||||
virtual bool set_next_channel(channel_selection_params_t* nextChanParams,
|
||||
uint8_t* channel, lorawan_time_t* time,
|
||||
lorawan_time_t* aggregatedTimeOff);
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
/** Adds a channel to the channel list.
|
||||
*
|
||||
* \param [in] nextChanParams Parameters for the next channel.
|
||||
* Verifies the channel parameters and if everything is found legitimate,
|
||||
* adds that particular channel to the channel list and updates the channel
|
||||
* mask.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
* @param [in] new_channel A pointer to the parameters for the new channel.
|
||||
* @param [in] id Channel ID
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
* @return LORAWAN_STATUS_OK if everything goes fine, negative error code
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff ) = 0;
|
||||
virtual lorawan_status_t add_channel(channel_params_t* new_channel, uint8_t id);
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
/** Removes a channel from the channel list.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
* @param [in] channel_id Index of the channel to be removed
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
* @return True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ) = 0;
|
||||
virtual bool remove_channel(uint8_t channel_id);
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
/** Puts the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
* @param [in] continuous_wave A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
* @param [in] frequency Frequency to transmit at
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ) = 0;
|
||||
virtual void set_tx_cont_mode(cw_mode_params_t* continuous_wave,
|
||||
uint32_t frequency = 0);
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
/** Computes new data rate according to the given offset
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
* @param [in] dr The current datarate.
|
||||
*
|
||||
* @param [in] dr_offset The offset to be applied.
|
||||
*
|
||||
* @return The computed datarate.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ) = 0;
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) = 0;
|
||||
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);
|
||||
|
||||
protected:
|
||||
LoRaRadio *_radio;
|
||||
LoRaWANTimeHandler &_lora_time;
|
||||
loraphy_params_t phy_params;
|
||||
|
||||
typedef struct sRegionCommonLinkAdrParams
|
||||
{
|
||||
/*!
|
||||
* The number of repetitions.
|
||||
*/
|
||||
uint8_t NbRep;
|
||||
/*!
|
||||
* Datarate.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* TX power.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
* Channels mask control field.
|
||||
*/
|
||||
uint8_t ChMaskCtrl;
|
||||
/*!
|
||||
* Channels mask field.
|
||||
*/
|
||||
uint16_t ChMask;
|
||||
}RegionCommonLinkAdrParams_t;
|
||||
LoRaPHY(LoRaWANTimeHandler &lora_time);
|
||||
|
||||
typedef struct sRegionCommonLinkAdrReqVerifyParams
|
||||
{
|
||||
/*!
|
||||
* The current status of the AdrLinkRequest.
|
||||
*/
|
||||
uint8_t Status;
|
||||
/*!
|
||||
* Set to true, if ADR is enabled.
|
||||
*/
|
||||
bool AdrEnabled;
|
||||
/*!
|
||||
* The datarate the AdrLinkRequest wants to set.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* The TX power the AdrLinkRequest wants to set.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
* The number of repetitions the AdrLinkRequest wants to set.
|
||||
*/
|
||||
uint8_t NbRep;
|
||||
/*!
|
||||
* The current datarate the node is using.
|
||||
*/
|
||||
int8_t CurrentDatarate;
|
||||
/*!
|
||||
* The current TX power the node is using.
|
||||
*/
|
||||
int8_t CurrentTxPower;
|
||||
/*!
|
||||
* The current number of repetitions the node is using.
|
||||
*/
|
||||
int8_t CurrentNbRep;
|
||||
/*!
|
||||
* The number of channels.
|
||||
*/
|
||||
uint8_t NbChannels;
|
||||
/*!
|
||||
* A pointer to the first element of the channels mask.
|
||||
*/
|
||||
uint16_t* ChannelsMask;
|
||||
/*!
|
||||
* The minimum possible datarate.
|
||||
*/
|
||||
int8_t MinDatarate;
|
||||
/*!
|
||||
* The maximum possible datarate.
|
||||
*/
|
||||
int8_t MaxDatarate;
|
||||
/*!
|
||||
* A pointer to the channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
/*!
|
||||
* The minimum possible TX power.
|
||||
*/
|
||||
int8_t MinTxPower;
|
||||
/*!
|
||||
* The maximum possible TX power.
|
||||
*/
|
||||
int8_t MaxTxPower;
|
||||
}RegionCommonLinkAdrReqVerifyParams_t;
|
||||
|
||||
typedef struct sRegionCommonCalcBackOffParams
|
||||
{
|
||||
/*!
|
||||
* A pointer to region specific channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
/*!
|
||||
* A pointer to region specific bands.
|
||||
*/
|
||||
Band_t* Bands;
|
||||
/*!
|
||||
* Set to true, if the last uplink was a join request.
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
* Set to true, if the node is joined.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
* Set to true, if the duty cycle is enabled.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
* The current channel.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
* The elapsed time since initialization.
|
||||
*/
|
||||
TimerTime_t ElapsedTime;
|
||||
/*!
|
||||
* The time on air of the last TX frame.
|
||||
*/
|
||||
TimerTime_t TxTimeOnAir;
|
||||
}RegionCommonCalcBackOffParams_t;
|
||||
|
||||
/*!
|
||||
* \brief Calculates the join duty cycle.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] elapsedTime The time elapsed since starting the device.
|
||||
*
|
||||
* \retval Duty cycle restriction.
|
||||
/**
|
||||
* Verifies the given frequency.
|
||||
*/
|
||||
uint16_t get_join_DC( TimerTime_t elapsedTime );
|
||||
virtual bool verify_frequency(uint32_t freq);
|
||||
|
||||
/*!
|
||||
* \brief Verifies, if a value is in a given range.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] value The value to verify, if it is in range.
|
||||
*
|
||||
* \param [in] min The minimum possible value.
|
||||
*
|
||||
* \param [in] max The maximum possible value.
|
||||
*
|
||||
* \retval 1 if the value is in range, otherwise 0.
|
||||
|
||||
/**
|
||||
* Verifies, if a value is in a given range.
|
||||
*/
|
||||
uint8_t val_in_range( int8_t value, int8_t min, int8_t max );
|
||||
uint8_t val_in_range(int8_t value, int8_t min, int8_t max);
|
||||
|
||||
/*!
|
||||
* \brief Verifies, if a datarate is available on an active channel.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] nbChannels The number of channels.
|
||||
*
|
||||
* \param [in] channelsMask The channels mask of the region.
|
||||
*
|
||||
* \param [in] dr The datarate to verify.
|
||||
*
|
||||
* \param [in] minDr The minimum datarate.
|
||||
*
|
||||
* \param [in] maxDr The maximum datarate.
|
||||
*
|
||||
* \param [in] channels The channels of the region.
|
||||
*
|
||||
* \retval True if the datarate is supported, false if not.
|
||||
/**
|
||||
* Verifies, if a datarate is available on an active channel.
|
||||
*/
|
||||
bool verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr,
|
||||
int8_t minDr, int8_t maxDr, ChannelParams_t* channels );
|
||||
bool verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, int8_t dr,
|
||||
int8_t minDr, int8_t maxDr, channel_params_t* channels);
|
||||
|
||||
/*!
|
||||
* \brief Disables a channel in a given channels mask.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] channelsMask The channels mask of the region.
|
||||
*
|
||||
* \param [in] id The ID of the channels mask to disable.
|
||||
*
|
||||
* \param [in] maxChannels The maximum number of channels.
|
||||
*
|
||||
* \retval True if the channel could be disabled, false if not.
|
||||
/**
|
||||
* Disables a channel in a given channels mask.
|
||||
*/
|
||||
bool disable_channel( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels );
|
||||
bool disable_channel(uint16_t* channel_mask, uint8_t id, uint8_t max_channels);
|
||||
|
||||
/*!
|
||||
* \brief Counts the number of active channels in a given channels mask.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] channelsMask The channels mask of the region.
|
||||
*
|
||||
* \param [in] startIdx The start index.
|
||||
*
|
||||
* \param [in] stopIdx The stop index (the channels of this index will not be counted).
|
||||
*
|
||||
* \retval The number of active channels.
|
||||
/**
|
||||
* Counts number of bits on in a given mask
|
||||
*/
|
||||
uint8_t num_active_channels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx );
|
||||
uint8_t count_bits(uint16_t mask, uint8_t nb_bits);
|
||||
|
||||
/*!
|
||||
* \brief Copy a channels mask.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] channelsMaskDest The destination channels mask.
|
||||
*
|
||||
* \param [in] channelsMaskSrc The source channels mask.
|
||||
*
|
||||
* \param [in] len The index length to copy.
|
||||
/**
|
||||
* Counts the number of active channels in a given channels mask.
|
||||
*/
|
||||
void copy_channel_mask( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len );
|
||||
uint8_t num_active_channels(uint16_t* channel_mask, uint8_t start_idx,
|
||||
uint8_t stop_idx);
|
||||
|
||||
/*!
|
||||
* \brief Sets the last TX done property.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] joined Set to true, if the node has joined the network
|
||||
*
|
||||
* \param [in] band The band to be updated.
|
||||
*
|
||||
* \param [in] lastTxDone The time of the last TX done.
|
||||
/**
|
||||
* Copy channel masks.
|
||||
*/
|
||||
void set_last_tx_done( bool joined, Band_t* band, TimerTime_t lastTxDone );
|
||||
void copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t len);
|
||||
|
||||
/*!
|
||||
* \brief Updates the time-offs of the bands.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] joined Set to true, if the node has joined the network
|
||||
*
|
||||
* \param [in] dutyCycle Set to true, if the duty cycle is enabled.
|
||||
*
|
||||
* \param [in] bands A pointer to the bands.
|
||||
*
|
||||
* \param [in] nbBands The number of bands available.
|
||||
*
|
||||
* \retval The time which must be waited to perform the next uplink.
|
||||
/**
|
||||
* Updates the time-offs of the bands.
|
||||
*/
|
||||
TimerTime_t update_band_timeoff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands );
|
||||
lorawan_time_t update_band_timeoff(bool joined, bool dutyCycle, band_t* bands,
|
||||
uint8_t nb_bands);
|
||||
|
||||
/*!
|
||||
* \brief Parses the parameter of an LinkAdrRequest.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [in] payload A pointer to the payload containing the MAC commands. The payload
|
||||
* must contain the CMD identifier, followed by the parameters.
|
||||
*
|
||||
* \param [out] parseLinkAdr The function fills the structure with the ADR parameters.
|
||||
*
|
||||
* \retval The length of the ADR request, if a request was found. Otherwise, the
|
||||
* function returns 0.
|
||||
/**
|
||||
* Parses the parameter of an LinkAdrRequest.
|
||||
*/
|
||||
uint8_t parse_link_ADR_req( uint8_t* payload, RegionCommonLinkAdrParams_t* parseLinkAdr );
|
||||
uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* adr_params);
|
||||
|
||||
/*!
|
||||
* \brief Verifies and updates the datarate, the TX power and the number of repetitions
|
||||
* of a LinkAdrRequest. This also depends on the ADR configuration.
|
||||
*
|
||||
* \param [in] verifyParams A pointer to a structure containing the input parameters.
|
||||
*
|
||||
* \param [out] dr The updated datarate.
|
||||
*
|
||||
* \param [out] txPow The updated TX power.
|
||||
*
|
||||
* \param [out] nbRep The updated number of repetitions.
|
||||
*
|
||||
* \retval The status according to the LinkAdrRequest definition.
|
||||
/**
|
||||
* Verifies and updates the datarate, the TX power and the number of repetitions
|
||||
* of a LinkAdrRequest.
|
||||
*/
|
||||
uint8_t verify_link_ADR_req( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep );
|
||||
uint8_t verify_link_ADR_req(verify_adr_params_t* verify_params, int8_t* dr,
|
||||
int8_t* tx_pow, uint8_t* nb_rep);
|
||||
|
||||
/*!
|
||||
* \brief Computes the symbol time for LoRa modulation.
|
||||
*
|
||||
* \param [in] phyDr The physical datarate to use.
|
||||
*
|
||||
* \param [in] bandwidth The bandwidth to use.
|
||||
*
|
||||
* \retval The symbol time.
|
||||
/**
|
||||
* Computes the symbol time for LoRa modulation.
|
||||
*/
|
||||
double compute_symb_timeout_lora( uint8_t phyDr, uint32_t bandwidth );
|
||||
double compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth );
|
||||
|
||||
/*!
|
||||
* \brief Computes the symbol time for FSK modulation.
|
||||
*
|
||||
* \param [in] phyDr The physical datarate to use.
|
||||
*
|
||||
* \retval The symbol time.
|
||||
/**
|
||||
* Computes the symbol time for FSK modulation.
|
||||
*/
|
||||
double compute_symb_timeout_fsk( uint8_t phyDr );
|
||||
double compute_symb_timeout_fsk(uint8_t phy_dr);
|
||||
|
||||
/*!
|
||||
* \brief Computes the RX window timeout and the RX window offset.
|
||||
*
|
||||
* \param [in] tSymbol The symbol timeout.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum required number of symbols to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms interval around RxOffset.
|
||||
*
|
||||
* \param [in] wakeUpTime The wakeup time of the system.
|
||||
*
|
||||
* \param [out] windowTimeout The RX window timeout.
|
||||
*
|
||||
* \param [out] windowOffset The RX window time offset to be applied to the RX delay.
|
||||
/**
|
||||
* Computes the RX window timeout and the RX window offset.
|
||||
*/
|
||||
void get_rx_window_params( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset );
|
||||
void get_rx_window_params(double t_symbol, uint8_t min_rx_symbols,
|
||||
uint32_t rx_error, uint32_t wakeup_time,
|
||||
uint32_t* window_timeout, int32_t* window_offset);
|
||||
|
||||
/*!
|
||||
* \brief Computes the txPower, based on the max EIRP and the antenna gain.
|
||||
*
|
||||
* \param [in] txPowerIndex The TX power index.
|
||||
*
|
||||
* \param [in] maxEirp The maximum EIRP.
|
||||
*
|
||||
* \param [in] antennaGain The antenna gain.
|
||||
*
|
||||
* \retval The physical TX power.
|
||||
/**
|
||||
* Computes the txPower, based on the max EIRP and the antenna gain.
|
||||
*/
|
||||
int8_t compute_tx_power( int8_t txPowerIndex, float maxEirp, float antennaGain );
|
||||
int8_t compute_tx_power(int8_t txPowerIndex, float maxEirp, float antennaGain);
|
||||
|
||||
/*!
|
||||
* \brief Provides a random number in the range provided.
|
||||
*
|
||||
* \param [in] min lower boundary
|
||||
* \param [in] max upper boundary
|
||||
/**
|
||||
* Provides a random number in the range provided.
|
||||
*/
|
||||
int32_t get_random(int32_t min, int32_t max);
|
||||
|
||||
/*!
|
||||
* \brief Calculates the duty cycle for the current band.
|
||||
*
|
||||
* \param [in] calcBackOffParams A pointer to the input parameters.
|
||||
/**
|
||||
* Get next lower data rate
|
||||
*/
|
||||
void get_DC_backoff( RegionCommonCalcBackOffParams_t* calcBackOffParams );
|
||||
int8_t get_next_lower_dr(int8_t dr, int8_t min_dr);
|
||||
|
||||
/**
|
||||
* Get channel bandwidth depending upon data rate table index
|
||||
*/
|
||||
uint8_t get_bandwidth(uint8_t dr_index);
|
||||
|
||||
uint8_t enabled_channel_count(bool joined, uint8_t datarate,
|
||||
const uint16_t *mask, uint8_t* enabledChannels,
|
||||
uint8_t* delayTx);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_BASE_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHY_AS923_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
|
@ -45,319 +44,28 @@
|
|||
*/
|
||||
#define AS923_MAX_NB_BANDS 1
|
||||
|
||||
#define AS923_CHANNELS_MASK_SIZE 1
|
||||
#define AS923_CHANNEL_MASK_SIZE 1
|
||||
|
||||
|
||||
class LoRaPHYAS923 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYAS923();
|
||||
LoRaPHYAS923(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYAS923();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval A structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
virtual int8_t get_alternate_DR(uint8_t nb_trials);
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
virtual bool set_next_channel(channel_selection_params_t* nextChanParams,
|
||||
uint8_t* channel, lorawan_time_t* time,
|
||||
lorawan_time_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to be verified.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing.
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum required number of symbols to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams The updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
virtual uint8_t apply_DR_offset(int8_t dr, int8_t drOffset );
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels(bool joined, uint8_t datarate,
|
||||
uint16_t* channelsMask,
|
||||
ChannelParams_t* channels, Band_t* bands,
|
||||
uint8_t* enabledChannels, uint8_t* delayTx);
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[AS923_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[AS923_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
*/
|
||||
uint16_t ChannelsMask[AS923_CHANNELS_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[AS923_CHANNELS_MASK_SIZE];
|
||||
channel_params_t channels[AS923_MAX_NB_CHANNELS];
|
||||
band_t bands[AS923_MAX_NB_BANDS];
|
||||
uint16_t channel_mask[AS923_CHANNEL_MASK_SIZE];
|
||||
uint16_t default_channel_mask[AS923_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_AS923_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,7 +34,6 @@
|
|||
#define MBED_OS_LORAPHY_AU915_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
// Definitions
|
||||
/*!
|
||||
|
@ -47,327 +46,62 @@
|
|||
*/
|
||||
#define AU915_MAX_NB_BANDS 1
|
||||
|
||||
#define AU915_CHANNELS_MASK_SIZE 6
|
||||
#define AU915_CHANNEL_MASK_SIZE 5
|
||||
|
||||
|
||||
class LoRaPHYAU915 : public LoRaPHY{
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYAU915();
|
||||
LoRaPHYAU915(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYAU915();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval A structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
virtual bool rx_config(rx_config_params_t* config, int8_t* datarate);
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
virtual bool tx_config(tx_config_params_t* config, int8_t* txPower,
|
||||
lorawan_time_t* txTimeOnAir);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to be verified.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams The updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
virtual uint8_t link_ADR_request(adr_req_params_t* params,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
uint8_t* nbBytesParsed);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
virtual int8_t get_alternate_DR(uint8_t nb_trials);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
virtual bool set_next_channel(channel_selection_params_t* next_chan_params,
|
||||
uint8_t* channel, lorawan_time_t* time,
|
||||
lorawan_time_t* aggregate_timeoff);
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval The function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels(uint8_t datarate,
|
||||
uint16_t* channelsMask,
|
||||
ChannelParams_t* channels,
|
||||
Band_t* bands, uint8_t* enabledChannels,
|
||||
uint8_t* delayTx);
|
||||
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[AU915_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[AU915_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[AU915_MAX_NB_BANDS];
|
||||
band_t bands[AU915_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[AU915_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[AU915_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels remaining
|
||||
* Previously used channel mask
|
||||
*/
|
||||
uint16_t ChannelsMaskRemaining[AU915_CHANNELS_MASK_SIZE];
|
||||
uint16_t current_channel_mask[AU915_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[AU915_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[AU915_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_AU915_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHY_CN470_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
// Definitions
|
||||
/*!
|
||||
|
@ -47,319 +46,48 @@
|
|||
#define CN470_MAX_NB_BANDS 1
|
||||
|
||||
|
||||
#define CN470_CHANNELS_MASK_SIZE 6
|
||||
#define CN470_CHANNEL_MASK_SIZE 6
|
||||
|
||||
|
||||
class LoRaPHYCN470 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYCN470();
|
||||
LoRaPHYCN470(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYCN470();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval A structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
virtual bool rx_config(rx_config_params_t* config, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power,
|
||||
lorawan_time_t* tx_toa);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
virtual uint8_t link_ADR_request(adr_req_params_t* params, int8_t* dr_out,
|
||||
int8_t* tx_power_out, uint8_t* nb_rep_out,
|
||||
uint8_t* nb_bytes_parsed);
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to be verified.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams The updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[CN470_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[CN470_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[CN470_MAX_NB_BANDS];
|
||||
band_t bands[CN470_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[CN470_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[CN470_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[CN470_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[CN470_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_CN470_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,322 +33,41 @@
|
|||
#define MBED_OS_LORAPHY_CN779_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
#define CN779_MAX_NB_CHANNELS 16
|
||||
|
||||
#define CN779_MAX_NB_BANDS 1
|
||||
|
||||
#define CN779_CHANNELS_MASK_SIZE 1
|
||||
#define CN779_CHANNEL_MASK_SIZE 1
|
||||
|
||||
|
||||
class LoRaPHYCN779 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYCN779();
|
||||
LoRaPHYCN779(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYCN779();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum required number of symbols to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[CN779_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[CN779_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[CN779_MAX_NB_BANDS];
|
||||
band_t bands[CN779_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[CN779_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[CN779_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[CN779_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[CN779_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_CN779_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHY_EU433_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
|
@ -45,316 +44,36 @@
|
|||
*/
|
||||
#define EU433_MAX_NB_BANDS 1
|
||||
|
||||
#define EU433_CHANNELS_MASK_SIZE 1
|
||||
#define EU433_CHANNEL_MASK_SIZE 1
|
||||
|
||||
|
||||
class LoRaPHYEU433 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYEU433();
|
||||
LoRaPHYEU433(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYEU433();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[EU433_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[EU433_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[EU433_MAX_NB_BANDS];
|
||||
band_t bands[EU433_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[EU433_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[EU433_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[EU433_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[EU433_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHY_EU868_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
|
@ -42,317 +41,42 @@
|
|||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*
|
||||
* We have broken down EU-868 MHz BAND 2 into two parts. That's why
|
||||
* total number of sub-bands is 6.
|
||||
* from 863 MHz to 865 MHz region is part of BAND 2, however
|
||||
* we call it Band-5 here. Duty cycle limit is 0.1 % in this sub band.
|
||||
*/
|
||||
#define EU868_MAX_NB_BANDS 5
|
||||
|
||||
#define EU868_CHANNELS_MASK_SIZE 1
|
||||
#define EU868_MAX_NB_BANDS 6
|
||||
|
||||
#define EU868_CHANNEL_MASK_SIZE 1
|
||||
|
||||
class LoRaPHYEU868 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
LoRaPHYEU868();
|
||||
LoRaPHYEU868(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYEU868();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval The function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[EU868_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[EU868_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[EU868_MAX_NB_BANDS];
|
||||
band_t bands[EU868_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
*/
|
||||
uint16_t ChannelsMask[EU868_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[EU868_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[EU868_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[EU868_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_EU868_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHY_IN865_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -46,316 +45,38 @@
|
|||
*/
|
||||
#define IN865_MAX_NB_BANDS 1
|
||||
|
||||
|
||||
#define IN865_CHANNELS_MASK_SIZE 1
|
||||
#define IN865_CHANNEL_MASK_SIZE 1
|
||||
|
||||
|
||||
class LoRaPHYIN865 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYIN865();
|
||||
LoRaPHYIN865(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYIN865();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details, please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval The function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pPointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset );
|
||||
|
||||
private:
|
||||
uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[IN865_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[IN865_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[IN865_MAX_NB_BANDS];
|
||||
band_t bands[IN865_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[IN865_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[IN865_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[IN865_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[IN865_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_IN865_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHY_KR920_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
|
@ -45,314 +44,52 @@
|
|||
*/
|
||||
#define KR920_MAX_NB_BANDS 1
|
||||
|
||||
#define KR920_CHANNELS_MASK_SIZE 1
|
||||
#define KR920_CHANNEL_MASK_SIZE 1
|
||||
|
||||
|
||||
class LoRaPHYKR920 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYKR920();
|
||||
LoRaPHYKR920(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYKR920();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
virtual bool verify_frequency(uint32_t freq);
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power,
|
||||
lorawan_time_t* tx_toa);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel,
|
||||
lorawan_time_t* time,
|
||||
lorawan_time_t* aggregate_timeOff);
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave,
|
||||
uint32_t frequency = 0);
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
private:
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
int8_t get_max_eirp(uint32_t freq);
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details, please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval The function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
/**
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[KR920_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[KR920_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
/**
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[KR920_MAX_NB_BANDS];
|
||||
band_t bands[KR920_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
/**
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[KR920_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[KR920_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
/**
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[KR920_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[KR920_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif // MBED_OS_LORAPHY_KR920_H_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,6 @@
|
|||
#define MBED_OS_LORAPHYUS_915_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
|
@ -45,321 +44,69 @@
|
|||
*/
|
||||
#define US915_MAX_NB_BANDS 1
|
||||
|
||||
#define US915_CHANNELS_MASK_SIZE 6
|
||||
#define US915_CHANNEL_MASK_SIZE 5
|
||||
|
||||
|
||||
class LoRaPHYUS915 : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYUS915();
|
||||
LoRaPHYUS915(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYUS915();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
virtual void restore_default_channels();
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
virtual bool rx_config(rx_config_params_t* config, int8_t* datarate);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power,
|
||||
lorawan_time_t* tx_toa);
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
virtual uint8_t link_ADR_request(adr_req_params_t* params,
|
||||
int8_t* dr_out, int8_t* tx_power_out,
|
||||
uint8_t* nb_rep_out,
|
||||
uint8_t* nb_bytes_parsed);
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
virtual int8_t get_alternate_DR(uint8_t nb_trials);
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel,
|
||||
lorawan_time_t* time, lorawan_time_t* aggregate_timeOff);
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave,
|
||||
uint32_t frequency = 0);
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details, please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval The function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);
|
||||
|
||||
private:
|
||||
int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask );
|
||||
uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
|
||||
// Global attributes
|
||||
int8_t limit_tx_power(int8_t tx_power, int8_t max_band_tx_power,
|
||||
int8_t datarate);
|
||||
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[US915_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[US915_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[US915_MAX_NB_BANDS];
|
||||
band_t bands[US915_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
* LoRaMac channel mask
|
||||
*/
|
||||
uint16_t ChannelsMask[US915_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[US915_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels remaining
|
||||
* Previously used channel mask
|
||||
*/
|
||||
uint16_t ChannelsMaskRemaining[US915_CHANNELS_MASK_SIZE];
|
||||
uint16_t current_channel_mask[US915_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[US915_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[US915_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_US915_H_ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,11 +29,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef MBED_OS_LORAPHY_US915HYBRID_H_
|
||||
#ifndef MBED_OS_LORAPHY_US915_HYBRID_H_
|
||||
#define MBED_OS_LORAPHY_US915_HYBRID_H_
|
||||
|
||||
#include "LoRaPHY.h"
|
||||
#include "netsocket/LoRaRadio.h"
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -46,321 +45,73 @@
|
|||
*/
|
||||
#define US915_HYBRID_MAX_NB_BANDS 1
|
||||
|
||||
#define US915_HYBRID_CHANNELS_MASK_SIZE 6
|
||||
#define US915_HYBRID_CHANNEL_MASK_SIZE 5
|
||||
|
||||
|
||||
class LoRaPHYUS915Hybrid : public LoRaPHY {
|
||||
|
||||
public:
|
||||
|
||||
LoRaPHYUS915Hybrid();
|
||||
LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time);
|
||||
virtual ~LoRaPHYUS915Hybrid();
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific PHY attribute.
|
||||
*
|
||||
* \param [in] getPhy A pointer to the function parameters.
|
||||
*
|
||||
* \retval The structure containing the PHY parameter.
|
||||
*/
|
||||
virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy );
|
||||
virtual void restore_default_channels();
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [in] txDone A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone );
|
||||
virtual bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
|
||||
int8_t& tx_power_out, uint32_t& adr_ack_cnt);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [in] type Sets the initialization type.
|
||||
*/
|
||||
virtual void load_defaults(InitType_t type );
|
||||
virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate);
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [in] verify A pointer to the function parameters.
|
||||
*
|
||||
* \param [in] phyAttribute The attribute to verify.
|
||||
*
|
||||
* \retval True, if the parameter is valid.
|
||||
*/
|
||||
virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power,
|
||||
lorawan_time_t* tx_toa);
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the CF list.
|
||||
*
|
||||
* \param [in] applyCFList A pointer to the function parameters.
|
||||
*/
|
||||
virtual void apply_cf_list(ApplyCFListParams_t* applyCFList );
|
||||
virtual uint8_t link_ADR_request(adr_req_params_t* params,
|
||||
int8_t* dr_out, int8_t* tx_power_out,
|
||||
uint8_t* nb_rep_out,
|
||||
uint8_t* nb_bytes_parsed);
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [in] chanMaskSet A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channels mask could be set.
|
||||
*/
|
||||
virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet );
|
||||
virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [in] adrNext A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [out] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [out] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval True, if an ADR request should be performed.
|
||||
*/
|
||||
virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut,
|
||||
int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
virtual int8_t get_alternate_DR(uint8_t nb_trials);
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [in] rxConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] datarate The datarate index set.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
virtual bool set_next_channel(channel_selection_params_t* params,
|
||||
uint8_t* channel, lorawan_time_t* time,
|
||||
lorawan_time_t* aggregate_timeoff);
|
||||
|
||||
/*
|
||||
* RX window precise timing
|
||||
*
|
||||
* For more details, please consult the following document, chapter 3.1.2.
|
||||
* http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
|
||||
* or
|
||||
* http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
|
||||
*
|
||||
* Downlink start: T = Tx + 1s (+/- 20 us)
|
||||
* |
|
||||
* TRxEarly | TRxLate
|
||||
* | | |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | | Latest Rx window |
|
||||
* | | +---+---+---+---+---+---+---+---+
|
||||
* | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* | Earliest Rx window |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*Downlink preamble 8 symbols | | | | | | | | |
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* Worst case Rx window timings
|
||||
*
|
||||
* TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
|
||||
* TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
|
||||
*
|
||||
* TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
*
|
||||
* RxOffset = ( TRxLate + TRxEarly ) / 2
|
||||
*
|
||||
* RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
|
||||
* RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
|
||||
*
|
||||
* The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
|
||||
*/
|
||||
/*!
|
||||
* Computes the RX window timeout and offset.
|
||||
*
|
||||
* \param [in] datarate The RX window datarate index to be used.
|
||||
*
|
||||
* \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame.
|
||||
*
|
||||
* \param [in] rxError The system maximum timing error of the receiver in milliseconds.
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset.
|
||||
*
|
||||
* \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
virtual void compute_rx_win_params(int8_t datarate,
|
||||
uint8_t minRxSymbols,
|
||||
uint32_t rxError,
|
||||
RxConfigParams_t *rxConfigParams);
|
||||
virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave,
|
||||
uint32_t frequency = 0);
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [in] txConfig A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] txPower The TX power index set.
|
||||
*
|
||||
* \param [out] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval True, if the configuration was applied successfully.
|
||||
*/
|
||||
virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower,
|
||||
TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR request.
|
||||
*
|
||||
* \param [in] linkAdrReq A pointer to the function parameters.
|
||||
*
|
||||
* \param [out] drOut The datarate applied.
|
||||
*
|
||||
* \param [out] txPowOut The TX power applied.
|
||||
*
|
||||
* \param [out] nbRepOut The number of repetitions to apply.
|
||||
*
|
||||
* \param [out] nbBytesParsed The number of bytes parsed.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq,
|
||||
int8_t* drOut, int8_t* txPowOut,
|
||||
uint8_t* nbRepOut,
|
||||
uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX parameter setup request.
|
||||
*
|
||||
* \param [in] rxParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a new channel request.
|
||||
*
|
||||
* \param [in] newChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup request.
|
||||
*
|
||||
* \param [in] txParamSetupReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall ignore the command.
|
||||
*/
|
||||
virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel request.
|
||||
*
|
||||
* \param [in] dlChannelReq A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [in] alternateDr A pointer to the function parameters.
|
||||
*
|
||||
* \retval The datarate to apply.
|
||||
*/
|
||||
virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [in] calcBackOff A pointer to the function parameters.
|
||||
*/
|
||||
virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and sets the next random available channel.
|
||||
*
|
||||
* \param [in] nextChanParams The parameters for the next channel.
|
||||
*
|
||||
* \param [out] channel The next channel to use for TX.
|
||||
*
|
||||
* \param [out] time The time to wait for the next transmission according to the duty cycle.
|
||||
*
|
||||
* \param [out] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval The function status [1: OK, 0: Unable to find a channel on the current datarate].
|
||||
*/
|
||||
virtual bool set_next_channel(NextChanParams_t* nextChanParams,
|
||||
uint8_t* channel, TimerTime_t* time,
|
||||
TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [in] channelAdd A pointer to the function parameters.
|
||||
*
|
||||
* \retval The status of the operation.
|
||||
*/
|
||||
virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [in] channelRemove A pointer to the function parameters.
|
||||
*
|
||||
* \retval True, if the channel was removed successfully.
|
||||
*/
|
||||
virtual bool remove_channel(ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [in] continuousWave A pointer to the function parameters.
|
||||
*/
|
||||
virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes a new datarate according to the given offset.
|
||||
*
|
||||
* \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [in] dr The current datarate.
|
||||
*
|
||||
* \param [in] drOffset The offset to be applied.
|
||||
*
|
||||
* \retval newDr The computed datarate.
|
||||
*/
|
||||
virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);
|
||||
|
||||
private:
|
||||
int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask );
|
||||
uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx );
|
||||
int8_t limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, int8_t datarate);
|
||||
bool validate_channel_mask(uint16_t* channel_mask);
|
||||
void reenable_500khz_channels(uint16_t mask, uint16_t* channel_mask);
|
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[US915_HYBRID_MAX_NB_CHANNELS];
|
||||
channel_params_t channels[US915_HYBRID_MAX_NB_CHANNELS];
|
||||
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[US915_HYBRID_MAX_NB_BANDS];
|
||||
band_t bands[US915_HYBRID_MAX_NB_BANDS];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
*/
|
||||
uint16_t ChannelsMask[US915_HYBRID_CHANNELS_MASK_SIZE];
|
||||
uint16_t channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels remaining
|
||||
* Previously used channel mask
|
||||
*/
|
||||
uint16_t ChannelsMaskRemaining[US915_HYBRID_CHANNELS_MASK_SIZE];
|
||||
uint16_t current_channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE];
|
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
* LoRaMac default channel mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[US915_HYBRID_CHANNELS_MASK_SIZE];
|
||||
uint16_t default_channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE];
|
||||
};
|
||||
|
||||
#endif /* MBED_OS_LORAPHY_US915HYBRID_H_ */
|
||||
|
|
|
@ -527,7 +527,7 @@
|
|||
/*!
|
||||
* Enumeration of PHY attributes.
|
||||
*/
|
||||
typedef enum ePhyAttribute
|
||||
typedef enum phy_attributes__e
|
||||
{
|
||||
/*!
|
||||
* The minimum RX datarate.
|
||||
|
@ -620,11 +620,11 @@ typedef enum ePhyAttribute
|
|||
/*!
|
||||
* The channels mask.
|
||||
*/
|
||||
PHY_CHANNELS_MASK,
|
||||
PHY_CHANNEL_MASK,
|
||||
/*!
|
||||
* The channels default mask.
|
||||
* The default channel mask.
|
||||
*/
|
||||
PHY_CHANNELS_DEFAULT_MASK,
|
||||
PHY_DEFAULT_CHANNEL_MASK,
|
||||
/*!
|
||||
* The maximum number of supported channels.
|
||||
*/
|
||||
|
@ -633,6 +633,13 @@ typedef enum ePhyAttribute
|
|||
* The channels.
|
||||
*/
|
||||
PHY_CHANNELS,
|
||||
/*!
|
||||
* The PHYs that support dynamic channel plan (non-custom)
|
||||
* support do not let the user add/remove to the channel plan.
|
||||
* The network guides the device for the plan. So only
|
||||
* EU like regions support custom channel planning.
|
||||
*/
|
||||
PHY_CUSTOM_CHANNEL_PLAN_SUPPORT,
|
||||
/*!
|
||||
* The default value of the uplink dwell time.
|
||||
*/
|
||||
|
@ -661,517 +668,481 @@ typedef enum ePhyAttribute
|
|||
* The next lower datarate.
|
||||
*/
|
||||
PHY_NEXT_LOWER_TX_DR
|
||||
}PhyAttribute_t;
|
||||
} phy_attributes_t;
|
||||
|
||||
/*!
|
||||
* Enumeration of initialization types.
|
||||
* Keeps value in response to a call to
|
||||
* get_phy_params() API.
|
||||
*/
|
||||
typedef enum eInitType
|
||||
{
|
||||
/*!
|
||||
* Performs an initialization and overwrites all existing data.
|
||||
*/
|
||||
INIT_TYPE_INIT,
|
||||
/*!
|
||||
* Restores default channels only.
|
||||
*/
|
||||
INIT_TYPE_RESTORE
|
||||
}InitType_t;
|
||||
|
||||
/*!
|
||||
* Selects a given or a default channel mask.
|
||||
*/
|
||||
typedef enum eChannelsMask
|
||||
{
|
||||
/*!
|
||||
* The channels mask.
|
||||
*/
|
||||
CHANNELS_MASK,
|
||||
/*!
|
||||
* The channels default mask.
|
||||
*/
|
||||
CHANNELS_DEFAULT_MASK
|
||||
}ChannelsMask_t;
|
||||
|
||||
/*!
|
||||
* The union for the structure uGetPhyParams.
|
||||
*/
|
||||
typedef union uPhyParam
|
||||
typedef union phy_param_u
|
||||
{
|
||||
/*!
|
||||
* A parameter value.
|
||||
*/
|
||||
uint32_t Value;
|
||||
uint32_t value;
|
||||
/*!
|
||||
* A floating point value.
|
||||
*/
|
||||
float fValue;
|
||||
float f_value;
|
||||
/*!
|
||||
* A pointer to the channels mask.
|
||||
*/
|
||||
uint16_t* ChannelsMask;
|
||||
uint16_t* channel_mask;
|
||||
/*!
|
||||
* A pointer to the channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
}PhyParam_t;
|
||||
channel_params_t* channel_params;
|
||||
} phy_param_t;
|
||||
|
||||
/*!
|
||||
/**
|
||||
* The parameter structure for the function RegionGetPhyParam.
|
||||
*/
|
||||
typedef struct sGetPhyParams
|
||||
typedef struct
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* Set up the parameter to get.
|
||||
*/
|
||||
PhyAttribute_t Attribute;
|
||||
/*!
|
||||
* Datarate.
|
||||
phy_attributes_t attribute;
|
||||
|
||||
/**
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* Uplink dwell time.
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_MIN_TX_DR, PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR.
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
/*!
|
||||
* Downlink dwell time.
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_MIN_RX_DR, PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER.
|
||||
*/
|
||||
uint8_t DownlinkDwellTime;
|
||||
}GetPhyParams_t;
|
||||
int8_t datarate;
|
||||
|
||||
/*!
|
||||
} get_phy_params_t;
|
||||
|
||||
/**
|
||||
* The parameter structure for the function RegionSetBandTxDone.
|
||||
*/
|
||||
typedef struct sSetBandTxDoneParams
|
||||
typedef struct
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The channel to update.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
uint8_t channel;
|
||||
/**
|
||||
* Joined set to true, if the node has joined the network.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
bool joined;
|
||||
/**
|
||||
* The last TX done time.
|
||||
*/
|
||||
TimerTime_t LastTxDoneTime;
|
||||
}SetBandTxDoneParams_t;
|
||||
lorawan_time_t last_tx_done_time;
|
||||
} set_band_txdone_params_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionVerify.
|
||||
/**
|
||||
* The parameter verification structure.
|
||||
*/
|
||||
typedef union uVerifyParams
|
||||
typedef union
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The TX power to verify.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
int8_t tx_power;
|
||||
/**
|
||||
* Set to true, if the duty cycle is enabled, otherwise false.
|
||||
*/
|
||||
bool DutyCycle;
|
||||
/*!
|
||||
bool duty_cycle;
|
||||
/**
|
||||
* The number of join trials.
|
||||
*/
|
||||
uint8_t NbJoinTrials;
|
||||
/*!
|
||||
uint8_t nb_join_trials;
|
||||
/**
|
||||
* The datarate to verify.
|
||||
*/
|
||||
struct sDatarateParams
|
||||
{
|
||||
/*!
|
||||
* The datarate to verify.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* The downlink dwell time.
|
||||
*/
|
||||
uint8_t DownlinkDwellTime;
|
||||
/*!
|
||||
* The uplink dwell time.
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
}DatarateParams;
|
||||
}VerifyParams_t;
|
||||
int8_t datarate;
|
||||
|
||||
/*!
|
||||
} verification_params_t;
|
||||
|
||||
/**
|
||||
* The parameter structure for the function RegionApplyCFList.
|
||||
*/
|
||||
typedef struct sApplyCFListParams
|
||||
typedef struct
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The payload containing the CF list.
|
||||
*/
|
||||
uint8_t* Payload;
|
||||
/*!
|
||||
uint8_t* payload;
|
||||
/**
|
||||
* The size of the payload.
|
||||
*/
|
||||
uint8_t Size;
|
||||
}ApplyCFListParams_t;
|
||||
uint8_t size;
|
||||
} cflist_params_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionChanMaskSet.
|
||||
/**
|
||||
* TX configuration parameters.
|
||||
*/
|
||||
typedef struct sChanMaskSetParams
|
||||
typedef struct
|
||||
{
|
||||
/*!
|
||||
* A pointer to the channels mask which should be set.
|
||||
*/
|
||||
uint16_t* ChannelsMaskIn;
|
||||
/*!
|
||||
* A pointer to the channels mask which should be set.
|
||||
*/
|
||||
ChannelsMask_t ChannelsMaskType;
|
||||
}ChanMaskSetParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionAdrNext.
|
||||
*/
|
||||
typedef struct sAdrNextParams
|
||||
{
|
||||
/*!
|
||||
* Set to true, if the function should update the channels mask.
|
||||
*/
|
||||
bool UpdateChanMask;
|
||||
/*!
|
||||
* Set to true, if ADR is enabled.
|
||||
*/
|
||||
bool AdrEnabled;
|
||||
/*!
|
||||
* The ADR ack counter.
|
||||
*/
|
||||
uint32_t AdrAckCounter;
|
||||
/*!
|
||||
* The datarate used currently.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* The TX power used currently.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
* UplinkDwellTime
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
}AdrNextParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionRxConfig.
|
||||
*/
|
||||
typedef struct sRxConfigParams
|
||||
{
|
||||
/*!
|
||||
* The RX channel.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
* The RX datarate.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* The RX bandwidth.
|
||||
*/
|
||||
uint8_t Bandwidth;
|
||||
/*!
|
||||
* The RX datarate offset.
|
||||
*/
|
||||
int8_t DrOffset;
|
||||
/*!
|
||||
* The RX frequency.
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* The RX window timeout
|
||||
*/
|
||||
uint32_t WindowTimeout;
|
||||
/*!
|
||||
* The RX window offset
|
||||
*/
|
||||
int32_t WindowOffset;
|
||||
/*!
|
||||
* The downlink dwell time.
|
||||
*/
|
||||
uint8_t DownlinkDwellTime;
|
||||
/*!
|
||||
* Set to true, if a repeater is supported.
|
||||
*/
|
||||
bool RepeaterSupport;
|
||||
/*!
|
||||
* Set to true, if RX should be continuous.
|
||||
*/
|
||||
bool RxContinuous;
|
||||
/*!
|
||||
* Sets the RX window. 0: RX window 1, 1: RX window 2.
|
||||
*/
|
||||
bool Window;
|
||||
}RxConfigParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionTxConfig.
|
||||
*/
|
||||
typedef struct sTxConfigParams
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The TX channel.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
uint8_t channel;
|
||||
/**
|
||||
* The TX datarate.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
int8_t datarate;
|
||||
/**
|
||||
* The TX power.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
int8_t tx_power;
|
||||
/**
|
||||
* The Max EIRP, if applicable.
|
||||
*/
|
||||
float MaxEirp;
|
||||
/*!
|
||||
float max_eirp;
|
||||
/**
|
||||
* The antenna gain, if applicable.
|
||||
*/
|
||||
float AntennaGain;
|
||||
/*!
|
||||
float antenna_gain;
|
||||
/**
|
||||
* The frame length to set up.
|
||||
*/
|
||||
uint16_t PktLen;
|
||||
}TxConfigParams_t;
|
||||
uint16_t pkt_len;
|
||||
} tx_config_params_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionLinkAdrReq.
|
||||
/**
|
||||
* This structure contains parameters for ADR request coming from
|
||||
* network server.
|
||||
*/
|
||||
typedef struct sLinkAdrReqParams
|
||||
typedef struct
|
||||
{
|
||||
/*!
|
||||
* A pointer to the payload containing the MAC commands.
|
||||
*/
|
||||
uint8_t* Payload;
|
||||
uint8_t* payload;
|
||||
/*!
|
||||
* The size of the payload.
|
||||
*/
|
||||
uint8_t PayloadSize;
|
||||
uint8_t payload_size;
|
||||
/*!
|
||||
* The uplink dwell time.
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
uint8_t ul_dwell_time;
|
||||
/*!
|
||||
* Set to true, if ADR is enabled.
|
||||
*/
|
||||
bool AdrEnabled;
|
||||
bool adr_enabled;
|
||||
/*!
|
||||
* The current datarate.
|
||||
*/
|
||||
int8_t CurrentDatarate;
|
||||
int8_t current_datarate;
|
||||
/*!
|
||||
* The current TX power.
|
||||
*/
|
||||
int8_t CurrentTxPower;
|
||||
int8_t current_tx_power;
|
||||
/*!
|
||||
* The current number of repetitions.
|
||||
*/
|
||||
uint8_t CurrentNbRep;
|
||||
}LinkAdrReqParams_t;
|
||||
uint8_t current_nb_rep;
|
||||
} adr_req_params_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionRxParamSetupReq.
|
||||
/**
|
||||
* Structure containing data for local ADR settings
|
||||
*/
|
||||
typedef struct sRxParamSetupReqParams
|
||||
typedef struct link_adr_params_s
|
||||
{
|
||||
/**
|
||||
* The number of repetitions.
|
||||
*/
|
||||
uint8_t nb_rep;
|
||||
/**
|
||||
* Datarate.
|
||||
*/
|
||||
int8_t datarate;
|
||||
/**
|
||||
* TX power.
|
||||
*/
|
||||
int8_t tx_power;
|
||||
/**
|
||||
* Channels mask control field.
|
||||
*/
|
||||
uint8_t ch_mask_ctrl;
|
||||
/**
|
||||
* Channels mask field.
|
||||
*/
|
||||
uint16_t channel_mask;
|
||||
} link_adr_params_t;
|
||||
|
||||
/**
|
||||
* Structure used to store ADR values received from network
|
||||
* for verification (legality) purposes.
|
||||
*/
|
||||
typedef struct verify_adr_params_s
|
||||
{
|
||||
/*!
|
||||
* The current status of the AdrLinkRequest.
|
||||
*/
|
||||
uint8_t status;
|
||||
/*!
|
||||
* Set to true, if ADR is enabled.
|
||||
*/
|
||||
bool adr_enabled;
|
||||
/*!
|
||||
* The datarate the AdrLinkRequest wants to set.
|
||||
*/
|
||||
int8_t datarate;
|
||||
/*!
|
||||
* The TX power the AdrLinkRequest wants to set.
|
||||
*/
|
||||
int8_t tx_power;
|
||||
/*!
|
||||
* The number of repetitions the AdrLinkRequest wants to set.
|
||||
*/
|
||||
uint8_t nb_rep;
|
||||
/*!
|
||||
* The current datarate the node is using.
|
||||
*/
|
||||
int8_t current_datarate;
|
||||
/*!
|
||||
* The current TX power the node is using.
|
||||
*/
|
||||
int8_t current_tx_power;
|
||||
/*!
|
||||
* The current number of repetitions the node is using.
|
||||
*/
|
||||
int8_t current_nb_rep;
|
||||
|
||||
/*!
|
||||
* A pointer to the first element of the channels mask.
|
||||
*/
|
||||
uint16_t* channel_mask;
|
||||
} verify_adr_params_t;
|
||||
|
||||
/**
|
||||
* Contains rx parameter setup request coming from
|
||||
* network server.
|
||||
*/
|
||||
typedef struct rx_param_setup_req_s
|
||||
{
|
||||
/**
|
||||
* The datarate to set up.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
int8_t datarate;
|
||||
/**
|
||||
* The datarate offset.
|
||||
*/
|
||||
int8_t DrOffset;
|
||||
/*!
|
||||
int8_t dr_offset;
|
||||
/**
|
||||
* The frequency to set up.
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
}RxParamSetupReqParams_t;
|
||||
uint32_t frequency;
|
||||
} rx_param_setup_req_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionNewChannelReq.
|
||||
/**
|
||||
* Contains tx parameter setup request coming from
|
||||
* network server.
|
||||
*/
|
||||
typedef struct sNewChannelReqParams
|
||||
typedef struct tx_param_setup_req_s
|
||||
{
|
||||
/*!
|
||||
* A pointer to the new channels.
|
||||
*/
|
||||
ChannelParams_t* NewChannel;
|
||||
/*!
|
||||
* The channel ID.
|
||||
*/
|
||||
int8_t ChannelId;
|
||||
}NewChannelReqParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionTxParamSetupReq.
|
||||
*/
|
||||
typedef struct sTxParamSetupReqParams
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The uplink dwell time.
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
/*!
|
||||
uint8_t ul_dwell_time;
|
||||
/**
|
||||
* The downlink dwell time.
|
||||
*/
|
||||
uint8_t DownlinkDwellTime;
|
||||
/*!
|
||||
uint8_t dl_dwell_time;
|
||||
/**
|
||||
* The max EIRP.
|
||||
*/
|
||||
uint8_t MaxEirp;
|
||||
}TxParamSetupReqParams_t;
|
||||
uint8_t max_eirp;
|
||||
} tx_param_setup_req_t;
|
||||
|
||||
/*!
|
||||
/**
|
||||
* A structure that holds new channel parameters coming
|
||||
* from the network server.
|
||||
*/
|
||||
typedef struct new_channel_req_params_s
|
||||
{
|
||||
/**
|
||||
* A pointer to the new channel's parameters.
|
||||
*/
|
||||
channel_params_t* new_channel;
|
||||
/**
|
||||
* The channel ID.
|
||||
*/
|
||||
int8_t channel_id;
|
||||
|
||||
} new_channel_req_params_t;
|
||||
|
||||
/**
|
||||
* The parameter structure for the function RegionDlChannelReq.
|
||||
*/
|
||||
typedef struct sDlChannelReqParams
|
||||
typedef struct dl_channel_req_params_s
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The channel ID to add the frequency.
|
||||
*/
|
||||
uint8_t ChannelId;
|
||||
/*!
|
||||
uint8_t channel_id;
|
||||
/**
|
||||
* The alternative frequency for the Rx1 window.
|
||||
*/
|
||||
uint32_t Rx1Frequency;
|
||||
}DlChannelReqParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionAlternateDr.
|
||||
*/
|
||||
typedef struct sAlternateDrParams
|
||||
{
|
||||
/*!
|
||||
* The number of trials.
|
||||
*/
|
||||
uint16_t NbTrials;
|
||||
}AlternateDrParams_t;
|
||||
uint32_t rx1_frequency;
|
||||
} dl_channel_req_params_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionCalcBackOff.
|
||||
*/
|
||||
typedef struct sCalcBackOffParams
|
||||
typedef struct backoff_params_s
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* Set to true, if the node has already joined a network, otherwise false.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
* Joined set to true, if the last uplink was a join request.
|
||||
bool joined;
|
||||
/**
|
||||
* set to true, if the last uplink was a join request.
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
bool last_tx_was_join_req;
|
||||
/**
|
||||
* Set to true, if the duty cycle is enabled, otherwise false.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
bool dc_enabled;
|
||||
/**
|
||||
* The current channel index.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
uint8_t channel;
|
||||
/**
|
||||
* Elapsed time since the start of the node.
|
||||
*/
|
||||
TimerTime_t ElapsedTime;
|
||||
/*!
|
||||
lorawan_time_t elapsed_time;
|
||||
/**
|
||||
* Time-on-air of the last transmission.
|
||||
*/
|
||||
TimerTime_t TxTimeOnAir;
|
||||
}CalcBackOffParams_t;
|
||||
lorawan_time_t tx_toa;
|
||||
|
||||
/*!
|
||||
} backoff_params_t;
|
||||
|
||||
/**
|
||||
* The parameter structure for the function RegionNextChannel.
|
||||
*/
|
||||
typedef struct sNextChanParams
|
||||
typedef struct channel_selection_params_s
|
||||
{
|
||||
/*!
|
||||
/**
|
||||
* The aggregated time-off time.
|
||||
*/
|
||||
TimerTime_t AggrTimeOff;
|
||||
/*!
|
||||
lorawan_time_t aggregate_timeoff;
|
||||
/**
|
||||
* The time of the last aggregated TX.
|
||||
*/
|
||||
TimerTime_t LastAggrTx;
|
||||
/*!
|
||||
lorawan_time_t last_aggregate_tx_time;
|
||||
/**
|
||||
* The current datarate.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
int8_t current_datarate;
|
||||
/**
|
||||
* Set to true, if the node has already joined a network, otherwise false.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
bool joined;
|
||||
/**
|
||||
* Set to true, if the duty cycle is enabled, otherwise false.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
}NextChanParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionChannelsAdd.
|
||||
*/
|
||||
typedef struct sChannelAddParams
|
||||
{
|
||||
/*!
|
||||
* A pointer to the new channel to add.
|
||||
*/
|
||||
ChannelParams_t* NewChannel;
|
||||
/*!
|
||||
* The channel ID to add.
|
||||
*/
|
||||
uint8_t ChannelId;
|
||||
}ChannelAddParams_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionChannelsRemove.
|
||||
*/
|
||||
typedef struct sChannelRemoveParams
|
||||
{
|
||||
/*!
|
||||
* The channel ID to remove.
|
||||
*/
|
||||
uint8_t ChannelId;
|
||||
}ChannelRemoveParams_t;
|
||||
bool dc_enabled;
|
||||
} channel_selection_params_t;
|
||||
|
||||
/*!
|
||||
* The parameter structure for the function RegionContinuousWave.
|
||||
*/
|
||||
typedef struct sContinuousWaveParams
|
||||
typedef struct continuous_wave_mode_params_s
|
||||
{
|
||||
/*!
|
||||
* The current channel index.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
uint8_t channel;
|
||||
/*!
|
||||
* The datarate. Used to limit the TX power.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
int8_t datarate;
|
||||
/*!
|
||||
* The TX power to set up.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
int8_t tx_power;
|
||||
/*!
|
||||
* The max EIRP, if applicable.
|
||||
*/
|
||||
float MaxEirp;
|
||||
float max_eirp;
|
||||
/*!
|
||||
* The antenna gain, if applicable.
|
||||
*/
|
||||
float AntennaGain;
|
||||
float antenna_gain;
|
||||
/*!
|
||||
* Specifies the time the radio will stay in CW mode.
|
||||
*/
|
||||
uint16_t Timeout;
|
||||
}ContinuousWaveParams_t;
|
||||
uint16_t timeout;
|
||||
} cw_mode_params_t;
|
||||
|
||||
typedef struct {
|
||||
void *table;
|
||||
uint8_t size;
|
||||
} loraphy_table_t;
|
||||
|
||||
typedef struct {
|
||||
channel_params_t *channel_list;
|
||||
uint8_t channel_list_size;
|
||||
|
||||
uint16_t *mask;
|
||||
uint16_t *default_mask;
|
||||
uint8_t mask_size;
|
||||
|
||||
} loraphy_channels_t;
|
||||
|
||||
typedef struct {
|
||||
bool duty_cycle_enabled;
|
||||
bool accept_tx_param_setup_req;
|
||||
bool fsk_supported;
|
||||
bool cflist_supported;
|
||||
bool custom_channelplans_supported;
|
||||
bool dl_channel_req_supported;
|
||||
|
||||
uint8_t default_channel_cnt;
|
||||
uint8_t cflist_channel_cnt;
|
||||
uint8_t max_channel_cnt;
|
||||
uint8_t min_tx_power;
|
||||
uint8_t max_tx_power;
|
||||
uint8_t default_tx_power;
|
||||
uint8_t adr_ack_limit;
|
||||
uint8_t adr_ack_delay;
|
||||
|
||||
uint8_t min_tx_datarate;
|
||||
uint8_t max_tx_datarate;
|
||||
uint8_t min_rx_datarate;
|
||||
uint8_t max_rx_datarate;
|
||||
uint8_t default_datarate;
|
||||
uint8_t default_max_datarate;
|
||||
uint8_t min_rx1_dr_offset;
|
||||
uint8_t max_rx1_dr_offset;
|
||||
uint8_t default_rx1_dr_offset;
|
||||
uint8_t dwell_limit_datarate;
|
||||
|
||||
uint16_t max_rx_window;
|
||||
uint16_t recv_delay1;
|
||||
uint16_t recv_delay2;
|
||||
uint16_t join_accept_delay1;
|
||||
uint16_t join_accept_delay2;
|
||||
uint16_t join_channel_mask;
|
||||
uint16_t max_fcnt_gap;
|
||||
uint16_t ack_timeout;
|
||||
uint16_t ack_timeout_rnd;
|
||||
|
||||
float default_max_eirp;
|
||||
float default_antenna_gain;
|
||||
|
||||
uint8_t rx_window2_datarate;
|
||||
uint32_t rx_window2_frequency;
|
||||
|
||||
loraphy_table_t bands;
|
||||
loraphy_table_t bandwidths;
|
||||
loraphy_table_t datarates;
|
||||
loraphy_table_t payloads;
|
||||
loraphy_table_t payloads_with_repeater;
|
||||
|
||||
loraphy_channels_t channels;
|
||||
|
||||
|
||||
unsigned ul_dwell_time_setting : 1;
|
||||
unsigned dl_dwell_time_setting : 1;
|
||||
|
||||
} loraphy_params_t;
|
||||
|
||||
|
||||
#endif /* MBED_OS_LORA_PHY_DATASTRUCTURES_ */
|
||||
|
|
|
@ -2,16 +2,7 @@
|
|||
"name": "lora",
|
||||
"config": {
|
||||
"phy": {
|
||||
"help": ["Select LoRa PHY layer. See README.md for more information. Default: 0 = LORA_PHY_EU868",
|
||||
" 1 = LORA_PHY_AS923",
|
||||
" 2 = LORA_PHY_AU915",
|
||||
" 3 = LORA_PHY_CN470",
|
||||
" 4 = LORA_PHY_CN779",
|
||||
" 5 = LORA_PHY_EU433",
|
||||
" 6 = LORA_PHY_IN865",
|
||||
" 7 = LORA_PHY_KR920",
|
||||
" 8 = LORA_PHY_US915",
|
||||
" 9 = LORA_PHY_US915_HYBRID"],
|
||||
"help": "LoRa PHY region. 0 = EU868 (default), 1 = AS923, 2 = AU915, 3 = CN470, 4 = CN779, 5 = EU433, 6 = IN865, 7 = KR920, 8 = US915, 9 = US915_HYBRID",
|
||||
"value": "0"
|
||||
},
|
||||
"over-the-air-activation": {
|
||||
|
@ -19,8 +10,8 @@
|
|||
"value": true
|
||||
},
|
||||
"nb-trials": {
|
||||
"help": "Indicates how many times join can be tried, default: 8",
|
||||
"value": 8
|
||||
"help": "Indicates how many times join can be tried, default: 12",
|
||||
"value": 12
|
||||
},
|
||||
"device-eui": {
|
||||
"help": "Mote device IEEE EUI",
|
||||
|
@ -34,10 +25,6 @@
|
|||
"help": "AES encryption/decryption cipher application key",
|
||||
"value": "{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}"
|
||||
},
|
||||
"network-id": {
|
||||
"help": "Current network ID",
|
||||
"value": 0
|
||||
},
|
||||
"device-address": {
|
||||
"help": "Device address on the network",
|
||||
"value": "0x00000000"
|
||||
|
@ -67,12 +54,12 @@
|
|||
"value": true
|
||||
},
|
||||
"duty-cycle-on": {
|
||||
"help": "Enables/disables duty cycling. NOTE: Disable only for testing. Mandatory in many regions.",
|
||||
"value": true
|
||||
"help": "Enables/disables duty cycling. NOTE: Disable only for testing. Mandatory in many regions.",
|
||||
"value": true
|
||||
},
|
||||
"lbt-on": {
|
||||
"help": "Enables/disables LBT. NOTE: [This feature is not yet integrated].",
|
||||
"value": false
|
||||
"help": "Enables/disables LBT. NOTE: [This feature is not yet integrated].",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,41 +20,45 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
|
||||
#include "lorawan/system/LoRaWANTimer.h"
|
||||
|
||||
static events::EventQueue *_queue = NULL;
|
||||
LoRaWANTimeHandler::LoRaWANTimeHandler()
|
||||
: _queue(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void TimerTimeCounterInit(events::EventQueue *queue)
|
||||
LoRaWANTimeHandler::~LoRaWANTimeHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void LoRaWANTimeHandler::activate_timer_subsystem(events::EventQueue *queue)
|
||||
{
|
||||
_queue = queue;
|
||||
}
|
||||
|
||||
TimerTime_t TimerGetCurrentTime( void )
|
||||
lorawan_time_t LoRaWANTimeHandler::get_current_time( void )
|
||||
{
|
||||
const uint32_t current_time = _queue->tick();
|
||||
return (TimerTime_t)current_time;
|
||||
return (lorawan_time_t)current_time;
|
||||
}
|
||||
|
||||
TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime )
|
||||
lorawan_time_t LoRaWANTimeHandler::get_elapsed_time(lorawan_time_t saved_time)
|
||||
{
|
||||
return TimerGetCurrentTime() - savedTime;
|
||||
return get_current_time() - saved_time;
|
||||
}
|
||||
|
||||
void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) )
|
||||
void LoRaWANTimeHandler::init(timer_event_t &obj, mbed::Callback<void()> callback)
|
||||
{
|
||||
obj->value = 0;
|
||||
obj->Callback = callback;
|
||||
obj.callback = callback;
|
||||
obj.timer_id = 0;
|
||||
}
|
||||
|
||||
void TimerStart( TimerEvent_t *obj )
|
||||
void LoRaWANTimeHandler::start(timer_event_t &obj, const uint32_t timeout)
|
||||
{
|
||||
obj->Timer.get()->attach_us( mbed::callback( obj->Callback ), obj->value * 1000 );
|
||||
obj.timer_id = _queue->call_in(timeout, obj.callback);
|
||||
MBED_ASSERT(obj.timer_id != 0);
|
||||
}
|
||||
|
||||
void TimerStop( TimerEvent_t *obj )
|
||||
void LoRaWANTimeHandler::stop(timer_event_t &obj)
|
||||
{
|
||||
obj->Timer.get()->detach( );
|
||||
}
|
||||
|
||||
void TimerSetValue( TimerEvent_t *obj, uint32_t value )
|
||||
{
|
||||
obj->value = value;
|
||||
_queue->cancel(obj.timer_id);
|
||||
obj.timer_id = 0;
|
||||
}
|
||||
|
|
|
@ -21,92 +21,63 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
#ifndef MBED_LORAWAN_SYS_TIMER_H__
|
||||
#define MBED_LORAWAN_SYS_TIMER_H__
|
||||
|
||||
#include "drivers/Timer.h"
|
||||
#include "drivers/Ticker.h"
|
||||
#include <stdint.h>
|
||||
#include "lorawan/system/lorawan_data_structures.h"
|
||||
#include "events/EventQueue.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
|
||||
/*!
|
||||
* \brief Timer object description
|
||||
*/
|
||||
typedef struct TimerEvent_s
|
||||
class LoRaWANTimeHandler
|
||||
{
|
||||
uint32_t value;
|
||||
void ( *Callback )( void );
|
||||
SingletonPtr<mbed::Ticker> Timer;
|
||||
}TimerEvent_t;
|
||||
public:
|
||||
LoRaWANTimeHandler();
|
||||
~LoRaWANTimeHandler();
|
||||
|
||||
/*!
|
||||
* \brief Initializes the timer object.
|
||||
*
|
||||
* \remark The TimerSetValue function must be called before starting the timer.
|
||||
* This function initializes the timestamp and reloads the value at 0.
|
||||
*
|
||||
* \param [in] obj The structure containing the timer object parameters.
|
||||
* \param [in] callback The function callback called at the end of the timeout.
|
||||
*/
|
||||
void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) );
|
||||
/** Activates the timer subsystem.
|
||||
*
|
||||
* Embeds EventQueue object to timer subsystem which is subsequently
|
||||
* used to extract timer information.
|
||||
*
|
||||
* @param [in] queue Handle to EventQueue object
|
||||
*/
|
||||
void activate_timer_subsystem(events::EventQueue *queue);
|
||||
|
||||
/*!
|
||||
* \brief Starts and adds the timer object to the list of timer events.
|
||||
*
|
||||
* \param [in] obj The structure containing the timer object parameters.
|
||||
*/
|
||||
void TimerStart( TimerEvent_t *obj );
|
||||
/** Read the current time.
|
||||
*
|
||||
* @return time The current time.
|
||||
*/
|
||||
lorawan_time_t get_current_time(void);
|
||||
|
||||
/*!
|
||||
* \brief Stops and removes the timer object from the list of timer events.
|
||||
*
|
||||
* \param [in] obj The structure containing the timer object parameters.
|
||||
*/
|
||||
void TimerStop( TimerEvent_t *obj );
|
||||
/** Return the time elapsed since a fixed moment in time.
|
||||
*
|
||||
* @param [in] saved_time The fixed moment in time.
|
||||
* @return time The elapsed time.
|
||||
*/
|
||||
lorawan_time_t get_elapsed_time(lorawan_time_t saved_time);
|
||||
|
||||
/*!
|
||||
* \brief Resets the timer object.
|
||||
*
|
||||
* \param [in] obj The structure containing the timer object parameters.
|
||||
*/
|
||||
void TimerReset( TimerEvent_t *obj );
|
||||
/** Initializes the timer object.
|
||||
*
|
||||
* @remark The TimerSetValue function must be called before starting the timer.
|
||||
* This function initializes the time-stamp and reloads the value at 0.
|
||||
*
|
||||
* @param [in] obj The structure containing the timer object parameters.
|
||||
* @param [in] callback The function callback called at the end of the timeout.
|
||||
*/
|
||||
void init(timer_event_t &obj, mbed::Callback<void()> callback);
|
||||
|
||||
/*!
|
||||
* \brief Set a new timeout value.
|
||||
*
|
||||
* \param [in] obj The structure containing the timer object parameters.
|
||||
* \param [in] value The new timeout value.
|
||||
*/
|
||||
void TimerSetValue( TimerEvent_t *obj, uint32_t value );
|
||||
/** Starts and adds the timer object to the list of timer events.
|
||||
*
|
||||
* @param [in] obj The structure containing the timer object parameters.
|
||||
* @param [in] timeout The new timeout value.
|
||||
*/
|
||||
void start(timer_event_t &obj, const uint32_t timeout);
|
||||
|
||||
/*!
|
||||
* \brief Initializes the timer used to get the current time.
|
||||
*
|
||||
* \remark The current time corresponds to the time since system startup.
|
||||
*
|
||||
* \param [in] queue Handle to EventQueue object
|
||||
*/
|
||||
void TimerTimeCounterInit(events::EventQueue *queue);
|
||||
/** Stops and removes the timer object from the list of timer events.
|
||||
*
|
||||
* @param [in] obj The structure containing the timer object parameters.
|
||||
*/
|
||||
void stop(timer_event_t &obj);
|
||||
|
||||
/*!
|
||||
* \brief Read the current time.
|
||||
*
|
||||
* \retval time The current time.
|
||||
*/
|
||||
TimerTime_t TimerGetCurrentTime( void );
|
||||
|
||||
/*!
|
||||
* \brief Return the time elapsed since a fixed moment in time.
|
||||
*
|
||||
* \param [in] savedTime The fixed moment in time.
|
||||
* \retval time The elapsed time.
|
||||
*/
|
||||
TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime );
|
||||
|
||||
/*!
|
||||
* \brief Return the time elapsed since a fixed moment in time.
|
||||
*
|
||||
* \param [in] eventInFuture The fixed moment in the future.
|
||||
* \retval time The difference between now and a future event.
|
||||
*/
|
||||
TimerTime_t TimerGetFutureTime( TimerTime_t eventInFuture );
|
||||
private:
|
||||
events::EventQueue *_queue;
|
||||
};
|
||||
|
||||
#endif // MBED_LORAWAN_SYS_TIMER_H__
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue