LoRa: LoRaMacMcps refactored to remove dependency to LoRaMac.

- This is internal logic only and there are no functionality changes
- Some compliance test stuff have been moved to end of files
- Some internal data structures removed as useless after refactor
pull/6279/head
Antti Kauppila 2018-03-05 15:16:08 +02:00
parent 37371df968
commit 2ac73a6cac
9 changed files with 371 additions and 450 deletions

View File

@ -34,6 +34,7 @@ public:
*
*/
LoRaWANInterface(LoRaRadio& radio);
virtual ~LoRaWANInterface();
/** Initialize the LoRa stack.

View File

@ -175,90 +175,6 @@ lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
return lora_state_machine();
}
#if defined(LORAWAN_COMPLIANCE_TEST)
/**
*
* Prepares the upload message to reserved ports
*
* \param port Application port
*/
void LoRaWANStack::prepare_special_tx_frame(uint8_t port)
{
if (port == 224) {
// Clear any normal message stuff before compliance test.
memset(&_tx_msg, 0, sizeof(_tx_msg));
if (_compliance_test.link_check == true) {
_compliance_test.link_check = false;
_compliance_test.state = 1;
_tx_msg.f_buffer_size = 3;
_tx_msg.f_buffer[0] = 5;
_tx_msg.f_buffer[1] = _compliance_test.demod_margin;
_tx_msg.f_buffer[2] = _compliance_test.nb_gateways;
} else {
switch (_compliance_test.state) {
case 4:
_compliance_test.state = 1;
_tx_msg.f_buffer_size = _compliance_test.app_data_size;
_tx_msg.f_buffer[0] = _compliance_test.app_data_buffer[0];
for(uint8_t i = 1; i < MIN(_compliance_test.app_data_size, MBED_CONF_LORA_TX_MAX_SIZE); ++i) {
_tx_msg.f_buffer[i] = _compliance_test.app_data_buffer[i];
}
break;
case 1:
_tx_msg.f_buffer_size = 2;
_tx_msg.f_buffer[0] = _compliance_test.downlink_counter >> 8;
_tx_msg.f_buffer[1] = _compliance_test.downlink_counter;
break;
}
}
}
}
/** Hands over the compliance test frame to MAC layer
*
* \return returns the state of the LoRa MAC
*/
lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
{
loramac_mcps_req_t mcps_req;
prepare_special_tx_frame(_compliance_test.app_port);
if (!_compliance_test.is_tx_confirmed) {
mcps_req.type = MCPS_UNCONFIRMED;
mcps_req.req.unconfirmed.fport = _compliance_test.app_port;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.req.unconfirmed.data_rate = _lora_phy.get_default_tx_datarate();
tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.f_buffer_size);
for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) {
tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]);
}
} else if (_compliance_test.is_tx_confirmed) {
mcps_req.type = MCPS_CONFIRMED;
mcps_req.req.confirmed.fport = _compliance_test.app_port;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.req.confirmed.nb_trials = _num_retry;
mcps_req.req.confirmed.data_rate = _lora_phy.get_default_tx_datarate();
tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.f_buffer_size);
for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) {
tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]);
}
} else {
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
return mcps_request_handler(&mcps_req);
}
#endif
uint16_t LoRaWANStack::check_possible_tx_size(uint16_t size)
{
loramac_tx_info_t tx_info;
@ -284,43 +200,45 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac()
mcps_req.type = _tx_msg.type;
if (MCPS_UNCONFIRMED == mcps_req.type) {
mcps_req.req.unconfirmed.fport = _tx_msg.message_u.unconfirmed.fport;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.fport = _tx_msg.fport;
mcps_req.nb_trials = 1;
mib_get_params.type = MIB_CHANNELS_DATARATE;
if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) {
tr_debug("Couldn't get MIB parameters: Using default data rate");
mcps_req.req.unconfirmed.data_rate = _lora_phy.get_default_tx_datarate();
mcps_req.data_rate = _lora_phy.get_default_tx_datarate();
} else {
mcps_req.req.unconfirmed.data_rate = mib_get_params.param.channel_data_rate;
mcps_req.data_rate = mib_get_params.param.channel_data_rate;
}
} else if (mcps_req.type == MCPS_CONFIRMED) {
mcps_req.req.confirmed.fport = _tx_msg.message_u.confirmed.fport;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.req.confirmed.nb_trials = _tx_msg.message_u.confirmed.nb_trials;
mcps_req.fport = _tx_msg.fport;
mcps_req.nb_trials = _tx_msg.nb_trials;
mib_get_params.type = MIB_CHANNELS_DATARATE;
if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) {
tr_debug("Couldn't get MIB parameters: Using default data rate");
mcps_req.req.confirmed.data_rate = _lora_phy.get_default_tx_datarate();
mcps_req.data_rate = _lora_phy.get_default_tx_datarate();
} else {
mcps_req.req.confirmed.data_rate = mib_get_params.param.channel_data_rate;
mcps_req.data_rate = mib_get_params.param.channel_data_rate;
}
} else if ( mcps_req.type == MCPS_PROPRIETARY) {
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.fport = 0;
mcps_req.nb_trials = 1;
mib_get_params.type = MIB_CHANNELS_DATARATE;
if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) {
tr_debug("Couldn't get MIB parameters: Using default data rate");
mcps_req.req.proprietary.data_rate = _lora_phy.get_default_tx_datarate();
mcps_req.data_rate = _lora_phy.get_default_tx_datarate();
} else {
mcps_req.req.proprietary.data_rate = mib_get_params.param.channel_data_rate;
mcps_req.data_rate = mib_get_params.param.channel_data_rate;
}
} else {
@ -651,7 +569,7 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
|| (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_PROPRIETARY) {
_tx_msg.type = MCPS_UNCONFIRMED;
_tx_msg.message_u.unconfirmed.fport = _app_port;
_tx_msg.fport = _app_port;
}
// Handles all confirmed messages, including proprietary and multicast
@ -660,8 +578,8 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
|| (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_PROPRIETARY) {
_tx_msg.type = MCPS_CONFIRMED;
_tx_msg.message_u.confirmed.fport = _app_port;
_tx_msg.message_u.confirmed.nb_trials = _num_retry;
_tx_msg.fport = _app_port;
_tx_msg.nb_trials = _num_retry;
}
tr_info("RTS = %u bytes, PEND = %u", _tx_msg.f_buffer_size, _tx_msg.pending_size);
@ -1357,3 +1275,89 @@ lorawan_status_t LoRaWANStack::lora_state_machine()
return status;
}
#if defined(LORAWAN_COMPLIANCE_TEST)
/**
*
* Prepares the upload message to reserved ports
*
* \param port Application port
*/
void LoRaWANStack::prepare_special_tx_frame(uint8_t port)
{
if (port == 224) {
// Clear any normal message stuff before compliance test.
memset(&_tx_msg, 0, sizeof(_tx_msg));
if (_compliance_test.link_check == true) {
_compliance_test.link_check = false;
_compliance_test.state = 1;
_tx_msg.f_buffer_size = 3;
_tx_msg.f_buffer[0] = 5;
_tx_msg.f_buffer[1] = _compliance_test.demod_margin;
_tx_msg.f_buffer[2] = _compliance_test.nb_gateways;
} else {
switch (_compliance_test.state) {
case 4:
_compliance_test.state = 1;
_tx_msg.f_buffer_size = _compliance_test.app_data_size;
_tx_msg.f_buffer[0] = _compliance_test.app_data_buffer[0];
for(uint8_t i = 1; i < MIN(_compliance_test.app_data_size, MBED_CONF_LORA_TX_MAX_SIZE); ++i) {
_tx_msg.f_buffer[i] = _compliance_test.app_data_buffer[i];
}
break;
case 1:
_tx_msg.f_buffer_size = 2;
_tx_msg.f_buffer[0] = _compliance_test.downlink_counter >> 8;
_tx_msg.f_buffer[1] = _compliance_test.downlink_counter;
break;
}
}
}
}
/** Hands over the compliance test frame to MAC layer
*
* \return returns the state of the LoRa MAC
*/
lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
{
loramac_mcps_req_t mcps_req;
prepare_special_tx_frame(_compliance_test.app_port);
if (!_compliance_test.is_tx_confirmed) {
mcps_req.type = MCPS_UNCONFIRMED;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.fport = _compliance_test.app_port;
mcps_req.nb_trials = 1;
mcps_req.data_rate = _lora_phy.get_default_tx_datarate();
tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.f_buffer_size);
for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) {
tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]);
}
} else if (_compliance_test.is_tx_confirmed) {
mcps_req.type = MCPS_CONFIRMED;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.fport = _compliance_test.app_port;
mcps_req.nb_trials = _num_retry;
mcps_req.data_rate = _lora_phy.get_default_tx_datarate();
tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.f_buffer_size);
for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) {
tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]);
}
} else {
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
return mcps_request_handler(&mcps_req);
}
#endif

View File

@ -77,6 +77,24 @@ SPDX-License-Identifier: BSD-3-Clause
#define LORAWAN_NETWORK_ID_MASK ( uint32_t )0xFE000000
class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
private:
/** End-device states.
*
*/
typedef enum device_states {
DEVICE_STATE_NOT_INITIALIZED,
DEVICE_STATE_INIT,
DEVICE_STATE_JOINING,
DEVICE_STATE_ABP_CONNECTING,
DEVICE_STATE_JOINED,
DEVICE_STATE_SEND,
DEVICE_STATE_IDLE,
#if defined(LORAWAN_COMPLIANCE_TEST)
DEVICE_STATE_COMPLIANCE_TEST,
#endif
DEVICE_STATE_SHUTDOWN
} device_states_t;
public:
static LoRaWANStack& get_lorawan_stack();
@ -424,6 +442,25 @@ private:
*/
uint16_t check_possible_tx_size(uint16_t size);
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 _app_port;
uint8_t _num_retry;
events::EventQueue *_queue;
bool _duty_cycle_on;
#if defined(LORAWAN_COMPLIANCE_TEST)
/**
* This function is used only for compliance testing
@ -439,28 +476,10 @@ private:
* Used only for compliance testing
*/
lorawan_status_t send_compliance_test_frame_to_mac();
#endif
LoRaWANTimeHandler _lora_time;
LoRaMac _loramac;
LoRaPHY_region _lora_phy;
loramac_primitives_t LoRaMacPrimitives;
#if defined(LORAWAN_COMPLIANCE_TEST)
uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE];
compliance_test_t _compliance_test;
#endif
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 _app_port;
uint8_t _num_retry;
events::EventQueue *_queue;
bool _duty_cycle_on;
};
#endif /* LORAWANSTACK_H_ */

View File

@ -1609,7 +1609,7 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
mlme.activate_mlme_subsystem(lora_phy);
// Activate MCPS subsystem
mcps.activate_mcps_subsystem(this, lora_phy);
mcps.activate_mcps_subsystem();
// Activate MIB subsystem
mib.activate_mib_subsystem(lora_phy);
@ -1955,7 +1955,60 @@ lorawan_status_t LoRaMac::mcps_request( loramac_mcps_req_t *mcpsRequest )
return LORAWAN_STATUS_BUSY;
}
lorawan_status_t status = mcps.set_request(mcpsRequest, &_params);
loramac_mhdr_t machdr;
int8_t datarate = mcpsRequest->data_rate;
// TODO: The comment is different than the code???
// Apply the minimum possible datarate.
// Some regions have limitations for the minimum datarate.
datarate = MAX(datarate, (int8_t)lora_phy->get_minimum_tx_datarate());
machdr.value = 0;
mcps.reset_confirmation();
_params.ack_timeout_retry_counter = 1;
_params.max_ack_timeout_retries = 1;
switch (mcpsRequest->type) {
case MCPS_UNCONFIRMED: {
machdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP;
break;
}
case MCPS_CONFIRMED: {
machdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP;
_params.max_ack_timeout_retries = mcpsRequest->nb_trials;
break;
}
case MCPS_PROPRIETARY: {
machdr.bits.mtype = FRAME_TYPE_PROPRIETARY;
break;
}
default:
return LORAWAN_STATUS_PARAMETER_INVALID;
}
// Filter fPorts
// TODO: Does not work with PROPRIETARY messages
// if( IsFPortAllowed( mcpsRequest->fport ) == false ) {
// return LORAWAN_STATUS_PARAMETER_INVALID;
// }
if (_params.sys_params.adr_on == false) {
if (lora_phy->verify_tx_datarate(datarate, false) == true) {
_params.sys_params.channel_data_rate = datarate;
} else {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
}
lorawan_status_t status = send(&machdr, mcpsRequest->fport, mcpsRequest->f_buffer,
mcpsRequest->f_buffer_size);
if (status == LORAWAN_STATUS_OK) {
mcps.get_confirmation().req_type = mcpsRequest->type;
_params.flags.bits.mcps_req = 1;
} else {
_params.is_node_ack_requested = false;
}
return status;
}

View File

@ -334,9 +334,9 @@ public:
*
* loramac_mcps_req_t request;
* request.type = MCPS_UNCONFIRMED;
* request.req.unconfirmed.fport = 1;
* request.req.unconfirmed.f_buffer = buffer;
* request.req.unconfirmed.f_buffer_size = sizeof(buffer);
* 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
@ -427,79 +427,7 @@ public:
*/
void open_continuous_rx2_window(void);
#if defined(LORAWAN_COMPLIANCE_TEST)
public: // Test interface
/**
* \brief LoRaMAC set tx timer.
*
* \details Sets up a timer for next transmission (application specific timers).
*
* \param [in] NextTxTime - Periodic time for next uplink.
* \retval `lorawan_status_t` The status of the operation. The possible values are:
* \ref LORAWAN_STATUS_OK
* \ref LORAWAN_STATUS_PARAMETER_INVALID
*/
lorawan_status_t LoRaMacSetTxTimer( uint32_t NextTxTime );
/**
* \brief LoRaMAC stop tx timer.
*
* \details Stops the next tx timer.
*
* \retval `lorawan_status_t` The status of the operation. The possible values are:
* \ref LORAWAN_STATUS_OK
* \ref LORAWAN_STATUS_PARAMETER_INVALID
*/
lorawan_status_t LoRaMacStopTxTimer( );
/**
* \brief Enabled or disables the reception windows
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] enable - Enabled or disables the reception windows
*/
void LoRaMacTestRxWindowsOn( bool enable );
/**
* \brief Enables the MIC field test
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] txPacketCounter - Fixed Tx packet counter value
*/
void LoRaMacTestSetMic( uint16_t txPacketCounter );
/**
* \brief Enabled or disables the duty cycle
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] enable - Enabled or disables the duty cycle
*/
void LoRaMacTestSetDutyCycleOn( bool enable );
/**
* \brief Sets the channel index
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] channel - Channel index
*/
void LoRaMacTestSetChannel( uint8_t channel );
private:
/**
* Timer to handle the application data transmission duty cycle
*/
timer_event_t tx_next_packet_timer;
#endif
private:
/**
@ -673,6 +601,80 @@ private:
* EventQueue object storage
*/
events::EventQueue *ev_queue;
#if defined(LORAWAN_COMPLIANCE_TEST)
public: // Test interface
/**
* \brief LoRaMAC set tx timer.
*
* \details Sets up a timer for next transmission (application specific timers).
*
* \param [in] NextTxTime - Periodic time for next uplink.
* \retval `lorawan_status_t` The status of the operation. The possible values are:
* \ref LORAWAN_STATUS_OK
* \ref LORAWAN_STATUS_PARAMETER_INVALID
*/
lorawan_status_t LoRaMacSetTxTimer( uint32_t NextTxTime );
/**
* \brief LoRaMAC stop tx timer.
*
* \details Stops the next tx timer.
*
* \retval `lorawan_status_t` The status of the operation. The possible values are:
* \ref LORAWAN_STATUS_OK
* \ref LORAWAN_STATUS_PARAMETER_INVALID
*/
lorawan_status_t LoRaMacStopTxTimer( );
/**
* \brief Enabled or disables the reception windows
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] enable - Enabled or disables the reception windows
*/
void LoRaMacTestRxWindowsOn( bool enable );
/**
* \brief Enables the MIC field test
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] txPacketCounter - Fixed Tx packet counter value
*/
void LoRaMacTestSetMic( uint16_t txPacketCounter );
/**
* \brief Enabled or disables the duty cycle
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] enable - Enabled or disables the duty cycle
*/
void LoRaMacTestSetDutyCycleOn( bool enable );
/**
* \brief Sets the channel index
*
* \details This is a test function. It shall be used for testing purposes only.
* Changing this attribute may lead to a non-conformance LoRaMac operation.
*
* \param [in] channel - Channel index
*/
void LoRaMacTestSetChannel( uint8_t channel );
private:
/**
* Timer to handle the application data transmission duty cycle
*/
timer_event_t tx_next_packet_timer;
#endif
};
#endif // MBED_LORAWAN_MAC_H__

View File

@ -27,7 +27,6 @@ SPDX-License-Identifier: BSD-3-Clause
#include "lorastack/mac/LoRaMacMcps.h"
LoRaMacMcps::LoRaMacMcps()
: _lora_mac(NULL), _lora_phy(NULL)
{
}
@ -35,6 +34,13 @@ 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;
@ -45,104 +51,7 @@ loramac_mcps_indication_t& LoRaMacMcps::get_indication()
return indication;
}
void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy)
void LoRaMacMcps::activate_mcps_subsystem()
{
_lora_mac = mac;
_lora_phy = phy;
}
lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
loramac_protocol_params *params)
{
if (mcpsRequest == NULL || _lora_phy == NULL || _lora_mac == NULL) {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
loramac_mhdr_t machdr;
uint8_t fport = 0;
void *fbuffer;
uint16_t fbuffer_size;
int8_t datarate = DR_0;
bool ready_to_send = false;
machdr.value = 0;
// Before performing any MCPS request, clear the confirmation structure
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
// ack_timeout_retry_counter must be reset every time a new request (unconfirmed or confirmed) is performed.
params->ack_timeout_retry_counter = 1;
switch (mcpsRequest->type) {
case MCPS_UNCONFIRMED: {
ready_to_send = true;
params->max_ack_timeout_retries = 1;
machdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP;
fport = mcpsRequest->req.unconfirmed.fport;
fbuffer = mcpsRequest->f_buffer;
fbuffer_size = mcpsRequest->f_buffer_size;
datarate = mcpsRequest->req.unconfirmed.data_rate;
break;
}
case MCPS_CONFIRMED: {
ready_to_send = true;
params->max_ack_timeout_retries = mcpsRequest->req.confirmed.nb_trials;
machdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP;
fport = mcpsRequest->req.confirmed.fport;
fbuffer = mcpsRequest->f_buffer;
fbuffer_size = mcpsRequest->f_buffer_size;
datarate = mcpsRequest->req.confirmed.data_rate;
break;
}
case MCPS_PROPRIETARY: {
ready_to_send = true;
params->max_ack_timeout_retries = 1;
machdr.bits.mtype = FRAME_TYPE_PROPRIETARY;
fbuffer = mcpsRequest->f_buffer;
fbuffer_size = mcpsRequest->f_buffer_size;
datarate = mcpsRequest->req.proprietary.data_rate;
break;
}
default:
break;
}
// Filter fPorts
// TODO: Does not work with PROPRIETARY messages
// if( IsFPortAllowed( fPort ) == false )
// {
// return LORAWAN_STATUS_PARAMETER_INVALID;
// }
// Apply the minimum possible datarate.
// Some regions have limitations for the minimum datarate.
datarate = MAX(datarate, (int8_t)_lora_phy->get_minimum_tx_datarate());
if (ready_to_send == true) {
if (params->sys_params.adr_on == false) {
if (_lora_phy->verify_tx_datarate(datarate, false) == true) {
params->sys_params.channel_data_rate = datarate;
} else {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
}
//nämä lora_maciin
status = _lora_mac->send(&machdr, fport, fbuffer, fbuffer_size);
if (status == LORAWAN_STATUS_OK) {
confirmation.req_type = mcpsRequest->type;
params->flags.bits.mcps_req = 1;
} else {
params->is_node_ack_requested = false;
}
}
return status;
}

View File

@ -49,6 +49,11 @@ public:
*/
~LoRaMacMcps();
/**
* @brief reset_confirmation Resets the confirmation struct
*/
void reset_confirmation();
/** Activating MCPS subsystem
*
* Stores pointers to MAC and PHY layer handles
@ -56,21 +61,7 @@ public:
* @param mac pointer to MAC layer
* @param phy pointer to PHY layer
*/
void activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy);
/** Sets up an MCPS Request
*
* Sets up an MCPS request and sends it through to the central MAC control.
* It also modifies or uses protocol information provided in the MAC
* protocol data structure.
*
* @param mcpsRequest pointer to MCPS request structure
* @param params pointer to MAC protocol parameters
*
* @return LORAWAN_STATUS_OK if everything goes well otherwise
* a negative error code is returned.
*/
lorawan_status_t set_request(loramac_mcps_req_t *mcpsRequest, loramac_protocol_params *params);
void activate_mcps_subsystem();
/** Grants access to MCPS confirmation data
*
@ -86,12 +77,6 @@ public:
private:
/**
* Pointers to MAC and PHY handles
*/
LoRaMac *_lora_mac;
LoRaPHY *_lora_phy;
/**
* Structure to hold MCPS indication data.
*/

View File

@ -49,6 +49,9 @@ public:
*/
~LoRaMacMlme();
/**
* @brief reset_confirmation Resets the confirmation struct
*/
void reset_confirmation();
/** Activating MLME subsystem

View File

@ -763,27 +763,14 @@ typedef enum {
} mcps_type_t;
/*!
* LoRaMAC MCPS-Request for an unconfirmed frame.
* LoRaMAC MCPS-Request structure.
*/
typedef struct {
/*!
* 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.
* MCPS-Request type.
*/
uint8_t fport;
mcps_type_t type;
/*!
* Uplink datarate, if ADR is off.
*/
int8_t data_rate;
} mcps_req_unconfirmed_t;
/*!
* LoRaMAC MCPS-Request for a confirmed frame.
*/
typedef struct {
/*!
* Frame port field. Must be set if the payload is not empty. Use the
* application-specific frame port values: [1...223].
@ -817,45 +804,6 @@ typedef struct {
* the datarate, if the LoRaMAC layer did not receive an acknowledgment.
*/
uint8_t nb_trials;
} mcps_req_confirmed_t;
/*!
* LoRaMAC MCPS-Request for a proprietary frame.
*/
typedef struct {
/*!
* Uplink datarate, if ADR is off.
*/
int8_t data_rate;
} mcps_req_proprietary_t;
/*!
* LoRaMAC MCPS-Request structure.
*/
typedef struct {
/*!
* MCPS-Request type.
*/
mcps_type_t type;
/*!
* MCPS-Request parameters.
*/
union
{
/*!
* MCPS-Request parameters for an unconfirmed frame.
*/
mcps_req_unconfirmed_t unconfirmed;
/*!
* MCPS-Request parameters for a confirmed frame.
*/
mcps_req_confirmed_t confirmed;
/*!
* MCPS-Request parameters for a proprietary frame.
*/
mcps_req_proprietary_t proprietary;
} req;
/** Payload data
*
@ -1663,23 +1611,6 @@ typedef struct {
mbed::Callback<void(loramac_mlme_indication_t*)> mlme_indication;
}loramac_primitives_t;
/** End-device states.
*
*/
typedef enum device_states {
DEVICE_STATE_NOT_INITIALIZED,
DEVICE_STATE_INIT,
DEVICE_STATE_JOINING,
DEVICE_STATE_ABP_CONNECTING,
DEVICE_STATE_JOINED,
DEVICE_STATE_SEND,
DEVICE_STATE_IDLE,
#if defined(LORAWAN_COMPLIANCE_TEST)
DEVICE_STATE_COMPLIANCE_TEST,
#endif
DEVICE_STATE_SHUTDOWN
} device_states_t;
/** Enum of LoRaWAN connection type.
*
* The LoRaWAN connection type specifies how an end-device connects to the gateway.
@ -1764,26 +1695,40 @@ typedef struct {
* Message type
*/
mcps_type_t type;
/** Message parameters.
/*!
* 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.
*/
union message {
/** An unconfirmed frame.
*
* The message parameters for an unconfirmed frame.
*/
mcps_req_unconfirmed_t unconfirmed;
/** A confirmed frame.
*
* The message parameters for a confirmed frame.
*/
mcps_req_confirmed_t confirmed;
/** A proprietary frame.
*
* The message parameters for a proprietary frame.
*/
mcps_req_proprietary_t proprietary;
} message_u;
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
*
@ -1918,54 +1863,6 @@ typedef struct {
uint32_t downlink_counter;
} lorawan_dev_commission_t;
#if defined(LORAWAN_COMPLIANCE_TEST)
/** LoRaWAN compliance tests support data
*
*/
typedef struct compliance_test {
/** Is test running
*
*/
bool running;
/** State of test
*
*/
uint8_t state;
/** Is TX confirmed
*
*/
bool is_tx_confirmed;
/** Port used by the application
*
*/
uint8_t app_port;
/** Maximum size of data used by application
*
*/
uint8_t app_data_size;
/** Data provided by application
*
*/
uint8_t *app_data_buffer;
/** Downlink counter
*
*/
uint16_t downlink_counter;
/** Is link check required
*
*/
bool link_check;
/** Demodulation margin
*
*/
uint8_t demod_margin;
/** Number of gateways
*
*/
uint8_t nb_gateways;
} compliance_test_t;
#endif
/** Structure containing the uplink status
*
*/
@ -2411,4 +2308,52 @@ typedef struct lora_channelplan {
loramac_channel_t *channels;
} lorawan_channelplan_t;
#if defined(LORAWAN_COMPLIANCE_TEST)
/** LoRaWAN compliance tests support data
*
*/
typedef struct compliance_test {
/** Is test running
*
*/
bool running;
/** State of test
*
*/
uint8_t state;
/** Is TX confirmed
*
*/
bool is_tx_confirmed;
/** Port used by the application
*
*/
uint8_t app_port;
/** Maximum size of data used by application
*
*/
uint8_t app_data_size;
/** Data provided by application
*
*/
uint8_t *app_data_buffer;
/** Downlink counter
*
*/
uint16_t downlink_counter;
/** Is link check required
*
*/
bool link_check;
/** Demodulation margin
*
*/
uint8_t demod_margin;
/** Number of gateways
*
*/
uint8_t nb_gateways;
} compliance_test_t;
#endif
#endif /* LORAWAN_SYSTEM_LORAWAN_DATA_STRUCTURES_H_ */