Skip to content

LoRa refactoring #6279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion features/lorawan/LoRaWANInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class LoRaWANInterface: public LoRaWANBase {
*
*/
LoRaWANInterface(LoRaRadio& radio);

virtual ~LoRaWANInterface();

/** Initialize the LoRa stack.
Expand All @@ -44,7 +45,7 @@ class LoRaWANInterface: public LoRaWANBase {
*
* @return 0 on success, a negative error code on failure.
*/
virtual lorawan_status_t initialize(events::EventQueue *ev_queue) ;
virtual lorawan_status_t initialize(events::EventQueue *ev_queue);

/** Connect OTAA or ABP using Mbed-OS config system
*
Expand Down
218 changes: 103 additions & 115 deletions features/lorawan/LoRaWANStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,15 @@ lorawan_status_t LoRaWANStack::set_application_port(uint8_t port)
LoRaWANStack::LoRaWANStack()
: _loramac(_lora_time), _lora_phy(_lora_time),
_device_current_state(DEVICE_STATE_NOT_INITIALIZED), _mac_handlers(NULL),
_num_retry(1), _queue(NULL), _duty_cycle_on(MBED_CONF_LORA_DUTY_CYCLE_ON)
_num_retry(1), _app_port(INVALID_PORT), _duty_cycle_on(MBED_CONF_LORA_DUTY_CYCLE_ON),
_queue(NULL)
{
#ifdef MBED_CONF_LORA_APP_PORT
// is_port_valid() is not virtual, so we can call it in constructor
if (is_port_valid(MBED_CONF_LORA_APP_PORT)) {
_app_port = MBED_CONF_LORA_APP_PORT;
} else {
tr_error("User defined port in .json is illegal.");
_app_port = INVALID_PORT;
}

#else
// initialize it to INVALID_PORT (255) an illegal port number.
// user should set the port
_app_port = INVALID_PORT;
#endif

memset(&_lw_session, 0, sizeof(_lw_session));
Expand Down Expand Up @@ -175,95 +169,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;

get_phy_params_t phy_params;
phy_param_t default_datarate;
phy_params.attribute = PHY_DEF_TX_DR;
default_datarate = _lora_phy.get_phy_params(&phy_params);

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 = default_datarate.value;

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 = default_datarate.value;

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;
Expand All @@ -286,51 +191,48 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac()
lorawan_status_t status;
loramac_mib_req_confirm_t mib_get_params;

get_phy_params_t phy_params;
phy_param_t default_datarate;
phy_params.attribute = PHY_DEF_TX_DR;
default_datarate = _lora_phy.get_phy_params(&phy_params);

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 = default_datarate.value;
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 = default_datarate.value;
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 = default_datarate.value;
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 {
Expand Down Expand Up @@ -661,7 +563,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
Expand All @@ -670,8 +572,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);
Expand Down Expand Up @@ -1367,3 +1269,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

54 changes: 36 additions & 18 deletions features/lorawan/LoRaWANStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -424,6 +442,24 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
*/
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 _num_retry;
uint8_t _app_port;
bool _duty_cycle_on;
events::EventQueue *_queue;

#if defined(LORAWAN_COMPLIANCE_TEST)
/**
* This function is used only for compliance testing
Expand All @@ -439,28 +475,10 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
* 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_ */
Loading