mirror of https://github.com/ARMmbed/mbed-os.git
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 refactorpull/6279/head
parent
37371df968
commit
2ac73a6cac
|
@ -34,6 +34,7 @@ public:
|
|||
*
|
||||
*/
|
||||
LoRaWANInterface(LoRaRadio& radio);
|
||||
|
||||
virtual ~LoRaWANInterface();
|
||||
|
||||
/** Initialize the LoRa stack.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -49,6 +49,9 @@ public:
|
|||
*/
|
||||
~LoRaMacMlme();
|
||||
|
||||
/**
|
||||
* @brief reset_confirmation Resets the confirmation struct
|
||||
*/
|
||||
void reset_confirmation();
|
||||
|
||||
/** Activating MLME subsystem
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue