Merge pull request #6059 from hasnainvirk/pr_branch

Enabling LoRaWAN technology in Mbed-OS 5.8
pull/6087/head
Cruz Monrreal 2018-02-13 14:15:03 -06:00 committed by GitHub
commit 213d2b649e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 9475 additions and 18549 deletions

View File

@ -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;
/**

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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

View File

@ -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 &params);
lorawan_status_t join_request_by_otaa(const lorawan_connect_t &params);
/** 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 &params);
lorawan_status_t activation_by_personalization(const lorawan_connect_t &params);
/** 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

View File

@ -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__

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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,
&params->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,
&params->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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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
}
}
}

View File

@ -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;
}

View File

@ -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