mirror of https://github.com/ARMmbed/mbed-os.git
LoRaWANStack is made independent of MAC sublayers
- Only internal changes, no API has been broke. - Tested by manually running Green tea testspull/6411/head
parent
b63c98e103
commit
6b54478af4
|
@ -45,10 +45,6 @@ using namespace mbed;
|
|||
using namespace events;
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
/**
|
||||
*
|
||||
* User application data buffer size if compliance test is used
|
||||
*/
|
||||
#if (MBED_CONF_LORA_PHY == 0 || MBED_CONF_LORA_PHY == 4 || MBED_CONF_LORA_PHY == 6 || MBED_CONF_LORA_PHY == 7)
|
||||
#define LORAWAN_COMPLIANCE_TEST_DATA_SIZE 16
|
||||
#elif (MBED_CONF_LORA_PHY == 1 || MBED_CONF_LORA_PHY == 2 || MBED_CONF_LORA_PHY == 8 || MBED_CONF_LORA_PHY == 9)
|
||||
|
@ -134,39 +130,33 @@ lorawan_status_t LoRaWANStack::connect()
|
|||
|
||||
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;
|
||||
//TODO: LoRaWANStack don't need to know these values, move to LoRaMac (or below)
|
||||
#if (1 == 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;
|
||||
|
||||
return join_request_by_otaa(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);
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* 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 join_request_by_otaa(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);
|
||||
|
||||
return activation_by_personalization(connection_params);
|
||||
}
|
||||
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 activation_by_personalization(connection_params);
|
||||
#endif
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
|
||||
|
@ -315,14 +305,7 @@ lorawan_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled)
|
|||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
//return _loramac.enable_adaptive_datarate(adr_enabled);
|
||||
|
||||
loramac_mib_req_confirm_t adr_mib_params;
|
||||
|
||||
adr_mib_params.type = MIB_ADR;
|
||||
adr_mib_params.param.is_adr_enable = adr_enabled;
|
||||
|
||||
return mib_set_request(&adr_mib_params);
|
||||
return _loramac.enable_adaptive_datarate(adr_enabled);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate)
|
||||
|
@ -333,23 +316,9 @@ lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate)
|
|||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
loramac_mib_req_confirm_t mib_params;
|
||||
mib_params.type = MIB_ADR;
|
||||
if (mib_get_request(&mib_params) != LORAWAN_STATUS_OK) {
|
||||
tr_error("Cannot set data rate. Please turn off ADR first.");
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
mib_params.type = MIB_CHANNELS_DATARATE;
|
||||
mib_params.param.channel_data_rate = data_rate;
|
||||
|
||||
return mib_set_request(&mib_params);
|
||||
return _loramac.set_channel_data_rate(data_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Join OTAA
|
||||
*/
|
||||
lorawan_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t ¶ms)
|
||||
{
|
||||
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state)
|
||||
|
@ -375,10 +344,6 @@ lorawan_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t &par
|
|||
return lora_state_machine(DEVICE_STATE_JOINING);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Connect ABP
|
||||
*/
|
||||
lorawan_status_t LoRaWANStack::activation_by_personalization(const lorawan_connect_t ¶ms)
|
||||
{
|
||||
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
|
||||
|
@ -435,16 +400,10 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
|
|||
}
|
||||
#endif
|
||||
|
||||
//TODO: Stack MUST know joining status!!!!
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
lorawan_status_t status;
|
||||
mib_req.type = MIB_NETWORK_JOINED;
|
||||
status = mib_get_request(&mib_req);
|
||||
|
||||
if (status == LORAWAN_STATUS_OK) {
|
||||
if (mib_req.param.is_nwk_joined == false) {
|
||||
return LORAWAN_STATUS_NO_NETWORK_JOINED;
|
||||
}
|
||||
if (_loramac.nwk_joined() == false) {
|
||||
return LORAWAN_STATUS_NO_NETWORK_JOINED;
|
||||
}
|
||||
|
||||
status = set_application_port(port);
|
||||
|
@ -454,8 +413,8 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
|
|||
return status;
|
||||
}
|
||||
|
||||
if (flags == 0
|
||||
|| (flags & MSG_FLAG_MASK) == (MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG)) {
|
||||
if (flags == 0 ||
|
||||
(flags & MSG_FLAG_MASK) == (MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG)) {
|
||||
tr_error("CONFIRMED and UNCONFIRMED are mutually exclusive for send()");
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
@ -552,19 +511,8 @@ int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data,
|
|||
return base_size;
|
||||
}
|
||||
|
||||
/** MLME-Confirm event function
|
||||
*
|
||||
* \param mlme_confirm Pointer to the confirm structure,
|
||||
* containing confirm attributes.
|
||||
*/
|
||||
void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
|
||||
{
|
||||
if (NULL == mlme_confirm) {
|
||||
tr_error("mlme_confirm: struct [in] is null!");
|
||||
MBED_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mlme_confirm->req_type) {
|
||||
case MLME_JOIN:
|
||||
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||
|
@ -613,37 +561,13 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
|
|||
}
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_request)
|
||||
{
|
||||
if (mcps_request == NULL) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return _loramac.mcps_request(mcps_request);
|
||||
}
|
||||
|
||||
/** MCPS-Confirm event function
|
||||
*
|
||||
* \param mcps_confirm Pointer to the confirm structure,
|
||||
* containing confirm attributes.
|
||||
*/
|
||||
void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
|
||||
{
|
||||
if (mcps_confirm == NULL) {
|
||||
tr_error("mcps_confirm: struct [in] is null!");
|
||||
MBED_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mcps_confirm->status != LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||
// Couldn't schedule packet, ack not recieved in CONFIRMED case
|
||||
// or some other error happened. Discard buffer, unset the tx-ongoing
|
||||
// flag and let the application know
|
||||
_loramac.reset_ongoing_tx();
|
||||
|
||||
tr_error("mcps_confirm_handler: Error code = %d", mcps_confirm->status);
|
||||
|
||||
// If sending timed out, we have a special event for that
|
||||
if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) {
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, TX_TIMEOUT);
|
||||
|
@ -651,11 +575,10 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
|
|||
(void)ret;
|
||||
}
|
||||
return;
|
||||
} if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) {
|
||||
} else if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) {
|
||||
tr_debug("Did not receive Ack");
|
||||
}
|
||||
|
||||
// Otherwise send a general TX_ERROR event
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, TX_ERROR);
|
||||
MBED_ASSERT(ret != 0);
|
||||
|
@ -664,20 +587,11 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
|
|||
return;
|
||||
}
|
||||
|
||||
// If No errors encountered, let's proceed with the status.
|
||||
// CONFIRMED needs special handling because of acks
|
||||
if (mcps_confirm->req_type == MCPS_CONFIRMED) {
|
||||
// In confirmed case, we need to check if we have received the Ack or not.
|
||||
// This is actually just being paranoid about ack because LoRaMac.cpp doesn't
|
||||
// call this callback until an ack is received.
|
||||
if (mcps_confirm->ack_received) {
|
||||
if (mcps_confirm->req_type == MCPS_CONFIRMED &&
|
||||
mcps_confirm->ack_received) {
|
||||
tr_debug("Ack received.");
|
||||
}
|
||||
}
|
||||
|
||||
// This part is common to both CONFIRMED and UNCONFIRMED.
|
||||
// Tell the application about successful transmission and store
|
||||
// data rate plus frame counter.
|
||||
_lw_session.uplink_counter = mcps_confirm->ul_frame_counter;
|
||||
_loramac.set_tx_ongoing(false);
|
||||
if (_callbacks.events) {
|
||||
|
@ -687,18 +601,8 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
|
|||
}
|
||||
}
|
||||
|
||||
/** MCPS-Indication event function
|
||||
*
|
||||
* \param mcps_indication Pointer to the indication structure,
|
||||
* containing indication attributes.
|
||||
*/
|
||||
void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indication)
|
||||
{
|
||||
if (mcps_indication == NULL) {
|
||||
tr_error("mcps_indication: struct [in] is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mcps_indication->status != LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, RX_ERROR);
|
||||
|
@ -721,6 +625,7 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
|
|||
break;
|
||||
}
|
||||
|
||||
//TODO:
|
||||
// Check Multicast
|
||||
// Check Port
|
||||
// Check Datarate
|
||||
|
@ -741,80 +646,63 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
|
|||
|
||||
if (mcps_indication->is_data_recvd == true) {
|
||||
switch (mcps_indication->port) {
|
||||
case 224:
|
||||
case 224: {
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
tr_debug("Compliance test command received.");
|
||||
compliance_test_handler(mcps_indication);
|
||||
tr_debug("Compliance test command received.");
|
||||
compliance_test_handler(mcps_indication);
|
||||
#else
|
||||
tr_debug("Compliance test disabled.");
|
||||
tr_info("Compliance test disabled.");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
if (is_port_valid(mcps_indication->port) == true ||
|
||||
mcps_indication->type == MCPS_PROPRIETARY) {
|
||||
|
||||
// Valid message arrived.
|
||||
_rx_msg.type = LORAMAC_RX_MCPS_INDICATION;
|
||||
_rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size;
|
||||
_rx_msg.msg.mcps_indication.port = mcps_indication->port;
|
||||
|
||||
// no copy, just set the pointer for the user
|
||||
_rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer;
|
||||
|
||||
// Notify application about received frame..
|
||||
tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size);
|
||||
_rx_msg.receive_ready = true;
|
||||
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, RX_DONE);
|
||||
MBED_ASSERT(ret != 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
mib_req.type = MIB_DEVICE_CLASS;
|
||||
mib_get_request(&mib_req);
|
||||
|
||||
// If fPending bit is set we try to generate an empty packet
|
||||
// with CONFIRMED flag set. We always set a CONFIRMED flag so
|
||||
// that we could retry a certain number of times if the uplink
|
||||
// failed for some reason
|
||||
if (mcps_indication->fpending_status && mib_req.param.dev_class != CLASS_C) {
|
||||
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
|
||||
}
|
||||
|
||||
// Class C and node received a confirmed message so we need to
|
||||
// send an empty packet to acknowledge the message.
|
||||
// This scenario is unspecified by LoRaWAN 1.0.2 specification,
|
||||
// but version 1.1.0 says that network SHALL not send any new
|
||||
// confirmed messages until ack has been sent
|
||||
if (mib_req.param.dev_class == CLASS_C && mcps_indication->type == MCPS_CONFIRMED) {
|
||||
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
|
||||
}
|
||||
} else {
|
||||
// Invalid port, ports 0, 224 and 225-255 are reserved.
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (is_port_valid(mcps_indication->port) == true ||
|
||||
mcps_indication->type == MCPS_PROPRIETARY) {
|
||||
|
||||
// Valid message arrived.
|
||||
_rx_msg.type = LORAMAC_RX_MCPS_INDICATION;
|
||||
_rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size;
|
||||
_rx_msg.msg.mcps_indication.port = mcps_indication->port;
|
||||
_rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer;
|
||||
|
||||
// Notify application about received frame..
|
||||
tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size);
|
||||
_rx_msg.receive_ready = true;
|
||||
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, RX_DONE);
|
||||
MBED_ASSERT(ret != 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
//TODO: below if clauses can be combined,
|
||||
// because those are calling same function with same parameters
|
||||
|
||||
// If fPending bit is set we try to generate an empty packet
|
||||
// with CONFIRMED flag set. We always set a CONFIRMED flag so
|
||||
// that we could retry a certain number of times if the uplink
|
||||
// failed for some reason
|
||||
if (_loramac.get_device_class() != CLASS_C && mcps_indication->fpending_status) {
|
||||
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
|
||||
}
|
||||
|
||||
// Class C and node received a confirmed message so we need to
|
||||
// send an empty packet to acknowledge the message.
|
||||
// This scenario is unspecified by LoRaWAN 1.0.2 specification,
|
||||
// but version 1.1.0 says that network SHALL not send any new
|
||||
// confirmed messages until ack has been sent
|
||||
if (_loramac.get_device_class() == CLASS_C && mcps_indication->type == MCPS_CONFIRMED) {
|
||||
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
|
||||
}
|
||||
} else {
|
||||
// Invalid port, ports 0, 224 and 225-255 are reserved.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::mib_set_request(loramac_mib_req_confirm_t *mib_set_params)
|
||||
{
|
||||
if (NULL == mib_set_params) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
return _loramac.mib_set_request_confirm(mib_set_params);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_get_params)
|
||||
{
|
||||
if(NULL == mib_get_params) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
return _loramac.mib_get_request_confirm(mib_get_params);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::set_link_check_request()
|
||||
{
|
||||
_link_check_requested = true;
|
||||
|
@ -823,9 +711,8 @@ lorawan_status_t LoRaWANStack::set_link_check_request()
|
|||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
loramac_mlme_req_t mlme_req;
|
||||
mlme_req.type = MLME_LINK_CHECK;
|
||||
return _loramac.mlme_request(&mlme_req);
|
||||
_loramac.setup_link_check_request();
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
void LoRaWANStack::remove_link_check_request()
|
||||
|
@ -838,17 +725,17 @@ lorawan_status_t LoRaWANStack::shutdown()
|
|||
return lora_state_machine(DEVICE_STATE_SHUTDOWN);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::set_device_class(const device_class_t device_class)
|
||||
lorawan_status_t LoRaWANStack::set_device_class(const device_class_t& device_class)
|
||||
{
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
mib_req.type = MIB_DEVICE_CLASS;
|
||||
mib_req.param.dev_class = device_class;
|
||||
return mib_set_request(&mib_req);
|
||||
if (device_class == CLASS_B) {
|
||||
return LORAWAN_STATUS_UNSUPPORTED;
|
||||
}
|
||||
_loramac.set_device_class(device_class);
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
||||
{
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
lorawan_status_t status = LORAWAN_STATUS_DEVICE_OFF;
|
||||
|
||||
_device_current_state = new_state;
|
||||
|
@ -860,19 +747,13 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
* Radio will be put to sleep by the APIs underneath
|
||||
*/
|
||||
drop_channel_list();
|
||||
|
||||
// Shutdown LoRaMac
|
||||
_loramac.disconnect();
|
||||
|
||||
// Stop sending messages and set joined status to false.
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
_loramac.LoRaMacStopTxTimer();
|
||||
#endif
|
||||
mib_req.type = MIB_NETWORK_JOINED;
|
||||
mib_req.param.is_nwk_joined = false;
|
||||
mib_set_request(&mib_req);
|
||||
_loramac.set_nwk_joined(false);
|
||||
|
||||
// reset buffers to original state
|
||||
_loramac.reset_ongoing_tx(true);
|
||||
|
||||
_rx_msg.msg.mcps_indication.buffer = NULL;
|
||||
|
@ -880,7 +761,6 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
_rx_msg.prev_read_size = 0;
|
||||
_rx_msg.msg.mcps_indication.buffer_size = 0;
|
||||
|
||||
// disable the session
|
||||
_lw_session.active = false;
|
||||
|
||||
tr_debug("LoRaWAN protocol has been shut down.");
|
||||
|
@ -892,7 +772,6 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
status = LORAWAN_STATUS_DEVICE_OFF;
|
||||
break;
|
||||
case DEVICE_STATE_NOT_INITIALIZED:
|
||||
// Device is disconnected.
|
||||
status = LORAWAN_STATUS_DEVICE_OFF;
|
||||
break;
|
||||
case DEVICE_STATE_INIT:
|
||||
|
@ -900,25 +779,13 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
break;
|
||||
case DEVICE_STATE_JOINING:
|
||||
if (_lw_session.connection.connect_type == LORAWAN_CONNECTION_OTAA) {
|
||||
/*
|
||||
* OTAA join
|
||||
*/
|
||||
tr_debug("Send Join-request..");
|
||||
loramac_mlme_req_t mlme_req;
|
||||
mlme_req.type = MLME_JOIN;
|
||||
|
||||
mlme_req.req.join.dev_eui = _lw_session.connection.connection_u.otaa.dev_eui;
|
||||
mlme_req.req.join.app_eui = _lw_session.connection.connection_u.otaa.app_eui;
|
||||
mlme_req.req.join.app_key = _lw_session.connection.connection_u.otaa.app_key;
|
||||
mlme_req.req.join.nb_trials = _lw_session.connection.connection_u.otaa.nb_trials;
|
||||
|
||||
// Send join request to server.
|
||||
status = _loramac.mlme_request(&mlme_req);
|
||||
status = _loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
|
||||
if (status != LORAWAN_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
// Otherwise request was successful and OTAA connect is in
|
||||
//progress
|
||||
|
||||
return LORAWAN_STATUS_CONNECT_IN_PROGRESS;
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
|
@ -926,9 +793,9 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
break;
|
||||
case DEVICE_STATE_JOINED:
|
||||
tr_debug("Join OK!");
|
||||
// Session is now active
|
||||
|
||||
_lw_session.active = true;
|
||||
// Tell the application that we are connected
|
||||
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, CONNECTED);
|
||||
MBED_ASSERT(ret != 0);
|
||||
|
@ -937,34 +804,13 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
status = LORAWAN_STATUS_OK;
|
||||
break;
|
||||
case DEVICE_STATE_ABP_CONNECTING:
|
||||
/*
|
||||
* ABP connection
|
||||
*/
|
||||
mib_req.type = MIB_NET_ID;
|
||||
mib_req.param.net_id = _lw_session.connection.connection_u.abp.nwk_id;
|
||||
mib_set_request(&mib_req);
|
||||
|
||||
mib_req.type = MIB_DEV_ADDR;
|
||||
mib_req.param.dev_addr = _lw_session.connection.connection_u.abp.dev_addr;
|
||||
mib_set_request(&mib_req);
|
||||
_loramac.join_by_abp(_lw_session.connection.connection_u.abp);
|
||||
|
||||
mib_req.type = MIB_NWK_SKEY;
|
||||
mib_req.param.nwk_skey = _lw_session.connection.connection_u.abp.nwk_skey;
|
||||
mib_set_request(&mib_req);
|
||||
|
||||
mib_req.type = MIB_APP_SKEY;
|
||||
mib_req.param.app_skey = _lw_session.connection.connection_u.abp.app_skey;
|
||||
mib_set_request(&mib_req);
|
||||
|
||||
mib_req.type = MIB_NETWORK_JOINED;
|
||||
mib_req.param.is_nwk_joined = true;
|
||||
mib_set_request(&mib_req);
|
||||
tr_debug("ABP Connection OK!");
|
||||
// tell the application we are okay
|
||||
// if users provide wrong keys, it's their responsibility
|
||||
// there is no way to test ABP authentication success
|
||||
|
||||
status = LORAWAN_STATUS_OK;
|
||||
// Session is now active
|
||||
|
||||
_lw_session.active = true;
|
||||
if (_callbacks.events) {
|
||||
const int ret = _queue->call(_callbacks.events, CONNECTED);
|
||||
|
@ -973,7 +819,6 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
}
|
||||
break;
|
||||
case DEVICE_STATE_SEND:
|
||||
// If a transmission is ongoing, don't interrupt
|
||||
if (_loramac.tx_ongoing()) {
|
||||
status = LORAWAN_STATUS_OK;
|
||||
} else {
|
||||
|
@ -1002,20 +847,17 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
|||
break;
|
||||
}
|
||||
}
|
||||
// otherwise all done, put device in idle state
|
||||
|
||||
_device_current_state = DEVICE_STATE_IDLE;
|
||||
break;
|
||||
case DEVICE_STATE_IDLE:
|
||||
//Do nothing
|
||||
status = LORAWAN_STATUS_IDLE;
|
||||
break;
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
case DEVICE_STATE_COMPLIANCE_TEST:
|
||||
//Device is in compliance test mode
|
||||
tr_debug("Device is in compliance test mode.");
|
||||
|
||||
//5000ms
|
||||
_loramac.LoRaMacSetTxTimer(5000);
|
||||
_loramac.LoRaMacSetTxTimer(5000); //ms
|
||||
if (_compliance_test.running == true) {
|
||||
send_compliance_test_frame_to_mac();
|
||||
}
|
||||
|
@ -1104,11 +946,15 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
|
|||
return mcps_request_handler(&mcps_req);
|
||||
}
|
||||
|
||||
/** Compliance testing function
|
||||
*
|
||||
* \param mcps_indication Pointer to the indication structure,
|
||||
* containing indication attributes.
|
||||
*/
|
||||
lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_request)
|
||||
{
|
||||
if (mcps_request == NULL) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return _loramac.mcps_request(mcps_request);
|
||||
}
|
||||
|
||||
void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indication)
|
||||
{
|
||||
if (_compliance_test.running == false) {
|
||||
|
@ -1128,10 +974,7 @@ void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indic
|
|||
_compliance_test.running = true;
|
||||
_compliance_test.state = 1;
|
||||
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
mib_req.type = MIB_ADR;
|
||||
mib_req.param.is_adr_enable = true;
|
||||
mib_set_request(&mib_req);
|
||||
_loramac.enable_adaptive_datarate(true);
|
||||
|
||||
#if MBED_CONF_LORA_PHY == 0
|
||||
_loramac.LoRaMacTestSetDutyCycleOn(false);
|
||||
|
@ -1154,10 +997,8 @@ void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indic
|
|||
_compliance_test.downlink_counter = 0;
|
||||
_compliance_test.running = false;
|
||||
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
mib_req.type = MIB_ADR;
|
||||
mib_req.param.is_adr_enable = MBED_CONF_LORA_ADR_ON;
|
||||
mib_set_request(&mib_req);
|
||||
_loramac.enable_adaptive_datarate(MBED_CONF_LORA_ADR_ON);
|
||||
|
||||
#if MBED_CONF_LORA_PHY == 0
|
||||
_loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON);
|
||||
#endif
|
||||
|
@ -1191,13 +1032,10 @@ void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indic
|
|||
send_compliance_test_frame_to_mac();
|
||||
break;
|
||||
case 5: // (viii)
|
||||
loramac_mlme_req_t mlme_req;
|
||||
mlme_req.type = MLME_LINK_CHECK;
|
||||
_loramac.mlme_request(&mlme_req);
|
||||
_loramac.setup_link_check_request();
|
||||
break;
|
||||
case 6: // (ix)
|
||||
loramac_mlme_req_t mlme_request;
|
||||
loramac_mib_req_confirm_t mib_request;
|
||||
loramac_mlme_req_t mlme_req;
|
||||
|
||||
// Disable TestMode and revert back to normal operation
|
||||
_compliance_test.is_tx_confirmed = true;
|
||||
|
@ -1206,32 +1044,26 @@ void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indic
|
|||
_compliance_test.downlink_counter = 0;
|
||||
_compliance_test.running = false;
|
||||
|
||||
mib_request.type = MIB_ADR;
|
||||
mib_request.param.is_adr_enable = MBED_CONF_LORA_ADR_ON;
|
||||
mib_set_request(&mib_request);
|
||||
_loramac.enable_adaptive_datarate(MBED_CONF_LORA_ADR_ON);
|
||||
|
||||
#if MBED_CONF_LORA_PHY == 0
|
||||
_loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON);
|
||||
#endif
|
||||
mlme_request.type = MLME_JOIN;
|
||||
mlme_request.req.join.dev_eui = _lw_session.connection.connection_u.otaa.dev_eui;
|
||||
mlme_request.req.join.app_eui = _lw_session.connection.connection_u.otaa.app_eui;
|
||||
mlme_request.req.join.app_key = _lw_session.connection.connection_u.otaa.app_key;
|
||||
mlme_request.req.join.nb_trials = _lw_session.connection.connection_u.otaa.nb_trials;
|
||||
_loramac.mlme_request(&mlme_request);
|
||||
_loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
|
||||
break;
|
||||
case 7: // (x)
|
||||
if (mcps_indication->buffer_size == 3) {
|
||||
loramac_mlme_req_t mlme_req;
|
||||
mlme_req.type = MLME_TXCW;
|
||||
mlme_req.req.cw_tx_mode.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]);
|
||||
mlme_req.cw_tx_mode.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]);
|
||||
_loramac.mlme_request(&mlme_req);
|
||||
} else if (mcps_indication->buffer_size == 7) {
|
||||
loramac_mlme_req_t mlme_req;
|
||||
mlme_req.type = MLME_TXCW_1;
|
||||
mlme_req.req.cw_tx_mode.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]);
|
||||
mlme_req.req.cw_tx_mode.frequency = (uint32_t)((mcps_indication->buffer[3] << 16) | (mcps_indication->buffer[4] << 8)
|
||||
mlme_req.cw_tx_mode.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]);
|
||||
mlme_req.cw_tx_mode.frequency = (uint32_t)((mcps_indication->buffer[3] << 16) | (mcps_indication->buffer[4] << 8)
|
||||
| mcps_indication->buffer[5]) * 100;
|
||||
mlme_req.req.cw_tx_mode.power = mcps_indication->buffer[6];
|
||||
mlme_req.cw_tx_mode.power = mcps_indication->buffer[6];
|
||||
_loramac.mlme_request(&mlme_req);
|
||||
}
|
||||
_compliance_test.state = 1;
|
||||
|
|
|
@ -371,7 +371,7 @@ public:
|
|||
* 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);
|
||||
lorawan_status_t set_device_class(const device_class_t& device_class);
|
||||
|
||||
private:
|
||||
LoRaWANStack();
|
||||
|
@ -401,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,
|
||||
|
@ -424,16 +417,6 @@ 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
|
||||
*/
|
||||
|
@ -488,6 +471,11 @@ private:
|
|||
*/
|
||||
void compliance_test_handler(loramac_mcps_indication_t *mcps_indication);
|
||||
|
||||
/**
|
||||
* Used only for compliance testing
|
||||
*/
|
||||
lorawan_status_t mcps_request_handler(loramac_mcps_req_t *mcps_request);
|
||||
|
||||
/**
|
||||
* Used only for compliance testing
|
||||
*/
|
||||
|
|
|
@ -78,7 +78,7 @@ using namespace events;
|
|||
|
||||
|
||||
LoRaMac::LoRaMac()
|
||||
: _lora_phy(_lora_time), mac_commands()
|
||||
: _lora_phy(_lora_time), mac_commands(), _is_nwk_joined(false)
|
||||
{
|
||||
//radio_events_t RadioEvents;
|
||||
_params.keys.dev_eui = NULL;
|
||||
|
@ -98,7 +98,6 @@ LoRaMac::LoRaMac()
|
|||
_params.dl_frame_counter = 0;
|
||||
_params.is_ul_frame_counter_fixed = false;
|
||||
_params.is_rx_window_enabled = true;
|
||||
_params.is_nwk_joined = false;
|
||||
_params.adr_ack_counter = 0;
|
||||
_params.is_node_ack_requested = false;
|
||||
_params.is_srv_ack_requested = false;
|
||||
|
@ -187,7 +186,7 @@ void LoRaMac::on_radio_tx_done( void )
|
|||
lorawan_time_t cur_time = _lora_time.get_current_time( );
|
||||
loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation();
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_lora_phy.put_radio_to_sleep();
|
||||
} else {
|
||||
open_continuous_rx2_window();
|
||||
|
@ -197,11 +196,11 @@ void LoRaMac::on_radio_tx_done( void )
|
|||
if(_params.is_rx_window_enabled == true) {
|
||||
_lora_time.start(_params.timers.rx_window1_timer, _params.rx_window1_delay);
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_lora_time.start(_params.timers.rx_window2_timer, _params.rx_window2_delay);
|
||||
}
|
||||
|
||||
if ((_params.dev_class == CLASS_C ) ||
|
||||
if ((_device_class == CLASS_C ) ||
|
||||
(_params.is_node_ack_requested == true)) {
|
||||
_lora_time.start(_params.timers.ack_timeout_timer,
|
||||
_params.rx_window2_delay + _lora_phy.get_ack_timeout());
|
||||
|
@ -230,7 +229,7 @@ void LoRaMac::on_radio_tx_done( void )
|
|||
|
||||
// Update last tx done time for the current channel
|
||||
tx_done_params.channel = _params.channel;
|
||||
tx_done_params.joined = _params.is_nwk_joined;
|
||||
tx_done_params.joined = _is_nwk_joined;
|
||||
tx_done_params.last_tx_done_time = cur_time;
|
||||
_lora_phy.set_last_tx_done(&tx_done_params);
|
||||
|
||||
|
@ -301,7 +300,7 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
mcps.get_indication().dl_frame_counter = 0;
|
||||
mcps.get_indication().type = MCPS_UNCONFIRMED;
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_lora_phy.put_radio_to_sleep();
|
||||
}
|
||||
|
||||
|
@ -312,7 +311,7 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
switch (mac_hdr.bits.mtype) {
|
||||
|
||||
case FRAME_TYPE_JOIN_ACCEPT:
|
||||
if (_params.is_nwk_joined == true) {
|
||||
if (_is_nwk_joined) {
|
||||
mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
prepare_rx_done_abort();
|
||||
return;
|
||||
|
@ -380,7 +379,7 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
_lora_phy.apply_cf_list(&cflist);
|
||||
|
||||
mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
_params.is_nwk_joined = true;
|
||||
_is_nwk_joined = true;
|
||||
} else {
|
||||
mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
|
||||
}
|
||||
|
@ -660,7 +659,7 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
}
|
||||
|
||||
// Verify if we need to disable the AckTimeoutTimer
|
||||
check_to_disable_ack_timeout(_params.is_node_ack_requested, _params.dev_class, mcps.get_confirmation().ack_received,
|
||||
check_to_disable_ack_timeout(_params.is_node_ack_requested, _device_class, mcps.get_confirmation().ack_received,
|
||||
_params.ack_timeout_retry_counter, _params.max_ack_timeout_retries );
|
||||
|
||||
if(_params.timers.ack_timeout_timer.timer_id == 0) {
|
||||
|
@ -672,7 +671,7 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
|
||||
void LoRaMac::on_radio_tx_timeout( void )
|
||||
{
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_lora_phy.put_radio_to_sleep();
|
||||
} else {
|
||||
open_continuous_rx2_window();
|
||||
|
@ -687,7 +686,7 @@ void LoRaMac::on_radio_tx_timeout( void )
|
|||
|
||||
void LoRaMac::on_radio_rx_error( void )
|
||||
{
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_lora_phy.put_radio_to_sleep();
|
||||
}
|
||||
|
||||
|
@ -698,7 +697,7 @@ void LoRaMac::on_radio_rx_error( void )
|
|||
|
||||
mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR;
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time) >= _params.rx_window2_delay) {
|
||||
_lora_time.stop(_params.timers.rx_window2_timer);
|
||||
_params.flags.bits.mac_done = 1;
|
||||
|
@ -711,19 +710,19 @@ void LoRaMac::on_radio_rx_error( void )
|
|||
|
||||
mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_params.flags.bits.mac_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_params.dev_class == CLASS_C) {
|
||||
if (_device_class == CLASS_C) {
|
||||
open_continuous_rx2_window();
|
||||
}
|
||||
}
|
||||
|
||||
void LoRaMac::on_radio_rx_timeout(void)
|
||||
{
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_lora_phy.put_radio_to_sleep();
|
||||
}
|
||||
|
||||
|
@ -733,7 +732,7 @@ void LoRaMac::on_radio_rx_timeout(void)
|
|||
}
|
||||
mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT;
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay) {
|
||||
_lora_time.stop(_params.timers.rx_window2_timer);
|
||||
_params.flags.bits.mac_done = 1;
|
||||
|
@ -746,12 +745,12 @@ void LoRaMac::on_radio_rx_timeout(void)
|
|||
|
||||
mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_params.flags.bits.mac_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_params.dev_class == CLASS_C) {
|
||||
if (_device_class == CLASS_C) {
|
||||
open_continuous_rx2_window();
|
||||
}
|
||||
}
|
||||
|
@ -936,7 +935,7 @@ void LoRaMac::on_mac_state_check_timer_event(void)
|
|||
if (_params.flags.bits.mcps_ind == 1) {
|
||||
_params.flags.bits.mcps_ind = 0;
|
||||
|
||||
if (_params.dev_class == CLASS_C) {
|
||||
if (_device_class == CLASS_C) {
|
||||
// Activate RX2 window for Class C
|
||||
open_continuous_rx2_window();
|
||||
}
|
||||
|
@ -1003,7 +1002,7 @@ void LoRaMac::on_rx_window1_timer_event(void)
|
|||
_params.rx_window1_config.is_rx_continuous = false;
|
||||
_params.rx_window1_config.rx_slot = _params.rx_slot;
|
||||
|
||||
if (_params.dev_class == CLASS_C) {
|
||||
if (_device_class == CLASS_C) {
|
||||
_lora_phy.put_radio_to_standby();
|
||||
}
|
||||
|
||||
|
@ -1024,7 +1023,7 @@ void LoRaMac::on_rx_window2_timer_event(void)
|
|||
_params.rx_window2_config.is_repeater_supported = _params.is_repeater_supported;
|
||||
_params.rx_window2_config.rx_slot = RX_SLOT_WIN_2;
|
||||
|
||||
if (_params.dev_class != CLASS_C) {
|
||||
if (_device_class != CLASS_C) {
|
||||
_params.rx_window2_config.is_rx_continuous = false;
|
||||
} else {
|
||||
// Setup continuous listening for class c
|
||||
|
@ -1082,7 +1081,7 @@ void LoRaMac::on_ack_timeout_timer_event(void)
|
|||
_params.is_ack_retry_timeout_expired = true;
|
||||
_params.mac_state &= ~LORAMAC_ACK_REQ;
|
||||
}
|
||||
if (_params.dev_class == CLASS_C) {
|
||||
if (_device_class == CLASS_C) {
|
||||
_params.flags.bits.mac_done = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1172,7 +1171,7 @@ lorawan_status_t LoRaMac::schedule_tx(void)
|
|||
nextChan.current_datarate = _params.sys_params.channel_data_rate;
|
||||
_params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON;
|
||||
nextChan.dc_enabled = _params.is_dutycycle_on;
|
||||
nextChan.joined = _params.is_nwk_joined;
|
||||
nextChan.joined = _is_nwk_joined;
|
||||
nextChan.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time;
|
||||
|
||||
// Select channel
|
||||
|
@ -1211,7 +1210,7 @@ lorawan_status_t LoRaMac::schedule_tx(void)
|
|||
_params.sys_params.max_sys_rx_error,
|
||||
&_params.rx_window2_config);
|
||||
|
||||
if (_params.is_nwk_joined == false) {
|
||||
if (!_is_nwk_joined) {
|
||||
_params.rx_window1_delay = _params.sys_params.join_accept_delay1
|
||||
+ _params.rx_window1_config.window_offset;
|
||||
_params.rx_window2_delay = _params.sys_params.join_accept_delay2
|
||||
|
@ -1236,7 +1235,7 @@ void LoRaMac::calculate_backOff(uint8_t channel)
|
|||
{
|
||||
backoff_params_t backoff_params;
|
||||
|
||||
backoff_params.joined = _params.is_nwk_joined;
|
||||
backoff_params.joined = _is_nwk_joined;
|
||||
_params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON;
|
||||
backoff_params.dc_enabled = _params.is_dutycycle_on;
|
||||
backoff_params.channel = channel;
|
||||
|
@ -1255,7 +1254,7 @@ void LoRaMac::calculate_backOff(uint8_t channel)
|
|||
|
||||
void LoRaMac::reset_mac_parameters(void)
|
||||
{
|
||||
_params.is_nwk_joined = false;
|
||||
_is_nwk_joined = false;
|
||||
|
||||
// Counters
|
||||
_params.ul_frame_counter = 0;
|
||||
|
@ -1308,6 +1307,29 @@ uint8_t LoRaMac::get_default_tx_datarate()
|
|||
return _lora_phy.get_default_tx_datarate();
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::enable_adaptive_datarate(bool adr_enabled)
|
||||
{
|
||||
_params.sys_params.adr_on = adr_enabled;
|
||||
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::set_channel_data_rate(uint8_t data_rate)
|
||||
{
|
||||
if (_params.sys_params.adr_on) {
|
||||
tr_error("Cannot set data rate. Please turn off ADR first.");
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
if (_lora_phy.verify_tx_datarate(data_rate, false) == true) {
|
||||
_params.sys_params.channel_data_rate = data_rate;
|
||||
} else {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
bool LoRaMac::tx_ongoing()
|
||||
{
|
||||
return _ongoing_tx_msg.tx_ongoing;
|
||||
|
@ -1390,18 +1412,13 @@ int16_t LoRaMac::prepare_ongoing_tx(uint8_t port, const uint8_t* data,
|
|||
lorawan_status_t LoRaMac::send_ongoing_tx()
|
||||
{
|
||||
lorawan_status_t status;
|
||||
loramac_mib_req_confirm_t mib_get_params;
|
||||
|
||||
if (_params.mac_state != LORAMAC_IDLE) {
|
||||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
int8_t datarate = get_default_tx_datarate();
|
||||
int8_t datarate = _params.sys_params.channel_data_rate;
|
||||
|
||||
mib_get_params.type = MIB_CHANNELS_DATARATE;
|
||||
if(mib_get_request_confirm(&mib_get_params) == LORAWAN_STATUS_OK) {
|
||||
datarate = mib_get_params.param.channel_data_rate;
|
||||
}
|
||||
// TODO: The comment is different than the code???
|
||||
// Apply the minimum possible datarate.
|
||||
// Some regions have limitations for the minimum datarate.
|
||||
|
@ -1447,6 +1464,103 @@ lorawan_status_t LoRaMac::send_ongoing_tx()
|
|||
return status;
|
||||
}
|
||||
|
||||
device_class_t LoRaMac::get_device_class() const
|
||||
{
|
||||
return _device_class;
|
||||
}
|
||||
|
||||
void LoRaMac::set_device_class(const device_class_t& device_class)
|
||||
{
|
||||
_device_class = device_class;
|
||||
|
||||
if (CLASS_A == _device_class) {
|
||||
// Set the radio into sleep to setup a defined state
|
||||
_lora_phy.put_radio_to_sleep();
|
||||
} else if (CLASS_C == _device_class) {
|
||||
// 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);
|
||||
}
|
||||
if (CLASS_C == _device_class) {
|
||||
open_continuous_rx2_window();
|
||||
}
|
||||
}
|
||||
|
||||
void LoRaMac::setup_link_check_request()
|
||||
{
|
||||
mlme.reset_confirmation();
|
||||
|
||||
mlme.get_confirmation().req_type = MLME_LINK_CHECK;
|
||||
_params.flags.bits.mlme_req = 1;
|
||||
mac_commands.add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::join_by_otaa(const lorawan_connect_otaa_t& otaa_join)
|
||||
{
|
||||
if (LORAMAC_IDLE != _params.mac_state) {
|
||||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
mlme.reset_confirmation();
|
||||
|
||||
mlme.get_confirmation().req_type = MLME_JOIN;
|
||||
_params.flags.bits.mlme_req = 1;
|
||||
|
||||
// if ((_params.mac_state & LORAMAC_TX_DELAYED) == LORAMAC_TX_DELAYED) {
|
||||
// return LORAWAN_STATUS_BUSY;
|
||||
// }
|
||||
|
||||
if ((otaa_join.dev_eui == NULL)
|
||||
|| (otaa_join.app_eui == NULL)
|
||||
|| (otaa_join.app_key == NULL)
|
||||
|| (otaa_join.nb_trials == 0)) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
_params.keys.dev_eui = otaa_join.dev_eui;
|
||||
_params.keys.app_eui = otaa_join.app_eui;
|
||||
_params.keys.app_key = otaa_join.app_key;
|
||||
_params.max_join_request_trials = otaa_join.nb_trials;
|
||||
|
||||
if (!_lora_phy.verify_nb_join_trials(otaa_join.nb_trials)) {
|
||||
// Value not supported, get default
|
||||
_params.max_join_request_trials = MBED_CONF_LORA_NB_TRIALS;
|
||||
}
|
||||
// Reset variable JoinRequestTrials
|
||||
_params.join_request_trial_counter = 0;
|
||||
|
||||
reset_mac_parameters();
|
||||
|
||||
_params.sys_params.channel_data_rate =
|
||||
_lora_phy.get_alternate_DR(_params.join_request_trial_counter + 1);
|
||||
|
||||
loramac_mhdr_t machdr;
|
||||
machdr.value = 0;
|
||||
machdr.bits.mtype = FRAME_TYPE_JOIN_REQ;
|
||||
return send(&machdr, 0, NULL, 0);
|
||||
}
|
||||
|
||||
void LoRaMac::join_by_abp(const lorawan_connect_abp_t& abp_join)
|
||||
{
|
||||
_params.net_id = abp_join.nwk_id;
|
||||
|
||||
_params.dev_addr = abp_join.dev_addr;
|
||||
|
||||
memcpy(_params.keys.nwk_skey, abp_join.nwk_skey,
|
||||
sizeof(_params.keys.nwk_skey));
|
||||
|
||||
memcpy(_params.keys.app_skey, abp_join.app_skey,
|
||||
sizeof(_params.keys.app_skey));
|
||||
|
||||
set_nwk_joined(true);
|
||||
}
|
||||
|
||||
static void memcpy_convert_endianess(uint8_t *dst, const uint8_t *src,
|
||||
uint16_t size)
|
||||
{
|
||||
|
@ -1513,7 +1627,7 @@ lorawan_status_t LoRaMac::prepare_frame(loramac_mhdr_t *machdr,
|
|||
_params.is_node_ack_requested = true;
|
||||
//Intentional fallthrough
|
||||
case FRAME_TYPE_DATA_UNCONFIRMED_UP: {
|
||||
if (_params.is_nwk_joined == false) {
|
||||
if (!_is_nwk_joined) {
|
||||
// No network has been joined yet
|
||||
return LORAWAN_STATUS_NO_NETWORK_JOINED;
|
||||
}
|
||||
|
@ -1664,7 +1778,7 @@ lorawan_status_t LoRaMac::send_frame_on_channel(uint8_t channel)
|
|||
_lora_time.start(_params.timers.mac_state_check_timer,
|
||||
MAC_STATE_CHECK_TIMEOUT);
|
||||
|
||||
if (_params.is_nwk_joined == false) {
|
||||
if (!_is_nwk_joined) {
|
||||
_params.join_request_trial_counter++;
|
||||
}
|
||||
|
||||
|
@ -1694,9 +1808,6 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
|
|||
// Activate MCPS subsystem
|
||||
mcps.activate_mcps_subsystem();
|
||||
|
||||
// Activate MIB subsystem
|
||||
mib.activate_mib_subsystem(&_lora_phy);
|
||||
|
||||
// Activate channel planning subsystem
|
||||
channel_plan.activate_channelplan_subsystem(&_lora_phy);
|
||||
|
||||
|
@ -1704,7 +1815,7 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
|
|||
|
||||
_params.flags.value = 0;
|
||||
|
||||
_params.dev_class = CLASS_A;
|
||||
_device_class = CLASS_A;
|
||||
_params.mac_state = LORAMAC_IDLE;
|
||||
|
||||
_params.join_request_trial_counter = 0;
|
||||
|
@ -1746,15 +1857,10 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
|
|||
// Store the current initialization time
|
||||
_params.timers.mac_init_time = _lora_time.get_current_time();
|
||||
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
_params.sys_params.adr_on = MBED_CONF_LORA_ADR_ON;
|
||||
|
||||
mib_req.type = MIB_ADR;
|
||||
mib_req.param.is_adr_enable = MBED_CONF_LORA_ADR_ON;
|
||||
mib_set_request_confirm(&mib_req);
|
||||
|
||||
mib_req.type = MIB_PUBLIC_NETWORK;
|
||||
mib_req.param.enable_public_nwk = MBED_CONF_LORA_PUBLIC_NETWORK;
|
||||
mib_set_request_confirm(&mib_req);
|
||||
_params.is_nwk_public = MBED_CONF_LORA_PUBLIC_NETWORK;
|
||||
_lora_phy.setup_public_network_mode(MBED_CONF_LORA_PUBLIC_NETWORK);
|
||||
|
||||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
@ -1772,7 +1878,7 @@ void LoRaMac::disconnect()
|
|||
_lora_phy.put_radio_to_sleep();
|
||||
|
||||
// Reset internal state
|
||||
_params.is_nwk_joined = false;
|
||||
_is_nwk_joined = false;
|
||||
_params.is_ack_retry_timeout_expired = false;
|
||||
_params.is_rx_window_enabled = true;
|
||||
_params.is_node_ack_requested = false;
|
||||
|
@ -1825,6 +1931,16 @@ uint8_t LoRaMac::query_tx_possible(uint8_t size)
|
|||
return current_payload_size;
|
||||
}
|
||||
|
||||
bool LoRaMac::nwk_joined()
|
||||
{
|
||||
return _is_nwk_joined;
|
||||
}
|
||||
|
||||
void LoRaMac::set_nwk_joined(bool joined)
|
||||
{
|
||||
_is_nwk_joined = joined;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::add_channel_plan(const lorawan_channelplan_t& plan)
|
||||
{
|
||||
// Validate if the MAC is in a correct state
|
||||
|
@ -1851,18 +1967,7 @@ lorawan_status_t LoRaMac::remove_channel_plan()
|
|||
|
||||
lorawan_status_t LoRaMac::get_channel_plan(lorawan_channelplan_t& plan)
|
||||
{
|
||||
// Request Mib to get channels
|
||||
loramac_mib_req_confirm_t mib_confirm;
|
||||
memset(&mib_confirm, 0, sizeof(mib_confirm));
|
||||
mib_confirm.type = MIB_CHANNELS;
|
||||
|
||||
lorawan_status_t status = mib.get_request(&mib_confirm, &_params);
|
||||
|
||||
if (status != LORAWAN_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return channel_plan.get_plan(plan, &mib_confirm);
|
||||
return channel_plan.get_plan(plan, _lora_phy.get_phy_channels());
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::remove_single_channel(uint8_t id)
|
||||
|
@ -1937,6 +2042,26 @@ lorawan_status_t LoRaMac::multicast_channel_unlink(
|
|||
return LORAWAN_STATUS_OK;
|
||||
}
|
||||
|
||||
void LoRaMac::bind_radio_driver(LoRaRadio& radio)
|
||||
{
|
||||
radio_events.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done);
|
||||
radio_events.rx_done = mbed::callback(this, &LoRaMac::handle_rx_done);
|
||||
radio_events.rx_error = mbed::callback(this, &LoRaMac::handle_rx_error);
|
||||
radio_events.tx_timeout = mbed::callback(this, &LoRaMac::handle_tx_timeout);
|
||||
radio_events.rx_timeout = mbed::callback(this, &LoRaMac::handle_rx_timeout);
|
||||
|
||||
_lora_phy.set_radio_instance(radio);
|
||||
radio.lock();
|
||||
radio.init_radio(&radio_events);
|
||||
radio.unlock();
|
||||
}
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
/***************************************************************************
|
||||
* Compliance testing *
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
lorawan_status_t LoRaMac::mlme_request( loramac_mlme_req_t *mlmeRequest )
|
||||
{
|
||||
if (LORAMAC_IDLE != _params.mac_state) {
|
||||
|
@ -1950,50 +2075,16 @@ lorawan_status_t LoRaMac::mlme_request( loramac_mlme_req_t *mlmeRequest )
|
|||
|
||||
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
|
||||
if (MLME_LINK_CHECK == mlmeRequest->type) {
|
||||
status = mac_commands.add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
||||
} else if (MLME_JOIN == mlmeRequest->type) {
|
||||
if ((_params.mac_state & LORAMAC_TX_DELAYED) == LORAMAC_TX_DELAYED) {
|
||||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
if ((mlmeRequest->req.join.dev_eui == NULL)
|
||||
|| (mlmeRequest->req.join.app_eui == NULL)
|
||||
|| (mlmeRequest->req.join.app_key == NULL)
|
||||
|| (mlmeRequest->req.join.nb_trials == 0)) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
_params.keys.dev_eui = mlmeRequest->req.join.dev_eui;
|
||||
_params.keys.app_eui = mlmeRequest->req.join.app_eui;
|
||||
_params.keys.app_key = mlmeRequest->req.join.app_key;
|
||||
_params.max_join_request_trials = mlmeRequest->req.join.nb_trials;
|
||||
|
||||
if (!_lora_phy.verify_nb_join_trials(mlmeRequest->req.join.nb_trials)) {
|
||||
// Value not supported, get default
|
||||
_params.max_join_request_trials = MBED_CONF_LORA_NB_TRIALS;
|
||||
}
|
||||
// Reset variable JoinRequestTrials
|
||||
_params.join_request_trial_counter = 0;
|
||||
|
||||
reset_mac_parameters();
|
||||
|
||||
_params.sys_params.channel_data_rate =
|
||||
_lora_phy.get_alternate_DR(_params.join_request_trial_counter + 1);
|
||||
|
||||
loramac_mhdr_t machdr;
|
||||
machdr.value = 0;
|
||||
machdr.bits.mtype = FRAME_TYPE_JOIN_REQ;
|
||||
status = send(&machdr, 0, NULL, 0);
|
||||
} else if (MLME_TXCW == mlmeRequest->type) {
|
||||
if (MLME_TXCW == mlmeRequest->type) {
|
||||
mlme.set_tx_continuous_wave(_params.channel, _params.sys_params.channel_data_rate, _params.sys_params.channel_tx_power,
|
||||
_params.sys_params.max_eirp, _params.sys_params.antenna_gain, mlmeRequest->req.cw_tx_mode.timeout);
|
||||
_params.sys_params.max_eirp, _params.sys_params.antenna_gain, mlmeRequest->cw_tx_mode.timeout);
|
||||
_lora_time.start(_params.timers.mac_state_check_timer,
|
||||
MAC_STATE_CHECK_TIMEOUT);
|
||||
|
||||
_params.mac_state |= LORAMAC_TX_RUNNING;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
} else if (MLME_TXCW_1 == mlmeRequest->type) {
|
||||
mlme.set_tx_continuous_wave(0, 0, mlmeRequest->req.cw_tx_mode.power, 0, 0, mlmeRequest->req.cw_tx_mode.timeout);
|
||||
mlme.set_tx_continuous_wave(0, 0, mlmeRequest->cw_tx_mode.power, 0, 0, mlmeRequest->cw_tx_mode.timeout);
|
||||
_lora_time.start(_params.timers.mac_state_check_timer,
|
||||
MAC_STATE_CHECK_TIMEOUT);
|
||||
|
||||
|
@ -2074,40 +2165,6 @@ lorawan_status_t LoRaMac::mcps_request( loramac_mcps_req_t *mcpsRequest )
|
|||
return status;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::mib_get_request_confirm( loramac_mib_req_confirm_t *mibGet )
|
||||
{
|
||||
return mib.get_request(mibGet, &_params);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMac::mib_set_request_confirm( loramac_mib_req_confirm_t *mibSet )
|
||||
{
|
||||
lorawan_status_t status = mib.set_request(mibSet, &_params);
|
||||
if (LORAWAN_STATUS_OK == status && CLASS_C == _params.dev_class && (MIB_DEVICE_CLASS == mibSet->type ||
|
||||
(MIB_RX2_CHANNEL == mibSet->type && _params.is_nwk_joined))) {
|
||||
open_continuous_rx2_window();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void LoRaMac::bind_radio_driver(LoRaRadio& radio)
|
||||
{
|
||||
radio_events.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done);
|
||||
radio_events.rx_done = mbed::callback(this, &LoRaMac::handle_rx_done);
|
||||
radio_events.rx_error = mbed::callback(this, &LoRaMac::handle_rx_error);
|
||||
radio_events.tx_timeout = mbed::callback(this, &LoRaMac::handle_tx_timeout);
|
||||
radio_events.rx_timeout = mbed::callback(this, &LoRaMac::handle_rx_timeout);
|
||||
|
||||
_lora_phy.set_radio_instance(radio);
|
||||
radio.lock();
|
||||
radio.init_radio(&radio_events);
|
||||
radio.unlock();
|
||||
}
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
/***************************************************************************
|
||||
* Compliance testing *
|
||||
**************************************************************************/
|
||||
|
||||
lorawan_status_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime )
|
||||
{
|
||||
_lora_time.start(tx_next_packet_timer, TxDutyCycleTime);
|
||||
|
|
|
@ -43,12 +43,11 @@
|
|||
#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 "LoRaMacMlme.h"
|
||||
#include "LoRaMacMcps.h"
|
||||
#include "LoRaMacChannelPlan.h"
|
||||
#include "loraphy_target.h"
|
||||
|
||||
class LoRaMac {
|
||||
|
@ -107,6 +106,18 @@ public:
|
|||
*/
|
||||
uint8_t query_tx_possible(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.
|
||||
*
|
||||
|
@ -198,155 +209,6 @@ public:
|
|||
*/
|
||||
lorawan_status_t multicast_channel_unlink(multicast_params_t *channel_param);
|
||||
|
||||
/**
|
||||
* @brief Get parameter values from MIB service.
|
||||
*
|
||||
* @details The MAC information base service to get the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to get the
|
||||
* parameter `AdrEnable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* loramac_mib_req_confirm_t mib_get;
|
||||
* mib_get.type = MIB_ADR;
|
||||
*
|
||||
* if (mib_get_request_confirm(&mib_get) == LORAWAN_STATUS_OK) {
|
||||
* // LoRaMAC updated the parameter mibParam.AdrEnable
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* @param [in] mib_get The MIB-GET request to perform. Refer to
|
||||
* \ref loramac_mib_req_confirm_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation.
|
||||
* The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t mib_get_request_confirm(loramac_mib_req_confirm_t *mib_get);
|
||||
|
||||
/**
|
||||
* @brief 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);
|
||||
|
||||
/** Binds radio driver to PHY layer.
|
||||
*
|
||||
* MAC layer is totally detached from the PHY layer so the stack layer
|
||||
|
@ -427,6 +289,27 @@ public:
|
|||
*/
|
||||
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.
|
||||
* @return LORAWAN_STATUS_OK or a negative error code on failure.
|
||||
*/
|
||||
lorawan_status_t 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.
|
||||
|
@ -465,6 +348,38 @@ public:
|
|||
*/
|
||||
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:
|
||||
/**
|
||||
* Function to be executed on Radio Tx Done event
|
||||
|
@ -613,11 +528,6 @@ private:
|
|||
*/
|
||||
LoRaMacMcps mcps;
|
||||
|
||||
/**
|
||||
* MCPS subsystem handle
|
||||
*/
|
||||
LoRaMacMib mib;
|
||||
|
||||
/**
|
||||
* Channel planning subsystem
|
||||
*/
|
||||
|
@ -645,9 +555,69 @@ private:
|
|||
|
||||
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_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 set tx timer.
|
||||
*
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -1,434 +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: {
|
||||
status = LORAWAN_STATUS_UNSUPPORTED;
|
||||
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,
|
||||
¶ms->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,
|
||||
¶ms->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;
|
||||
}
|
||||
case MIB_DEFAULT_ANTENNA_GAIN:
|
||||
{
|
||||
params->sys_params.antenna_gain = mibSet->param.default_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;
|
||||
}
|
||||
case MIB_DEFAULT_ANTENNA_GAIN:
|
||||
{
|
||||
mibGet->param.default_antenna_gain = params->sys_params.antenna_gain;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -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_ */
|
|
@ -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
|
||||
*/
|
||||
|
@ -762,62 +747,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.
|
||||
*/
|
||||
|
@ -1025,29 +954,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 +997,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
|
||||
* \ref MIB_DEFAULT_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,
|
||||
/*!
|
||||
* Default antenna gain of the node. 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_DEFAULT_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;
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*
|
||||
* Related MIB type: \ref MIB_DEFAULT_ANTENNA_GAIN
|
||||
*/
|
||||
float default_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 status.
|
||||
*
|
||||
*/
|
||||
|
@ -1830,14 +1277,10 @@ 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;
|
||||
|
@ -2051,11 +1494,6 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
|
||||
/*!
|
||||
* Actual device class
|
||||
*/
|
||||
device_class_t dev_class;
|
||||
|
||||
/*!
|
||||
* Holds the type of current Receive window slot
|
||||
*/
|
||||
|
@ -2288,6 +1726,69 @@ typedef struct lora_channelplan {
|
|||
} 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 {
|
||||
/*!
|
||||
* 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;
|
||||
|
||||
/** LoRaWAN compliance tests support data
|
||||
*
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue