Merge pull request #6411 from AnttiKauppila/stack_refactoring

Stack refactoring
pull/6544/head
Cruz Monrreal 2018-04-04 10:26:55 -05:00 committed by GitHub
commit 75cb4d7512
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 1742 additions and 3397 deletions

View File

@ -331,6 +331,18 @@ public:
* callbacks.
*/
virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0;
/** Change device class
*
* Change current device class.
*
* @param device_class The device class
*
* @return LORAWAN_STATUS_OK on success,
* LORAWAN_STATUS_UNSUPPORTED is requested class is not supported,
* or other negative error code if request failed.
*/
virtual lorawan_status_t set_device_class(device_class_t device_class) = 0;
};
#endif /* LORAWAN_BASE_H_ */

View File

@ -28,14 +28,9 @@ inline LoRaWANStack& stk_obj()
return LoRaWANStack::get_lorawan_stack();
}
LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio) : _link_check_requested(false)
LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio)
{
// Pass mac_handlers to radio to the radio driver after
// binding radio driver to PHY layer
radio_events_t *events = stk_obj().bind_radio_driver(radio);
radio.lock();
radio.init_radio(events);
radio.unlock();
stk_obj().bind_radio_driver(radio);
}
LoRaWANInterface::~LoRaWANInterface()
@ -44,71 +39,17 @@ LoRaWANInterface::~LoRaWANInterface()
lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
{
if(!queue) {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
return stk_obj().initialize_mac_layer(queue);
}
lorawan_status_t LoRaWANInterface::connect()
{
// connection attempt without parameters.
// System tries to look for configuration in mbed_lib.json that can be
// overridden by mbed_app.json. However, if none of the json files are
// available (highly unlikely), we still fallback to some default parameters.
// Check lorawan_data_structure for fallback defaults.
lorawan_connect_t connection_params;
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
*/
connection_params.connect_type = LORAWAN_CONNECTION_OTAA;
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 = MBED_CONF_LORA_NB_TRIALS;
return connect(connection_params);
} else {
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);
/**
*
* ABP connection
*/
connection_params.connect_type = LORAWAN_CONNECTION_ABP;
connection_params.connection_u.abp.nwk_id = nwk_id;
connection_params.connection_u.abp.dev_addr = dev_addr;
connection_params.connection_u.abp.nwk_skey = nwk_skey;
connection_params.connection_u.abp.app_skey = app_skey;
return connect(connection_params);
}
return stk_obj().connect();
}
lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
{
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 LORAWAN_STATUS_PARAMETER_INVALID;
}
return mac_status;
return stk_obj().connect(connect);
}
lorawan_status_t LoRaWANInterface::disconnect()
@ -118,13 +59,12 @@ lorawan_status_t LoRaWANInterface::disconnect()
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;
stk_obj().remove_link_check_request();
}
lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
@ -170,37 +110,22 @@ lorawan_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();
}
return stk_obj().handle_tx(port, data, length, flags);
if (data) {
return stk_obj().handle_tx(port, data, length, flags);
} else {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
}
int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length,
int flags)
{
if (data && length > 0) {
return stk_obj().handle_rx(port, data, length, flags);
} else {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
return stk_obj().handle_rx(port, data, length, flags);
}
lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
{
{
return stk_obj().set_lora_callbacks(callbacks);
}
if (!callbacks || !callbacks->events) {
// Event Callback is mandatory
return LORAWAN_STATUS_PARAMETER_INVALID;
}
stk_obj().set_lora_callbacks(callbacks);
return LORAWAN_STATUS_OK;
}
lorawan_status_t LoRaWANInterface::set_device_class(const device_class_t device_class)
{
return stk_obj().set_device_class(device_class);
}

View File

@ -429,8 +429,17 @@ public:
*/
virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks);
private:
bool _link_check_requested;
/** Change device class
*
* Change current device class.
*
* @param device_class The device class
*
* @return LORAWAN_STATUS_OK on success,
* LORAWAN_STATUS_UNSUPPORTED is requested class is not supported,
* or other negative error code if request failed.
*/
virtual lorawan_status_t set_device_class(const device_class_t device_class);
};
#endif /* LORAWANINTERFACE_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -35,42 +35,6 @@ 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.
*/
@ -103,15 +67,90 @@ public:
* MAC layer is totally detached from the PHY layer so the stack layer
* needs to play the role of an arbitrator. This API gets a radio driver
* object from the application (via LoRaWANInterface), binds it to the PHY
* layer and returns MAC layer callback handles which the radio driver will
* layer and initialises radio callback handles which the radio driver will
* use in order to report events.
*
* @param radio LoRaRadio object, i.e., the radio driver
*
* @return A list of callbacks from MAC layer that needs to
* be passed to radio driver
*/
radio_events_t *bind_radio_driver(LoRaRadio& radio);
void bind_radio_driver(LoRaRadio& radio);
/** Connect OTAA or ABP using Mbed-OS config system
*
* Connect by Over The Air Activation or Activation By Personalization.
* You need to configure the connection properly via the Mbed OS configuration
* system.
*
* 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
* all user-configured channels except the Join/Default channels. A CF-List can
* configure a maximum of five channels other than the default channels.
*
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
* By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions
* on these channels are severe and you may experience long delays or even failures in the confirmed traffic.
* If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only.
*
* **NOTES ON RECONNECTION:**
* Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
* memory storage. Therefore, the state and frame counters cannot be restored after
* a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
* protocol, the state and frame counters are saved. Connecting again would try to
* restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
* to zero for OTAA and a new Join request lets the network server know
* that the counters need a reset. The same is said about the ABP but there
* is no way to convey this information to the network server. For a network
* server, an ABP device is always connected. That's why storing the frame counters
* is important, at least for ABP. That's why we try to restore frame counters from
* session information after a disconnection.
*
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS
* on success, or a negative error code on failure.
*/
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 (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
* all user-configured channels except the Join/Default channels. A CF-List can
* configure a maximum of five channels other than the default channels.
*
* In case of ABP, the CONNECTED event is posted before the call to `connect()` returns.
* To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection.
* By default, the PHY layers configure only the mandatory Join
* channels. The retransmission back-off restrictions on these channels
* are severe and you may experience long delays or even
* failures in the confirmed traffic. If you add more channels, the aggregated duty
* cycle becomes much more relaxed as compared to the Join (default) channels only.
*
* **NOTES ON RECONNECTION:**
* Currently, the Mbed OS LoRaWAN implementation does not support non-volatile
* memory storage. Therefore, the state and frame counters cannot be restored after
* a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN
* protocol, the state and frame counters are saved. Connecting again would try to
* restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset
* to zero for OTAA and a new Join request lets the network server know
* that the counters need a reset. The same is said about the ABP but there
* is no way to convey this information to the network server. For a network
* server, an ABP device is always connected. That's why storing the frame counters
* is important, at least for ABP. That's why we try to restore frame counters from
* session information after a disconnection.
*
* @param connect Options for an end device connection to the gateway.
*
* @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS,
* a negative error code on failure.
*/
lorawan_status_t connect(const lorawan_connect_t &connect);
/** End device initialization.
* @param queue A pointer to an EventQueue passed from the application.
@ -122,8 +161,9 @@ public:
/** Sets all callbacks for the application.
*
* @param callbacks A pointer to the structure carrying callbacks.
* @return LORAWAN_STATUS_OK on success, a negative error code on failure.
*/
void set_lora_callbacks(lorawan_app_callbacks_t *callbacks);
lorawan_status_t set_lora_callbacks(lorawan_app_callbacks_t *callbacks);
/** Adds channels to use.
*
@ -209,39 +249,6 @@ public:
*/
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 lorawan_dev_commission_t &commission_data);
/** End device OTAA join.
*
* Based on the LoRaWAN standard 1.0.2.
* Join the network using the Over The Air Activation (OTAA) procedure.
*
* @param params The `lorawan_connect_t` type structure.
*
* @return LORAWAN_STATUS_OK or
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
* or a negative error code on failure.
*/
lorawan_status_t join_request_by_otaa(const lorawan_connect_t &params);
/** End device ABP join.
*
* Based on the LoRaWAN standard 1.0.2.
* Join the network using the Activation By Personalization (ABP) procedure.
*
* @param params The `lorawan_connect_t` type structure.
*
* @return LORAWAN_STATUS_OK or
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
* or a negative error code on failure.
*/
lorawan_status_t activation_by_personalization(const lorawan_connect_t &params);
/** Send message to gateway
*
* @param port The application port number. Port numbers 0 and 224
@ -271,13 +278,15 @@ public:
* MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are
* mutually exclusive.
*
* @param null_allowed Internal use only. Needed for sending empty packet
* having CONFIRMED bit on.
*
* @return The number of bytes sent, or
* 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,
uint16_t length, uint8_t flags);
uint16_t length, uint8_t flags, bool null_allowed = false);
/** Receives a message from the Network Server.
*
@ -337,6 +346,13 @@ public:
*/
lorawan_status_t set_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.
*/
void remove_link_check_request();
/** Shuts down the LoRaWAN protocol.
*
* In response to the user call for disconnection, the stack shuts down itself.
@ -345,6 +361,18 @@ public:
*/
lorawan_status_t shutdown();
/** Change device class
*
* Change current device class.
*
* @param device_class The device class
*
* @return LORAWAN_STATUS_OK on success,
* LORAWAN_STATUS_UNSUPPORTED is requested class is not supported,
* or other negative error code if request failed.
*/
lorawan_status_t set_device_class(const device_class_t& device_class);
private:
LoRaWANStack();
~LoRaWANStack();
@ -356,22 +384,8 @@ private:
/**
* State machine for stack controller layer.
* Needs to be wriggled for every state change
*/
lorawan_status_t lora_state_machine();
/**
* Sets the current state of the device.
* Every call to set_device_state() should precede with
* a call to lora_state_machine() in order to take the state change
* in effect.
*/
void set_device_state(device_states_t new_state);
/**
* Hands over the packet to Mac layer by posting an MCPS request.
*/
lorawan_status_t send_frame_to_mac();
lorawan_status_t lora_state_machine(device_states_t new_state);
/**
* Callback function for MLME indication. Mac layer calls this function once
@ -380,13 +394,6 @@ private:
*/
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.
*/
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,
@ -394,13 +401,6 @@ private:
*/
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.
*/
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
* MCPS request. We take appropriate actions in response to the confirmation,
@ -417,54 +417,54 @@ private:
*/
void mcps_indication_handler(loramac_mcps_indication_t *mcps_indication);
/**
* Sets a MIB request, i.e., update a particular parameter etc.
*/
lorawan_status_t mib_set_request(loramac_mib_req_confirm_t *mib_set_params);
/**
* Requests the MIB to inquire about a particular parameter.
*/
lorawan_status_t mib_get_request(loramac_mib_req_confirm_t *mib_get_params);
/**
* Sets up user application port
*/
lorawan_status_t set_application_port(uint8_t port);
/**
* Helper function to figure out if the user defined data size is possible
* to send or not. The allowed size for transmission depends on the current
* data rate set for the channel. If its not possible to send user defined
* packet size, this method returns the maximum possible size at the moment,
* otherwise the user defined size is returned which means all of user data
* can be sent.
/** End device OTAA join.
*
* Based on the LoRaWAN standard 1.0.2.
* Join the network using the Over The Air Activation (OTAA) procedure.
*
* @param params The `lorawan_connect_t` type structure.
*
* @return LORAWAN_STATUS_OK or
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
* or a negative error code on failure.
*/
uint16_t check_possible_tx_size(uint16_t size);
lorawan_status_t join_request_by_otaa(const lorawan_connect_t &params);
/** End device ABP join.
*
* Based on the LoRaWAN standard 1.0.2.
* Join the network using the Activation By Personalization (ABP) procedure.
*
* @param params The `lorawan_connect_t` type structure.
*
* @return LORAWAN_STATUS_OK or
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
* or a negative error code on failure.
*/
lorawan_status_t activation_by_personalization(const lorawan_connect_t &params);
private:
LoRaWANTimeHandler _lora_time;
LoRaMac _loramac;
LoRaPHY_region _lora_phy;
loramac_primitives_t LoRaMacPrimitives;
device_states_t _device_current_state;
lorawan_app_callbacks_t _callbacks;
radio_events_t *_mac_handlers;
lorawan_session_t _lw_session;
loramac_tx_message_t _tx_msg;
loramac_rx_message_t _rx_msg;
uint8_t _num_retry;
uint8_t _app_port;
bool _duty_cycle_on;
bool _link_check_requested;
events::EventQueue *_queue;
#if defined(LORAWAN_COMPLIANCE_TEST)
/**
* This function is used only for compliance testing
*/
void prepare_special_tx_frame(uint8_t port);
/**
* Used only for compliance testing
@ -476,7 +476,6 @@ private:
*/
lorawan_status_t send_compliance_test_frame_to_mac();
uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE];
compliance_test_t _compliance_test;
#endif
};

File diff suppressed because it is too large Load Diff

View File

@ -43,12 +43,10 @@
#include "lorawan/system/LoRaWANTimer.h"
#include "lorastack/phy/LoRaPHY.h"
#include "lorawan/system/lorawan_data_structures.h"
#include "lorastack/mac/LoRaMacCommand.h"
#include "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"
#include "LoRaMacChannelPlan.h"
#include "loraphy_target.h"
class LoRaMac {
@ -57,7 +55,7 @@ public:
/**
* Constructor
*/
LoRaMac(LoRaWANTimeHandler &lora_time);
LoRaMac();
/**
* Destructor
@ -75,15 +73,13 @@ public:
* @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,
lorawan_status_t initialize(loramac_primitives_t *primitives,
events::EventQueue *queue);
/**
@ -97,26 +93,28 @@ public:
/**
* @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.
* account and returns corresponding value.
*
* @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.
* @return Size of the biggest packet that can be sent.
* 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);
uint8_t get_max_possible_tx_size(uint8_t size);
/**
* @brief nwk_joined Checks if device has joined to network
* @return True if joined to network, false otherwise
*/
bool nwk_joined();
/**
* @brief set_nwk_joined This is used for ABP mode for which real joining does not happen
* @param joined True if device has joined in network, false otherwise
*/
void set_nwk_joined(bool joined);
/**
* @brief Adds a channel plan to the system.
@ -209,162 +207,18 @@ public:
*/
lorawan_status_t multicast_channel_unlink(multicast_params_t *channel_param);
/**
* @brief Get parameter values from MIB service.
/** Binds radio driver to PHY layer.
*
* @details The MAC information base service to get the attributes of the LoRaMac layer.
* MAC layer is totally detached from the PHY layer so the stack layer
* needs to play the role of an arbitrator. This API gets a radio driver
* object from the application (via LoRaWANInterface), binds it to the PHY
* layer and initialises radio callback handles which the radio driver will
* use in order to report events.
*
* The following code-snippet shows how to use the API to get the
* parameter `AdrEnable`, defined by the enumeration type
* \ref MIB_ADR.
* @param radio LoRaRadio object, i.e., the radio driver
*
* @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 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 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 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.fport = 1;
* request.f_buffer = buffer;
* request.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 *get_phy_event_handlers();
void bind_radio_driver(LoRaRadio& radio);
/**
* @brief Configures the events to trigger an MLME-Indication with
@ -427,7 +281,101 @@ public:
*/
void open_continuous_rx2_window(void);
/**
* @brief get_default_tx_datarate Gets the default TX datarate
* @return default TX datarate.
*/
uint8_t get_default_tx_datarate();
/**
* @brief enable_adaptive_datarate Enables or disables adaptive datarate.
* @param adr_enabled Flag indicating is adr enabled or disabled.
*/
void enable_adaptive_datarate(bool adr_enabled);
/** Sets up the data rate.
*
* `set_datarate()` first verifies whether the data rate given is valid or not.
* If it is valid, the system sets the given data rate to the channel.
*
* @param data_rate The intended data rate, for example DR_0 or DR_1.
* Note that the macro DR_* can mean different
* things in different regions.
*
* @return LORAWAN_STATUS_OK if everything goes well, otherwise
* a negative error code.
*/
lorawan_status_t set_channel_data_rate(uint8_t data_rate);
/**
* @brief tx_ongoing Check whether a prepare is done or not.
* @return True if prepare_ongoing_tx is called, false otherwise.
*/
bool tx_ongoing();
/**
* @brief set_tx_ongoing Changes the ongoing status for prepared message.
* @param ongoing The value indicating the status.
*/
void set_tx_ongoing(bool ongoing);
/**
* @brief reset_ongoing_tx Resets _ongoing_tx_msg.
* @param reset_pending If true resets pending size also.
*/
void reset_ongoing_tx(bool reset_pending = false);
/**
* @brief prepare_ongoing_tx This will prepare (and override) ongoing_tx_msg.
* @param port The application port number.
* @param data A pointer to the data being sent. The ownership of the
* buffer is not transferred.
* @param length The size of data in bytes.
* @param flags A flag used to determine what type of
* message is being sent.
* @param num_retries Number of retries for a confirmed type message
* @return The number of bytes prepared for sending.
*/
int16_t prepare_ongoing_tx(uint8_t port, const uint8_t* data,
uint16_t length, uint8_t flags, uint8_t num_retries);
/**
* @brief send_ongoing_tx Sends the ongoing_tx_msg
* @return LORAWAN_STATUS_OK or a negative error code on failure.
*/
lorawan_status_t send_ongoing_tx();
/**
* @brief device_class Returns active device class
* @return Device class in use.
*/
device_class_t get_device_class() const;
/**
* @brief set_device_class Sets active device class.
* @param device_class Device class to use.
*/
void set_device_class(const device_class_t& device_class);
/**
* @brief setup_link_check_request Adds link check request command
* to be put on next outgoing message (when it fits)
*/
void setup_link_check_request();
/**
* @brief join_by_otaa Sends OTAA join message
* @param otaa_join Joining parameters
*
* @return LORAWAN_STATUS_OK or a negative error code on failure.
*/
lorawan_status_t join_by_otaa(const lorawan_connect_otaa_t& otaa_join);
/**
* @brief join_by_abp Sets up ABP connectivity parameters.
* @param abp_join Connectivity parameters.
*/
void join_by_abp(const lorawan_connect_abp_t& abp_join);
private:
/**
@ -482,6 +430,23 @@ private:
*/
void on_rx_window2_timer_event(void);
/*!
* \brief Check if the OnAckTimeoutTimer has do be disabled. If so, the
* function disables it.
*
* \param [in] node_ack_requested Set to true, if the node has requested an ACK
* \param [in] dev_class The device class
* \param [in] ack_received Set to true, if the node has received an ACK
* \param [in] ack_timeout_retries_counter Retries counter for confirmed uplinks
* \param [in] ack_timeout_retries Maximum retries for confirmed uplinks
*/
void check_to_disable_ack_timeout(bool node_ack_requested,
device_class_t dev_class,
bool ack_received,
uint8_t ack_timeout_retries_counter,
uint8_t ack_timeout_retries);
/**
* Function executed on AckTimeout timer event
*/
@ -524,64 +489,59 @@ private:
lorawan_status_t send_frame_on_channel(uint8_t channel);
/**
* Checks for Port validity.
* @brief reset_mcps_confirmation Resets the MCPS confirmation struct
*/
bool is_fPort_allowed(uint8_t fPort);
void reset_mcps_confirmation();
/**
* @brief reset_mlme_confirmation Resets the MLME confirmation struct
*/
void reset_mlme_confirmation();
/**
* @brief set_tx_continuous_wave Puts the system in continuous transmission mode
* @param [in] channel A Channel to use
* @param [in] datarate A datarate to use
* @param [in] tx_power A RF output power to use
* @param [in] max_eirp A maximum possible EIRP to use
* @param [in] antenna_gain Antenna gain to use
* @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
*/
void set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power,
float max_eirp, float antenna_gain, uint16_t timeout);
/**
* 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_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:
/**
* Timer subsystem handle
*/
LoRaWANTimeHandler _lora_time;
/**
* LoRa PHY layer object storage
*/
LoRaPHY *lora_phy;
LoRaPHY_region _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
*/
@ -602,9 +562,91 @@ private:
*/
events::EventQueue *ev_queue;
/**
* Structure to hold MCPS indication data.
*/
loramac_mcps_indication_t _mcps_indication;
/**
* Structure to hold MCPS confirm data.
*/
loramac_mcps_confirm_t _mcps_confirmation;
/**
* Structure to hold MLME indication data.
*/
loramac_mlme_indication_t _mlme_indication;
/**
* Structure to hold MLME confirm data.
*/
loramac_mlme_confirm_t _mlme_confirmation;
loramac_tx_message_t _ongoing_tx_msg;
bool _is_nwk_joined;
device_class_t _device_class;
#if defined(LORAWAN_COMPLIANCE_TEST)
public: // Test interface
/**
* @brief Set forth an MLME request.
*
* @details The MAC layer management entity handles the management services.
*
* @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 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_compliance_test_req_t request;
* request.type = MCPS_UNCONFIRMED;
* request.fport = 1;
* request.f_buffer = buffer;
* request.f_buffer_size = sizeof(buffer);
*
* if (test_request(&request) == LORAWAN_STATUS_OK) {
* // Service started successfully. Waiting for the MCPS-Confirm event
* }
*
* @endcode
*
* @param [in] request The test request to perform.
* Refer to \ref loramac_compliance_test_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 test_request(loramac_compliance_test_req_t *request);
/**
* \brief LoRaMAC set tx timer.
*

View File

@ -77,12 +77,8 @@ lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan)
}
lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
const loramac_mib_req_confirm_t* mib_confirm)
const channel_params_t* channel_list)
{
if (mib_confirm == NULL) {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
uint8_t max_num_channels;
uint16_t *channel_mask;
uint8_t count = 0;
@ -103,12 +99,12 @@ lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
// 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;
plan.channels[count].ch_param.frequency = channel_list[i].frequency;
plan.channels[count].ch_param.dr_range.value = channel_list[i].dr_range.value;
plan.channels[count].ch_param.dr_range.fields.min = channel_list[i].dr_range.fields.min;
plan.channels[count].ch_param.dr_range.fields.max = channel_list[i].dr_range.fields.max;
plan.channels[count].ch_param.band = channel_list[i].band;
plan.channels[count].ch_param.rx1_frequency = channel_list[i].rx1_frequency;
count++;
}

View File

@ -30,7 +30,6 @@ SPDX-License-Identifier: BSD-3-Clause
#include "lorawan/system/lorawan_data_structures.h"
#include "lorastack/phy/LoRaPHY.h"
#include "lorastack/mac/LoRaMacMib.h"
class LoRaMacChannelPlan {
@ -77,12 +76,12 @@ public:
* @param plan a reference to application provided channel plan structure
* which gets filled in with active channel plan data.
*
* @param mib_confirm pointer to MIB request structure containing channel information
* @param channel_list pointer to structure containing channel information
*
* @return LORAWAN_STATUS_OK if everything goes well otherwise
* a negative error code is returned.
*/
lorawan_status_t get_plan(lorawan_channelplan_t& plan, const loramac_mib_req_confirm_t *mib_confirm);
lorawan_status_t get_plan(lorawan_channelplan_t& plan, const channel_params_t* channel_list);
/** Remove the active channel plan
*

View File

@ -341,15 +341,12 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
// 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);
batteryLevel, snr & 0x3F);
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;
int8_t channel_id = payload[mac_index++];
chParam.frequency = (uint32_t) payload[mac_index++];
chParam.frequency |= (uint32_t) payload[mac_index++] << 8;
@ -358,7 +355,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
chParam.rx1_frequency = 0;
chParam.dr_range.value = payload[mac_index++];
status = lora_phy.request_new_channel(&newChannelReq);
status = lora_phy.request_new_channel(channel_id, &chParam);
ret_value = add_mac_command(MOTE_MAC_NEW_CHANNEL_ANS, status, 0);
}
@ -375,44 +372,47 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
}
break;
case SRV_MAC_TX_PARAM_SETUP_REQ: {
tx_param_setup_req_t txParamSetupReq;
uint8_t eirpDwellTime = payload[mac_index++];
uint8_t ul_dwell_time;
uint8_t dl_dwell_time;
uint8_t max_eirp;
txParamSetupReq.ul_dwell_time = 0;
txParamSetupReq.dl_dwell_time = 0;
ul_dwell_time = 0;
dl_dwell_time = 0;
if ((eirpDwellTime & 0x20) == 0x20) {
txParamSetupReq.dl_dwell_time = 1;
dl_dwell_time = 1;
}
if ((eirpDwellTime & 0x10) == 0x10) {
txParamSetupReq.ul_dwell_time = 1;
ul_dwell_time = 1;
}
txParamSetupReq.max_eirp = eirpDwellTime & 0x0F;
max_eirp = eirpDwellTime & 0x0F;
// Check the status for correctness
if (lora_phy.accept_tx_param_setup_req(&txParamSetupReq)) {
if (lora_phy.accept_tx_param_setup_req(ul_dwell_time, dl_dwell_time)) {
// Accept command
mac_sys_params.uplink_dwell_time =
txParamSetupReq.ul_dwell_time;
ul_dwell_time;
mac_sys_params.downlink_dwell_time =
txParamSetupReq.dl_dwell_time;
dl_dwell_time;
mac_sys_params.max_eirp =
max_eirp_table[txParamSetupReq.max_eirp];
max_eirp_table[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;
uint8_t channel_id = payload[mac_index++];
uint32_t rx1_frequency;
status = lora_phy.dl_channel_request(&dlChannelReq);
rx1_frequency = (uint32_t) payload[mac_index++];
rx1_frequency |= (uint32_t) payload[mac_index++] << 8;
rx1_frequency |= (uint32_t) payload[mac_index++] << 16;
rx1_frequency *= 100;
status = lora_phy.dl_channel_request(channel_id, rx1_frequency);
ret_value = add_mac_command(MOTE_MAC_DL_CHANNEL_ANS, status, 0);
}

View File

@ -1,57 +0,0 @@
/**
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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()
{
}
LoRaMacMcps::~LoRaMacMcps()
{
}
void LoRaMacMcps::reset_confirmation()
{
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
}
loramac_mcps_confirm_t& LoRaMacMcps::get_confirmation()
{
return confirmation;
}
loramac_mcps_indication_t& LoRaMacMcps::get_indication()
{
return indication;
}
void LoRaMacMcps::activate_mcps_subsystem()
{
}

View File

@ -1,88 +0,0 @@
/**
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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();
/**
* @brief reset_confirmation Resets the confirmation struct
*/
void reset_confirmation();
/** Activating MCPS subsystem
*
* Stores pointers to MAC and PHY layer handles
*/
void activate_mcps_subsystem();
/** Grants access to MCPS confirmation data
*
* @return a reference to MCPS confirm data structure
*/
loramac_mcps_confirm_t& get_confirmation();
/** Grants access to MCPS indication data
*
* @return a reference to MCPS indication data structure
*/
loramac_mcps_indication_t& get_indication();
private:
/**
* 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

@ -1,423 +0,0 @@
/**
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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_phy(NULL)
{
}
LoRaMacMib::~LoRaMacMib()
{
}
void LoRaMacMib::activate_mib_subsystem(LoRaPHY *phy)
{
_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) {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
lorawan_status_t status = LORAWAN_STATUS_OK;
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);
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: {
if (_lora_phy->verify_rx_datarate(mibSet->param.rx2_channel.datarate) == 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);
}
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_RX2_DEFAULT_CHANNEL: {
if (_lora_phy->verify_rx_datarate(mibSet->param.rx2_channel.datarate) == 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: {
if (_lora_phy->verify_tx_datarate(mibSet->param.default_channel_data_rate, true)) {
params->sys_params.channel_data_rate = mibSet->param.default_channel_data_rate;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_CHANNELS_DATARATE: {
if (_lora_phy->verify_tx_datarate(mibSet->param.channel_data_rate, false) == true) {
params->sys_params.channel_data_rate = mibSet->param.channel_data_rate;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_CHANNELS_DEFAULT_TX_POWER: {
if (_lora_phy->verify_tx_power(mibSet->param.default_channel_tx_pwr)) {
params->sys_params.channel_tx_power = mibSet->param.default_channel_tx_pwr;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_CHANNELS_TX_POWER: {
if (_lora_phy->verify_tx_power(mibSet->param.channel_tx_pwr)) {
params->sys_params.channel_tx_power = mibSet->param.channel_tx_pwr;
} 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;
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:
{
mibGet->param.channel_list = _lora_phy->get_phy_channels();
break;
}
case MIB_RX2_CHANNEL:
{
mibGet->param.rx2_channel = params->sys_params.rx2_channel;
break;
}
case MIB_RX2_DEFAULT_CHANNEL:
{
rx2_channel.datarate = _lora_phy->get_default_rx2_datarate();
rx2_channel.frequency = _lora_phy->get_default_rx2_frequency();
mibGet->param.rx2_channel = rx2_channel;
break;
}
case MIB_CHANNELS_DEFAULT_MASK:
{
mibGet->param.default_channel_mask = _lora_phy->get_channel_mask(true);
break;
}
case MIB_CHANNELS_MASK:
{
mibGet->param.channel_mask = _lora_phy->get_channel_mask(false);
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:
{
mibGet->param.default_channel_data_rate = _lora_phy->get_default_tx_datarate();
break;
}
case MIB_CHANNELS_DATARATE:
{
mibGet->param.channel_data_rate = params->sys_params.channel_data_rate;
break;
}
case MIB_CHANNELS_DEFAULT_TX_POWER:
{
mibGet->param.default_channel_tx_pwr = _lora_phy->get_default_tx_power();
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

@ -1,100 +0,0 @@
/**
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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 phy pointer to PHY layer
*/
void activate_mib_subsystem(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:
/**
* Pointer PHY handle
*/
LoRaPHY *_lora_phy;
};
#endif /* MBED_OS_LORAWAN_MAC_MIB_H_ */

View File

@ -1,73 +0,0 @@
/**
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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_phy(NULL)
{
}
LoRaMacMlme::~LoRaMacMlme()
{
}
void LoRaMacMlme::reset_confirmation()
{
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
}
loramac_mlme_confirm_t& LoRaMacMlme::get_confirmation()
{
return confirmation;
}
loramac_mlme_indication_t& LoRaMacMlme::get_indication()
{
return indication;
}
void LoRaMacMlme::activate_mlme_subsystem(LoRaPHY *phy)
{
_lora_phy = phy;
}
void LoRaMacMlme::set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power,
float max_eirp, float antenna_gain, uint16_t timeout)
{
cw_mode_params_t continuous_wave;
continuous_wave.channel = channel;
continuous_wave.datarate = datarate;
continuous_wave.tx_power = tx_power;
continuous_wave.max_eirp = max_eirp;
continuous_wave.antenna_gain = antenna_gain;
continuous_wave.timeout = timeout;
_lora_phy->set_tx_cont_mode(&continuous_wave);
}

View File

@ -1,107 +0,0 @@
/**
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(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"
// 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();
/**
* @brief reset_confirmation Resets the confirmation struct
*/
void reset_confirmation();
/** Activating MLME subsystem
*
* Stores pointers to MAC and PHY layer handles
*
* @param phy pointer to PHY layer
*/
void activate_mlme_subsystem(LoRaPHY *phy);
/** Grants access to MLME confirmation data
*
* @return a reference to MLME confirm data structure
*/
loramac_mlme_confirm_t& get_confirmation();
/** Grants access to MLME indication data
*
* @return a reference to MLME indication data structure
*/
loramac_mlme_indication_t& get_indication();
/**
* @brief set_tx_continuous_wave Puts the system in continuous transmission mode
* @param [in] channel A Channel to use
* @param [in] datarate A datarate to use
* @param [in] tx_power A RF output power to use
* @param [in] max_eirp A maximum possible EIRP to use
* @param [in] antenna_gain Antenna gain to use
* @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
*/
void set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power,
float max_eirp, float antenna_gain, uint16_t timeout);
private:
/**
* Pointer to PHY handle
*/
LoRaPHY *_lora_phy;
/**
* 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

@ -112,7 +112,7 @@ void LoRaPHY::handle_send(uint8_t *buf, uint8_t size)
_radio->unlock();
}
uint8_t LoRaPHY::request_new_channel(new_channel_req_params_t* params)
uint8_t LoRaPHY::request_new_channel(int8_t channel_id, channel_params_t* new_channel)
{
if (!phy_params.custom_channelplans_supported) {
return 0;
@ -120,14 +120,14 @@ uint8_t LoRaPHY::request_new_channel(new_channel_req_params_t* params)
uint8_t status = 0x03;
if (params->new_channel->frequency == 0) {
if (new_channel->frequency == 0) {
// Remove
if (remove_channel(params->channel_id) == false) {
if (remove_channel(channel_id) == false) {
status &= 0xFC;
}
} else {
switch (add_channel(params->new_channel, params->channel_id)) {
switch (add_channel(new_channel, channel_id)) {
case LORAWAN_STATUS_OK:
{
break;
@ -175,7 +175,7 @@ bool LoRaPHY::verify_channel_DR(uint8_t nb_channels, uint16_t* channel_mask,
if (mask_bit_test(channel_mask, i)) {
// Check datarate validity for enabled channels
if (val_in_range(dr, (channels[i].dr_range.fields.min & 0x0F),
(channels[i].dr_range.fields.max & 0x0F))) {
(channels[i].dr_range.fields.max & 0x0F))) {
// At least 1 channel has been found we can return OK.
return true;
}
@ -247,22 +247,18 @@ void LoRaPHY::copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t
}
}
void LoRaPHY::set_last_tx_done(set_band_txdone_params_t* last_tx_params)
void LoRaPHY::set_last_tx_done(uint8_t channel, bool joined, lorawan_time_t last_tx_done_time)
{
if (!last_tx_params) {
return;
}
band_t *band_table = (band_t *) phy_params.bands.table;
channel_params_t *channel_list = phy_params.channels.channel_list;
if (last_tx_params->joined == true) {
band_table[channel_list[last_tx_params->channel].band].last_tx_time = last_tx_params->last_tx_done_time;
if (joined == true) {
band_table[channel_list[channel].band].last_tx_time = last_tx_done_time;
return;
}
band_table[channel_list[last_tx_params->channel].band].last_tx_time = last_tx_params->last_tx_done_time;
band_table[channel_list[last_tx_params->channel].band].last_join_tx_time = last_tx_params->last_tx_done_time;
band_table[channel_list[channel].band].last_tx_time = last_tx_done_time;
band_table[channel_list[channel].band].last_join_tx_time = last_tx_done_time;
}
@ -427,13 +423,13 @@ int8_t LoRaPHY::compute_tx_power(int8_t tx_power_idx, float max_eirp,
int8_t LoRaPHY::get_next_lower_dr(int8_t dr, int8_t min_dr)
{
uint8_t next_lower_dr = 0;
uint8_t next_lower_dr = dr;
if (dr == min_dr) {
next_lower_dr = min_dr;
} else {
next_lower_dr = dr - 1;
}
do {
if (next_lower_dr != min_dr) {
next_lower_dr -= 1;
}
} while((next_lower_dr != min_dr) && !is_datarate_supported(next_lower_dr));
return next_lower_dr;
}
@ -487,6 +483,15 @@ uint8_t LoRaPHY::enabled_channel_count(bool joined, uint8_t datarate,
return count;
}
bool LoRaPHY::is_datarate_supported(const int8_t datarate) const
{
if (datarate < phy_params.datarates.size) {
return (((uint8_t *)phy_params.datarates.table)[datarate] != 0) ? true : false;
} else {
return false;
}
}
void LoRaPHY::reset_to_default_values(loramac_protocol_params *params, bool init)
{
if (init) {
@ -629,20 +634,27 @@ void LoRaPHY::restore_default_channels()
bool LoRaPHY::verify_rx_datarate(uint8_t datarate)
{
if (phy_params.dl_dwell_time_setting == 0) {
//TODO: Check this! datarate must be same as minimum! Can be compared directly if OK
return val_in_range(datarate,
phy_params.min_rx_datarate,
phy_params.min_rx_datarate);
} else {
return val_in_range(datarate,
phy_params.dwell_limit_datarate,
phy_params.min_rx_datarate );
if (is_datarate_supported(datarate)) {
if (phy_params.dl_dwell_time_setting == 0) {
//TODO: Check this! datarate must be same as minimum! Can be compared directly if OK
return val_in_range(datarate,
phy_params.min_rx_datarate,
phy_params.max_rx_datarate);
} else {
return val_in_range(datarate,
phy_params.dwell_limit_datarate,
phy_params.max_rx_datarate );
}
}
return false;
}
bool LoRaPHY::verify_tx_datarate(uint8_t datarate, bool use_default)
{
if (!is_datarate_supported(datarate)) {
return false;
}
if (use_default) {
return val_in_range(datarate, phy_params.default_datarate,
phy_params.default_max_datarate);
@ -677,7 +689,7 @@ bool LoRaPHY::verify_nb_join_trials(uint8_t nb_join_trials)
return true;
}
void LoRaPHY::apply_cf_list(cflist_params_t* cf_list)
void LoRaPHY::apply_cf_list(const uint8_t* payload, uint8_t size)
{
// if the underlying PHY doesn't support CF-List, ignore the request
if (!phy_params.cflist_supported) {
@ -688,10 +700,10 @@ void LoRaPHY::apply_cf_list(cflist_params_t* cf_list)
// Setup default datarate range
new_channel.dr_range.value = (phy_params.default_max_datarate << 4)
| phy_params.default_datarate;
| phy_params.default_datarate;
// Size of the optional CF list
if (cf_list->size != 16) {
if (size != 16) {
return;
}
@ -706,9 +718,9 @@ void LoRaPHY::apply_cf_list(cflist_params_t* cf_list)
channel_id < phy_params.max_channel_cnt; i+=phy_params.default_channel_cnt, channel_id++) {
if (channel_id < (phy_params.cflist_channel_cnt + phy_params.default_channel_cnt)) {
// Channel frequency
new_channel.frequency = (uint32_t) cf_list->payload[i];
new_channel.frequency |= ((uint32_t) cf_list->payload[i + 1] << 8);
new_channel.frequency |= ((uint32_t) cf_list->payload[i + 2] << 16);
new_channel.frequency = (uint32_t) payload[i];
new_channel.frequency |= ((uint32_t) payload[i + 1] << 8);
new_channel.frequency |= ((uint32_t) payload[i + 2] << 16);
new_channel.frequency *= 100;
// Initialize alternative frequency to 0
@ -976,23 +988,27 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req,
}
}
verify_params.status = status;
if (is_datarate_supported(adr_settings.datarate)) {
verify_params.status = status;
verify_params.adr_enabled = link_adr_req->adr_enabled;
verify_params.current_datarate = link_adr_req->current_datarate;
verify_params.current_tx_power = link_adr_req->current_tx_power;
verify_params.current_nb_rep = link_adr_req->current_nb_rep;
verify_params.adr_enabled = link_adr_req->adr_enabled;
verify_params.current_datarate = link_adr_req->current_datarate;
verify_params.current_tx_power = link_adr_req->current_tx_power;
verify_params.current_nb_rep = link_adr_req->current_nb_rep;
verify_params.datarate = adr_settings.datarate;
verify_params.tx_power = adr_settings.tx_power;
verify_params.nb_rep = adr_settings.nb_rep;
verify_params.datarate = adr_settings.datarate;
verify_params.tx_power = adr_settings.tx_power;
verify_params.nb_rep = adr_settings.nb_rep;
verify_params.channel_mask = temp_channel_mask;
verify_params.channel_mask = temp_channel_mask;
// Verify the parameters and update, if necessary
status = verify_link_ADR_req(&verify_params, &adr_settings.datarate,
&adr_settings.tx_power, &adr_settings.nb_rep);
// Verify the parameters and update, if necessary
status = verify_link_ADR_req(&verify_params, &adr_settings.datarate,
&adr_settings.tx_power, &adr_settings.nb_rep);
} else {
status &= 0xFD; // Datarate KO
}
// Update channelsMask if everything is correct
if (status == 0x07) {
@ -1038,11 +1054,11 @@ uint8_t LoRaPHY::accept_rx_param_setup_req(rx_param_setup_req_t* params)
return status;
}
bool LoRaPHY::accept_tx_param_setup_req(tx_param_setup_req_t *params)
bool LoRaPHY::accept_tx_param_setup_req(uint8_t ul_dwell_time, uint8_t dl_dwell_time)
{
if (phy_params.accept_tx_param_setup_req) {
phy_params.ul_dwell_time_setting = params->ul_dwell_time;
phy_params.dl_dwell_time_setting = params->dl_dwell_time;
phy_params.ul_dwell_time_setting = ul_dwell_time;
phy_params.dl_dwell_time_setting = dl_dwell_time;
}
return phy_params.accept_tx_param_setup_req;
@ -1065,7 +1081,7 @@ bool LoRaPHY::verify_frequency(uint32_t freq)
return false;
}
uint8_t LoRaPHY::dl_channel_request(dl_channel_req_params_t* params)
uint8_t LoRaPHY::dl_channel_request(uint8_t channel_id, uint32_t rx1_frequency)
{
if (!phy_params.dl_channel_req_supported) {
return 0;
@ -1074,18 +1090,18 @@ uint8_t LoRaPHY::dl_channel_request(dl_channel_req_params_t* params)
uint8_t status = 0x03;
// Verify if the frequency is supported
if (verify_frequency(params->rx1_frequency) == false) {
if (verify_frequency(rx1_frequency) == false) {
status &= 0xFE;
}
// Verify if an uplink frequency exists
if (phy_params.channels.channel_list[params->channel_id].frequency == 0) {
if (phy_params.channels.channel_list[channel_id].frequency == 0) {
status &= 0xFD;
}
// Apply Rx1 frequency, if the status is OK
if (status == 0x03) {
phy_params.channels.channel_list[params->channel_id].rx1_frequency = params->rx1_frequency;
phy_params.channels.channel_list[channel_id].rx1_frequency = rx1_frequency;
}
return status;
@ -1139,23 +1155,24 @@ int8_t LoRaPHY::get_alternate_DR(uint8_t nb_trials)
return datarate;
}
void LoRaPHY::calculate_backoff(backoff_params_t* calc_backoff)
void LoRaPHY::calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_enabled, uint8_t channel,
lorawan_time_t elapsed_time, lorawan_time_t tx_toa)
{
band_t *band_table = (band_t *) phy_params.bands.table;
channel_params_t *channel_list = phy_params.channels.channel_list;
uint8_t band_idx = channel_list[calc_backoff->channel].band;
uint8_t band_idx = channel_list[channel].band;
uint16_t duty_cycle = band_table[band_idx].duty_cycle;
uint16_t join_duty_cycle = 0;
// Reset time-off to initial value.
band_table[band_idx].off_time = 0;
if (calc_backoff->joined == false) {
if (joined == false) {
// Get the join duty cycle
if (calc_backoff->elapsed_time < 3600000) {
if (elapsed_time < 3600000) {
join_duty_cycle = BACKOFF_DC_1_HOUR;
} else if (calc_backoff->elapsed_time < (3600000 + 36000000)) {
} else if (elapsed_time < (3600000 + 36000000)) {
join_duty_cycle = BACKOFF_DC_10_HOURS;
} else {
join_duty_cycle = BACKOFF_DC_24_HOURS;
@ -1167,18 +1184,18 @@ void LoRaPHY::calculate_backoff(backoff_params_t* calc_backoff)
// No back-off if the last frame was not a join request and when the
// duty cycle is not enabled
if (calc_backoff->dc_enabled == false &&
calc_backoff->last_tx_was_join_req == false) {
if (dc_enabled == false &&
last_tx_was_join_req == false) {
band_table[band_idx].off_time = 0;
} else {
// Apply band time-off.
band_table[band_idx].off_time = calc_backoff->tx_toa * duty_cycle - calc_backoff->tx_toa;
band_table[band_idx].off_time = tx_toa * duty_cycle - tx_toa;
}
}
bool LoRaPHY::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff)
lorawan_status_t LoRaPHY::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff)
{
uint8_t channel_count = 0;
uint8_t delay_tx = 0;
@ -1228,13 +1245,13 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params,
// We found a valid channel
*channel = enabled_channels[get_random(0, channel_count - 1)];
*time = 0;
return true;
return LORAWAN_STATUS_OK;
}
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = next_tx_delay;
return true;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
// Datarate not supported by any channel, restore defaults
@ -1242,7 +1259,7 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params,
phy_params.channels.default_mask,
phy_params.channels.mask_size);
*time = 0;
return false;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
lorawan_status_t LoRaPHY::add_channel(channel_params_t* new_channel, uint8_t id)
@ -1331,7 +1348,7 @@ bool LoRaPHY::remove_channel(uint8_t channel_id)
// Remove the channel from the list of channels
const channel_params_t empty_channel = { 0, 0, { 0 }, 0 };
const channel_params_t empty_channel = { 0, 0, {0}, 0 };
phy_params.channels.channel_list[channel_id] = empty_channel;
return disable_channel(phy_params.channels.mask, channel_id,

View File

@ -104,28 +104,34 @@ public:
*/
uint32_t get_radio_rng();
/** Calculates and applies duty cycle back-off time.
/**
* @brief calculate_backoff Calculates and applies duty cycle back-off time.
* Explicitly updates the band time-off.
*
* Explicitly updates the band time-off.
*
* @param [in] backoff_params A pointer to backoff parameters.
* @param joined Set to true, if the node has already joined a network, otherwise false.
* @param last_tx_was_join_req Set to true, if the last uplink was a join request.
* @param dc_enabled Set to true, if the duty cycle is enabled, otherwise false.
* @param channel The current channel index.
* @param elapsed_time Elapsed time since the start of the node.
* @param tx_toa Time-on-air of the last transmission.
*/
void calculate_backoff(backoff_params_t* backoff_params);
void calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_enabled, uint8_t channel,
lorawan_time_t elapsed_time, lorawan_time_t tx_toa);
/**
/**
* Tests if a channel is on or off in the channel mask
*/
bool mask_bit_test(const uint16_t *mask, unsigned bit);
bool mask_bit_test(const uint16_t *mask, unsigned bit);
/**
/**
* Tests if a channel is on or off in the channel mask
*/
void mask_bit_set(uint16_t *mask, unsigned bit);
void mask_bit_set(uint16_t *mask, unsigned bit);
/**
/**
* Tests if a channel is on or off in the channel mask
*/
void mask_bit_clear(uint16_t *mask, unsigned bit);
void mask_bit_clear(uint16_t *mask, unsigned bit);
/** Entertain a new channel request MAC command.
*
@ -133,20 +139,21 @@ public:
* 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.
* @param channel_id The channel ID.
* @param new_channel A pointer to the new channel's parameters.
*
* @return bit mask, according to the LoRaWAN spec 1.0.2.
*/
virtual uint8_t request_new_channel(new_channel_req_params_t* new_channel_req);
virtual uint8_t request_new_channel(int8_t channel_id, channel_params_t* new_channel);
/** Process PHY layer state after a successful transmission.
*
* Updates times of the last transmission for the particular channel and
* band upon which last transmission took place.
*
* @param [in] tx_done A pointer to set_band_txdone_params_t
* @brief set_last_tx_done Updates times of the last transmission for the particular channel and
* band upon which last transmission took place.
* @param channel The channel in use.
* @param joined Boolean telling if node has joined the network.
* @param last_tx_done_time The last TX done time.
*/
virtual void set_last_tx_done(set_band_txdone_params_t* tx_done);
virtual void set_last_tx_done(uint8_t channel, bool joined, lorawan_time_t last_tx_done_time);
/** Enables default channels only.
*
@ -160,9 +167,11 @@ public:
* Handles the payload containing CF-list and enables channels defined
* therein.
*
* @param cflist_params A pointer to cflist_params_t.
* @param payload Payload to process.
* @param size Size of the payload.
*
*/
virtual void apply_cf_list(cflist_params_t* cflist_params);
virtual void apply_cf_list(const uint8_t* payload, uint8_t size);
/** Calculates the next datarate to set, when ADR is on or off.
*
@ -259,7 +268,7 @@ public:
* @return True, if the configuration was applied successfully.
*/
virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power,
lorawan_time_t* tx_toa);
lorawan_time_t* tx_toa);
/** Processes a Link ADR Request.
*
@ -291,23 +300,26 @@ public:
*/
virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
/** Makes decision whether to accept or reject TxParamSetupReq MAC command
/**
* @brief accept_tx_param_setup_req Makes decision whether to accept or reject TxParamSetupReq MAC command.
*
* @param [in] params A pointer to tx parameter setup request.
* @param ul_dwell_time The uplink dwell time.
* @param dl_dwell_time The downlink dwell time.
*
* @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.
* @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 bool accept_tx_param_setup_req(tx_param_setup_req_t* params);
virtual bool accept_tx_param_setup_req(uint8_t ul_dwell_time, uint8_t dl_dwell_time);
/** Processes a DlChannelReq MAC command.
*
* @param [in] params A pointer to downlink channel request.
* @param channel_id The channel ID to add the frequency.
* @param rx1_frequency The alternative frequency for the Rx1 window.
*
* @return The status of the operation, according to the LoRaWAN specification.
*/
virtual uint8_t dl_channel_request(dl_channel_req_params_t* params);
virtual uint8_t dl_channel_request(uint8_t channel_id, uint32_t rx1_frequency);
/** Alternates the datarate of the channel for the join request.
*
@ -332,9 +344,9 @@ public:
*
* @return Function status [1: OK, 0: Unable to find a channel on the current datarate].
*/
virtual bool set_next_channel(channel_selection_params_t* nextChanParams,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregatedTimeOff);
virtual lorawan_status_t set_next_channel(channel_selection_params_t* nextChanParams,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregatedTimeOff);
/** Adds a channel to the channel list.
*
@ -512,10 +524,6 @@ public: //Verifiers
bool verify_nb_join_trials(uint8_t nb_join_trials);
protected:
LoRaRadio *_radio;
LoRaWANTimeHandler &_lora_time;
loraphy_params_t phy_params;
LoRaPHY(LoRaWANTimeHandler &lora_time);
/**
@ -614,8 +622,13 @@ protected:
uint8_t enabled_channel_count(bool joined, uint8_t datarate,
const uint16_t *mask, uint8_t* enabledChannels,
uint8_t* delayTx);
bool is_datarate_supported(const int8_t datarate) const;
protected:
LoRaRadio *_radio;
LoRaWANTimeHandler &_lora_time;
loraphy_params_t phy_params;
};
#endif /* MBED_OS_LORAPHY_BASE_ */

View File

@ -334,9 +334,9 @@ int8_t LoRaPHYAS923::get_alternate_DR(uint8_t nb_trials)
return AS923_DWELL_LIMIT_DATARATE;
}
bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_prams,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff)
lorawan_status_t LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_prams,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff)
{
uint8_t next_channel_idx = 0;
uint8_t nb_enabled_channels = 0;
@ -387,23 +387,23 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra
_radio->unlock();
*channel = next_channel_idx;
*time = 0;
return true;
return LORAWAN_STATUS_OK;
}
}
_radio->unlock();
return false;
return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND;
} else {
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = next_tx_delay;
return true;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
// Datarate not supported by any channel, restore defaults
channel_mask[0] |= LC( 1 ) + LC( 2 );
*time = 0;
return false;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
}

View File

@ -55,9 +55,9 @@ public:
virtual int8_t get_alternate_DR(uint8_t nb_trials);
virtual bool set_next_channel(channel_selection_params_t* nextChanParams,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregatedTimeOff );
virtual lorawan_status_t set_next_channel(channel_selection_params_t* nextChanParams,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregatedTimeOff );
virtual uint8_t apply_DR_offset(int8_t dr, int8_t drOffset );

View File

@ -555,9 +555,9 @@ int8_t LoRaPHYAU915::get_alternate_DR(uint8_t nb_trials)
return datarate;
}
bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregated_timeOff)
lorawan_status_t LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregated_timeOff)
{
uint8_t nb_enabled_channels = 0;
uint8_t delay_tx = 0;
@ -605,16 +605,16 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params
AU915_MAX_NB_CHANNELS - 8);
*time = 0;
return true;
return LORAWAN_STATUS_OK;
} else {
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = next_tx_delay;
return true;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
// Datarate not supported by any channel
*time = 0;
return false;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
}

View File

@ -70,9 +70,9 @@ public:
virtual int8_t get_alternate_DR(uint8_t nb_trials);
virtual bool set_next_channel(channel_selection_params_t* next_chan_params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff);
virtual lorawan_status_t set_next_channel(channel_selection_params_t* next_chan_params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff);
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);

View File

@ -210,7 +210,7 @@ static const channel_params_t IN865_LC3 = { 865985000, 0, { ( ( DR_5 << 4 ) | DR
/*!
* Data rates table definition
*/
static const uint8_t datarates_IN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
static const uint8_t datarates_IN865[] = { 12, 11, 10, 9, 8, 7, 0, 50 };
/*!
* Bandwidths table definition in Hz

View File

@ -404,9 +404,9 @@ bool LoRaPHYKR920::tx_config(tx_config_params_t* config, int8_t* tx_power,
return true;
}
bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff)
lorawan_status_t LoRaPHYKR920::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff)
{
uint8_t next_channel_idx = 0;
uint8_t nb_enabled_channels = 0;
@ -455,26 +455,26 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params,
*channel = next_channel_idx;
*time = 0;
_radio->unlock();
return true;
return LORAWAN_STATUS_OK;
}
_radio->unlock();
}
return false;
return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND;
} else {
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = nextTxDelay;
return true;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
// Datarate not supported by any channel, restore defaults
channel_mask[0] |= LC(1) + LC(2) + LC(3);
*time = 0;
return false;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
}

View File

@ -59,9 +59,9 @@ public:
virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power,
lorawan_time_t* tx_toa);
virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel,
lorawan_time_t* time,
lorawan_time_t* aggregate_timeOff);
virtual lorawan_status_t set_next_channel(channel_selection_params_t* params, uint8_t* channel,
lorawan_time_t* time,
lorawan_time_t* aggregate_timeOff);
virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave,
uint32_t frequency = 0);

View File

@ -602,9 +602,9 @@ int8_t LoRaPHYUS915::get_alternate_DR(uint8_t nb_trials)
return datarate;
}
bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeOff)
lorawan_status_t LoRaPHYUS915::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeOff)
{
uint8_t nb_enabled_channels = 0;
uint8_t delay_tx = 0;
@ -649,19 +649,19 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params,
disable_channel(current_channel_mask, *channel, US915_MAX_NB_CHANNELS - 8);
*time = 0;
return true;
return LORAWAN_STATUS_OK;
} else {
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = next_tx_delay;
return true;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
// Datarate not supported by any channel
*time = 0;
return false;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
}

View File

@ -70,8 +70,8 @@ public:
virtual int8_t get_alternate_DR(uint8_t nb_trials);
virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel,
lorawan_time_t* time, lorawan_time_t* aggregate_timeOff);
virtual lorawan_status_t set_next_channel(channel_selection_params_t* params, uint8_t* channel,
lorawan_time_t* time, lorawan_time_t* aggregate_timeOff);
virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave,
uint32_t frequency = 0);

View File

@ -601,9 +601,9 @@ int8_t LoRaPHYUS915Hybrid::get_alternate_DR(uint8_t nb_trials)
return datarate;
}
bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeOff)
lorawan_status_t LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeOff)
{
uint8_t nb_enabled_channels = 0;
uint8_t delay_tx = 0;
@ -650,19 +650,19 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params,
disable_channel(current_channel_mask, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8);
*time = 0;
return true;
return LORAWAN_STATUS_OK;
} else {
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = next_tx_delay;
return true;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
// Datarate not supported by any channel
*time = 0;
return false;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
}
@ -757,7 +757,7 @@ bool LoRaPHYUS915Hybrid::validate_channel_mask(uint16_t* channel_masks)
block1 = temp_channel_masks[i] & 0x00FF;
block2 = temp_channel_masks[i] & 0xFF00;
if (count_bits(block1, 16) > 5) {
if (count_bits(block1, 16) > 1) {
temp_channel_masks[i] &= block1;
temp_channel_masks[4] = 1 << ( i * 2 );
@ -765,7 +765,7 @@ bool LoRaPHYUS915Hybrid::validate_channel_mask(uint16_t* channel_masks)
index = i;
break;
} else if( count_bits( block2, 16 ) > 5 ) {
} else if( count_bits( block2, 16 ) > 1 ) {
temp_channel_masks[i] &= block2;
temp_channel_masks[4] = 1 << ( i * 2 + 1 );

View File

@ -74,9 +74,9 @@ public:
virtual int8_t get_alternate_DR(uint8_t nb_trials);
virtual bool set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff);
virtual lorawan_status_t set_next_channel(channel_selection_params_t* params,
uint8_t* channel, lorawan_time_t* time,
lorawan_time_t* aggregate_timeoff);
virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave,
uint32_t frequency = 0);

View File

@ -524,40 +524,6 @@
*/
#define TX_POWER_15 15
/**
* The parameter structure for the function RegionSetBandTxDone.
*/
typedef struct
{
/**
* The channel to update.
*/
uint8_t channel;
/**
* Joined set to true, if the node has joined the network.
*/
bool joined;
/**
* The last TX done time.
*/
lorawan_time_t last_tx_done_time;
} set_band_txdone_params_t;
/**
* The parameter structure for the function RegionApplyCFList.
*/
typedef struct
{
/**
* The payload containing the CF list.
*/
uint8_t* payload;
/**
* The size of the payload.
*/
uint8_t size;
} cflist_params_t;
/**
* TX configuration parameters.
*/
@ -717,90 +683,6 @@ typedef struct rx_param_setup_req_s
uint32_t frequency;
} rx_param_setup_req_t;
/**
* Contains tx parameter setup request coming from
* network server.
*/
typedef struct tx_param_setup_req_s
{
/**
* The uplink dwell time.
*/
uint8_t ul_dwell_time;
/**
* The downlink dwell time.
*/
uint8_t dl_dwell_time;
/**
* The max EIRP.
*/
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 dl_channel_req_params_s
{
/**
* The channel ID to add the frequency.
*/
uint8_t channel_id;
/**
* The alternative frequency for the Rx1 window.
*/
uint32_t rx1_frequency;
} dl_channel_req_params_t;
/*!
* The parameter structure for the function RegionCalcBackOff.
*/
typedef struct backoff_params_s
{
/**
* Set to true, if the node has already joined a network, otherwise false.
*/
bool joined;
/**
* set to true, if the last uplink was a join request.
*/
bool last_tx_was_join_req;
/**
* Set to true, if the duty cycle is enabled, otherwise false.
*/
bool dc_enabled;
/**
* The current channel index.
*/
uint8_t channel;
/**
* Elapsed time since the start of the node.
*/
lorawan_time_t elapsed_time;
/**
* Time-on-air of the last transmission.
*/
lorawan_time_t tx_toa;
} backoff_params_t;
/**
* The parameter structure for the function RegionNextChannel.
*/
@ -865,13 +747,13 @@ typedef struct {
} loraphy_table_t;
typedef struct {
channel_params_t *channel_list;
uint8_t channel_list_size;
uint8_t mask_size;
uint16_t *mask;
uint16_t *default_mask;
uint8_t mask_size;
channel_params_t *channel_list;
} loraphy_channels_t;
typedef struct {

View File

@ -0,0 +1,58 @@
/**
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LORAPHY_TARGET
#define LORAPHY_TARGET
#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
#endif // LORAPHY_TARGET

View File

@ -55,21 +55,6 @@ typedef uint32_t lorawan_time_t;
#define MSG_MULTICAST_FLAG 0x04
#define MSG_PROPRIETARY_FLAG 0x08
/**
* A macro to test a if a bit is on in a channel mask or not.
*/
//#define MASK_BIT_TEST(mask, bit) (mask & (1U << bit))
//#define MASK_BIT_TEST(mask, bit) ((mask)[(bit) / 16] & (1U << ((bit) % 16)))
/**
* A macro to clear a bit in a channel mask.
*/
//#define MASK_BIT_CLEAR(mask, bit) (mask &= ~(1 << bit))
/**
* A macro to clear a bit in a channel mask.
*/
//#define MASK_BIT_SET(mask, bit) (mask |= (1 << bit))
/**
* Bit mask for message flags
*/
@ -157,6 +142,7 @@ typedef enum {
/*!
* LoRaMAC channel parameters definition.
* DO NOT MODIFY, WILL BREAK THE API!
*/
typedef union {
/*!
@ -189,6 +175,7 @@ typedef union {
/*!
* LoRaMAC channel definition.
* DO NOT MODIFY, WILL BREAK THE API!
*/
typedef struct {
/*!
@ -762,62 +749,6 @@ typedef enum {
MCPS_PROPRIETARY,
} mcps_type_t;
/*!
* LoRaMAC MCPS-Request structure.
*/
typedef struct {
/*!
* MCPS-Request type.
*/
mcps_type_t type;
/*!
* Frame port field. Must be set if the payload is not empty. Use the
* application-specific frame port values: [1...223].
*
* LoRaWAN Specification V1.0.2, chapter 4.3.2.
*/
uint8_t fport;
/*!
* Uplink datarate, if ADR is off.
*/
int8_t data_rate;
/*!
* The number of trials to transmit the frame, if the LoRaMAC layer did not
* receive an acknowledgment. The MAC performs a datarate adaptation
* according to the LoRaWAN Specification V1.0.2, chapter 18.4, as in
* the following table:
*
* Transmission nb | Data Rate
* ----------------|-----------
* 1 (first) | DR
* 2 | DR
* 3 | max(DR-1,0)
* 4 | max(DR-1,0)
* 5 | max(DR-2,0)
* 6 | max(DR-2,0)
* 7 | max(DR-3,0)
* 8 | max(DR-3,0)
*
* Note that if nb_trials is set to 1 or 2, the MAC will not decrease
* the datarate, if the LoRaMAC layer did not receive an acknowledgment.
*/
uint8_t nb_trials;
/** Payload data
*
* A pointer to the buffer of the frame payload.
*/
void *f_buffer;
/** Payload size
*
* The size of the frame payload.
*/
uint16_t f_buffer_size;
} loramac_mcps_req_t;
/*!
* LoRaMAC MCPS-Confirm.
*/
@ -856,9 +787,9 @@ typedef struct {
*/
uint32_t ul_frame_counter;
/*!
* The uplink frequency related to the frame.
* The uplink channel related to the frame.
*/
uint32_t ul_frequency;
uint32_t channel;
} loramac_mcps_confirm_t;
/*!
@ -1025,29 +956,6 @@ typedef struct {
uint8_t power;
} mlme_cw_tx_mode_t;
/*!
* LoRaMAC MLME-Request structure.
*/
typedef struct {
/*!
* MLME-Request type.
*/
mlme_type_t type;
/*!
* MLME-Request parameters.
*/
union {
/*!
* MLME-Request parameters for a join request.
*/
mlme_join_req_t join;
/*!
* MLME-Request parameters for TX continuous mode request.
*/
mlme_cw_tx_mode_t cw_tx_mode;
} req;
} loramac_mlme_req_t;
/*!
* LoRaMAC MLME-Confirm primitive.
@ -1091,465 +999,6 @@ typedef struct {
mlme_type_t indication_type;
} loramac_mlme_indication_t;
/*!
* LoRa MAC Information Base (MIB).
*
* The following table lists the MIB parameters and the related attributes:
*
* Attribute | Get | Set
* --------------------------------- | :-: | :-:
* \ref MIB_DEVICE_CLASS | YES | YES
* \ref MIB_NETWORK_JOINED | YES | YES
* \ref MIB_ADR | YES | YES
* \ref MIB_NET_ID | YES | YES
* \ref MIB_DEV_ADDR | YES | YES
* \ref MIB_NWK_SKEY | YES | YES
* \ref MIB_APP_SKEY | YES | YES
* \ref MIB_PUBLIC_NETWORK | YES | YES
* \ref MIB_REPEATER_SUPPORT | YES | YES
* \ref MIB_CHANNELS | YES | NO
* \ref MIB_RX2_CHANNEL | YES | YES
* \ref MIB_CHANNELS_MASK | YES | YES
* \ref MIB_CHANNELS_DEFAULT_MASK | YES | YES
* \ref MIB_CHANNELS_NB_REP | YES | YES
* \ref MIB_MAX_RX_WINDOW_DURATION | YES | YES
* \ref MIB_RECEIVE_DELAY_1 | YES | YES
* \ref MIB_RECEIVE_DELAY_2 | YES | YES
* \ref MIB_JOIN_ACCEPT_DELAY_1 | YES | YES
* \ref MIB_JOIN_ACCEPT_DELAY_2 | YES | YES
* \ref MIB_CHANNELS_DATARATE | YES | YES
* \ref MIB_CHANNELS_DEFAULT_DATARATE| YES | YES
* \ref MIB_CHANNELS_TX_POWER | YES | YES
* \ref MIB_CHANNELS_DEFAULT_TX_POWER| YES | YES
* \ref MIB_UPLINK_COUNTER | YES | YES
* \ref MIB_DOWNLINK_COUNTER | YES | YES
* \ref MIB_MULTICAST_CHANNEL | YES | NO
* \ref MIB_SYSTEM_MAX_RX_ERROR | YES | YES
* \ref MIB_MIN_RX_SYMBOLS | YES | YES
* \ref MIB_ANTENNA_GAIN | YES | YES
*
* The following table provides links to the function implementations of the
* related MIB primitives:
*
* Primitive | Function
* ---------------- | :---------------------:
* MIB-Set | LoRaMacMibSetRequestConfirm
* MIB-Get | LoRaMacMibGetRequestConfirm
*/
typedef enum {
/*!
* LoRaWAN device class.
*
* LoRaWAN Specification V1.0.2.
*/
MIB_DEVICE_CLASS,
/*!
* LoRaWAN Network joined attribute.
*
* LoRaWAN Specification V1.0.2.
*/
MIB_NETWORK_JOINED,
/*!
* Adaptive data rate.
*
* LoRaWAN Specification V1.0.2, chapter 4.3.1.1.
*
* [true: ADR enabled, false: ADR disabled].
*/
MIB_ADR,
/*!
* Network identifier.
*
* LoRaWAN Specification V1.0.2, chapter 6.1.1.
*/
MIB_NET_ID,
/*!
* End-device address.
*
* LoRaWAN Specification V1.0.2, chapter 6.1.1.
*/
MIB_DEV_ADDR,
/*!
* Network session key.
*
* LoRaWAN Specification V1.0.2, chapter 6.1.3.
*/
MIB_NWK_SKEY,
/*!
* Application session key.
*
* LoRaWAN Specification V1.0.2, chapter 6.1.4.
*/
MIB_APP_SKEY,
/*!
* Set the network type to public or private.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*
* [true: public network, false: private network]
*/
MIB_PUBLIC_NETWORK,
/*!
* Support the operation with repeaters.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*
* [true: repeater support enabled, false: repeater support disabled]
*/
MIB_REPEATER_SUPPORT,
/*!
* Communication channels. A GET request will return a
* pointer that references the first entry of the channel list. The
* list is of size LORA_MAX_NB_CHANNELS.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_CHANNELS,
/*!
* Set receive window 2 channel.
*
* LoRaWAN Specification V1.0.2, chapter 3.3.1.
*/
MIB_RX2_CHANNEL,
/*!
* Set receive window 2 channel.
*
* LoRaWAN Specification V1.0.2, chapter 3.3.2.
*/
MIB_RX2_DEFAULT_CHANNEL,
/*!
* LoRaWAN channels mask.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_CHANNELS_MASK,
/*!
* LoRaWAN default channels mask.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_CHANNELS_DEFAULT_MASK,
/*!
* Set the number of repetitions on a channel.
*
* LoRaWAN Specification V1.0.2, chapter 5.2.
*/
MIB_CHANNELS_NB_REP,
/*!
* The maximum receive window duration in [ms].
*
* LoRaWAN Specification V1.0.2, chapter 3.3.3.
*/
MIB_MAX_RX_WINDOW_DURATION,
/*!
* The receive delay 1 in [ms].
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_RECEIVE_DELAY_1,
/*!
* The receive delay 2 in [ms].
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_RECEIVE_DELAY_2,
/*!
* The join accept delay 1 in [ms].
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_JOIN_ACCEPT_DELAY_1,
/*!
* The join accept delay 2 in [ms].
*
* LoRaWAN Regional Parameters V1.0.2rB.
*/
MIB_JOIN_ACCEPT_DELAY_2,
/*!
* The default data rate of a channel.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*
* The allowed ranges are region-specific. Please refer to \ref DR_0 to \ref DR_15 for details.
*/
MIB_CHANNELS_DEFAULT_DATARATE,
/*!
* The data rate of a channel.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*
* The allowed ranges are region-specific. Please refer to \ref DR_0 to \ref DR_15 for details.
*/
MIB_CHANNELS_DATARATE,
/*!
* The transmission power of a channel.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*
* The allowed ranges are region-specific. Please refer to \ref TX_POWER_0 to \ref TX_POWER_15 for details.
*/
MIB_CHANNELS_TX_POWER,
/*!
* The transmission power of a channel.
*
* LoRaWAN Regional Parameters V1.0.2rB.
*
* The allowed ranges are region-specific. Please refer to \ref TX_POWER_0 to \ref TX_POWER_15 for details.
*/
MIB_CHANNELS_DEFAULT_TX_POWER,
/*!
* LoRaWAN uplink counter.
*
* LoRaWAN Specification V1.0.2, chapter 4.3.1.5.
*/
MIB_UPLINK_COUNTER,
/*!
* LoRaWAN downlink counter.
*
* LoRaWAN Specification V1.0.2, chapter 4.3.1.5.
*/
MIB_DOWNLINK_COUNTER,
/*!
* Multicast channels. A GET request will return a pointer to the first
* entry of the multicast channel linked list. If the pointer is equal to
* NULL, the list is empty.
*/
MIB_MULTICAST_CHANNEL,
/*!
* System overall timing error in milliseconds.
* [-SystemMaxRxError : +SystemMaxRxError]
* Default: +/-10 ms
*/
MIB_SYSTEM_MAX_RX_ERROR,
/*!
* The minimum number of symbols required to detect an RX frame.
* Default: 6 symbols
*/
MIB_MIN_RX_SYMBOLS,
/*!
* The antenna gain of the node. The default value is region-specific.
* The antenna gain is used to calculate the TX power of the node.
* The formula is:
* radioTxPower = ( int8_t )floor( maxEirp - antennaGain )
*/
MIB_ANTENNA_GAIN
} mib_type_t;
/*!
* LoRaMAC MIB parameters.
*/
typedef union {
/*!
* LoRaWAN device class.
*
* Related MIB type: \ref MIB_DEVICE_CLASS
*/
device_class_t dev_class;
/*!
* LoRaWAN network joined attribute
*
* Related MIB type: \ref MIB_NETWORK_JOINED
*/
bool is_nwk_joined;
/*!
* Activation state of ADR
*
* Related MIB type: \ref MIB_ADR
*/
bool is_adr_enable;
/*!
* Network identifier
*
* Related MIB type: \ref MIB_NET_ID
*/
uint32_t net_id;
/*!
* End-device address
*
* Related MIB type: \ref MIB_DEV_ADDR
*/
uint32_t dev_addr;
/*!
* Network session key
*
* Related MIB type: \ref MIB_NWK_SKEY
*/
uint8_t *nwk_skey;
/*!
* Application session key
*
* Related MIB type: \ref MIB_APP_SKEY
*/
uint8_t *app_skey;
/*!
* Enable or disable a public network
*
* Related MIB type: \ref MIB_PUBLIC_NETWORK
*/
bool enable_public_nwk;
/*!
* Enable or disable repeater support
*
* Related MIB type: \ref MIB_REPEATER_SUPPORT
*/
bool enable_repeater_support;
/*!
* LoRaWAN channel
*
* Related MIB type: \ref MIB_CHANNELS
*/
channel_params_t* channel_list;
/*!
* Channel for the receive window 2
*
* Related MIB type: \ref MIB_RX2_CHANNEL
*/
rx2_channel_params rx2_channel;
/*!
* Channel for the receive window 2
*
* Related MIB type: \ref MIB_RX2_DEFAULT_CHANNEL
*/
rx2_channel_params default_rx2_channel;
/*!
* Channel mask
*
* Related MIB type: \ref MIB_CHANNELS_MASK
*/
uint16_t* channel_mask;
/*!
* Default channel mask
*
* Related MIB type: \ref MIB_CHANNELS_DEFAULT_MASK
*/
uint16_t* default_channel_mask;
/*!
* Number of frame repetitions
*
* Related MIB type: \ref MIB_CHANNELS_NB_REP
*/
uint8_t channel_nb_rep;
/*!
* Maximum receive window duration
*
* Related MIB type: \ref MIB_MAX_RX_WINDOW_DURATION
*/
uint32_t max_rx_window;
/*!
* Receive delay 1
*
* Related MIB type: \ref MIB_RECEIVE_DELAY_1
*/
uint32_t recv_delay1;
/*!
* Receive delay 2
*
* Related MIB type: \ref MIB_RECEIVE_DELAY_2
*/
uint32_t recv_delay2;
/*!
* Join accept delay 1
*
* Related MIB type: \ref MIB_JOIN_ACCEPT_DELAY_1
*/
uint32_t join_accept_delay1;
/*!
* Join accept delay 2
*
* Related MIB type: \ref MIB_JOIN_ACCEPT_DELAY_2
*/
uint32_t join_accept_delay2;
/*!
* Channels data rate
*
* Related MIB type: \ref MIB_CHANNELS_DEFAULT_DATARATE
*/
int8_t default_channel_data_rate;
/*!
* Channels data rate
*
* Related MIB type: \ref MIB_CHANNELS_DATARATE
*/
int8_t channel_data_rate;
/*!
* Channels TX power
*
* Related MIB type: \ref MIB_CHANNELS_DEFAULT_TX_POWER
*/
int8_t default_channel_tx_pwr;
/*!
* Channels TX power
*
* Related MIB type: \ref MIB_CHANNELS_TX_POWER
*/
int8_t channel_tx_pwr;
/*!
* LoRaWAN uplink counter
*
* Related MIB type: \ref MIB_UPLINK_COUNTER
*/
uint32_t ul_frame_counter;
/*!
* LoRaWAN downlink counter
*
* Related MIB type: \ref MIB_DOWNLINK_COUNTER
*/
uint32_t dl_frame_counter;
/*!
* Multicast channel
*
* Related MIB type: \ref MIB_MULTICAST_CHANNEL
*/
multicast_params_t* multicast_list;
/*!
* System overall timing error in milliseconds
*
* Related MIB type: \ref MIB_SYSTEM_MAX_RX_ERROR
*/
uint32_t max_rx_sys_error;
/*!
* Minimum required number of symbols to detect an RX frame
*
* Related MIB type: \ref MIB_MIN_RX_SYMBOLS
*/
uint8_t min_rx_symb;
/*!
* Antenna gain
*
* Related MIB type: \ref MIB_ANTENNA_GAIN
*/
float antenna_gain;
} mib_params_t;
/*!
* LoRaMAC MIB-RequestConfirm structure
*/
typedef struct {
/*!
* MIB-Request type
*/
mib_type_t type;
/*!
* MLME-RequestConfirm parameters
*/
mib_params_t param;
}loramac_mib_req_confirm_t;
/*!
* LoRaMAC TX information
*/
typedef struct {
/*!
* Defines the size of the applicable payload that can be processed.
*/
uint8_t max_possible_payload_size;
/*!
* The current payload size, dependent on the current datarate.
*/
uint8_t current_payload_size;
} loramac_tx_info_t;
/** LoRaMAC status.
*
*/
@ -1575,6 +1024,9 @@ typedef enum lorawan_status {
#if defined(LORAWAN_COMPLIANCE_TEST)
LORAWAN_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */
#endif
LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020,
LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021,
LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022,
} lorawan_status_t;
/*!
@ -1783,6 +1235,7 @@ typedef struct {
/**
* Structure to hold A list of LoRa Channels
* DO NOT MODIFY, WILL BREAK THE API!
*/
typedef struct lora_channels_s {
uint8_t id;
@ -1827,42 +1280,14 @@ typedef struct lorawan_session {
lorawan_connect_t connection;
/**
* LoRaWAN uplink counter
*
* Related MIB type: LORA_MIB_UPLINK_COUNTER
*/
uint32_t uplink_counter;
/**
* LoRaWAN downlink counter
*
* Related MIB type: LORA_MIB_DOWNLINK_COUNTER
*/
uint32_t downlink_counter;
} lorawan_session_t;
/** Commissioning data
*
* A structure for data in commission.
*/
typedef struct {
/** Connection information
*
* Saves information for etc. keys
*/
lorawan_connect_t connection;
/**
* LoRaWAN Up-link counter
*
* Related MIB type: LORA_MIB_UPLINK_COUNTER
*/
uint32_t uplink_counter;
/**
* LoRaWAN Down-link counter
*
* Related MIB type: LORA_MIB_DOWNLINK_COUNTER
*/
uint32_t downlink_counter;
} lorawan_dev_commission_t;
/** Structure containing the uplink status
*
*/
@ -2072,11 +1497,6 @@ typedef struct {
typedef struct {
/*!
* Actual device class
*/
device_class_t dev_class;
/*!
* Holds the type of current Receive window slot
*/
@ -2303,12 +1723,79 @@ typedef struct {
mbed::Callback<uint8_t(void)> battery_level;
} lorawan_app_callbacks_t;
/**
* DO NOT MODIFY, WILL BREAK THE API!
*/
typedef struct lora_channelplan {
uint8_t nb_channels; // number of channels
loramac_channel_t *channels;
} lorawan_channelplan_t;
#if defined(LORAWAN_COMPLIANCE_TEST)
typedef struct {
/*!
* MLME-Request type.
*/
mlme_type_t type;
mlme_cw_tx_mode_t cw_tx_mode;
} loramac_mlme_req_t;
typedef struct {
/*!
* Compliance test request
*/
mcps_type_t type;
/*!
* Frame port field. Must be set if the payload is not empty. Use the
* application-specific frame port values: [1...223].
*
* LoRaWAN Specification V1.0.2, chapter 4.3.2.
*/
uint8_t fport;
/*!
* Uplink datarate, if ADR is off.
*/
int8_t data_rate;
/*!
* The number of trials to transmit the frame, if the LoRaMAC layer did not
* receive an acknowledgment. The MAC performs a datarate adaptation
* according to the LoRaWAN Specification V1.0.2, chapter 18.4, as in
* the following table:
*
* Transmission nb | Data Rate
* ----------------|-----------
* 1 (first) | DR
* 2 | DR
* 3 | max(DR-1,0)
* 4 | max(DR-1,0)
* 5 | max(DR-2,0)
* 6 | max(DR-2,0)
* 7 | max(DR-3,0)
* 8 | max(DR-3,0)
*
* Note that if nb_trials is set to 1 or 2, the MAC will not decrease
* the datarate, if the LoRaMAC layer did not receive an acknowledgment.
*/
uint8_t nb_trials;
/** Payload data
*
* A pointer to the buffer of the frame payload.
*/
uint8_t f_buffer[LORAMAC_PHY_MAXPAYLOAD];
/** Payload size
*
* The size of the frame payload.
*/
uint16_t f_buffer_size;
} loramac_compliance_test_req_t;
/** LoRaWAN compliance tests support data
*
*/
@ -2336,7 +1823,7 @@ typedef struct compliance_test {
/** Data provided by application
*
*/
uint8_t *app_data_buffer;
uint8_t app_data_buffer[MBED_CONF_LORA_TX_MAX_SIZE];
/** Downlink counter
*
*/