Skip to content

Lora: Split add_mac_command() into separate methods #6741

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion features/lorawan/lorastack/mac/LoRaMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1432,7 +1432,7 @@ void LoRaMac::setup_link_check_request()

_mlme_confirmation.req_type = MLME_LINK_CHECK;
_params.flags.bits.mlme_req = 1;
mac_commands.add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
mac_commands.add_link_check_req();
}

lorawan_status_t LoRaMac::prepare_join(const lorawan_connect_t *params, bool is_otaa)
Expand Down
271 changes: 143 additions & 128 deletions features/lorawan/lorastack/mac/LoRaMacCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,107 +51,6 @@ LoRaMacCommand::LoRaMacCommand()
memset(mac_cmd_buffer_to_repeat, 0, sizeof(mac_cmd_buffer_to_repeat));
}

LoRaMacCommand::~LoRaMacCommand()
{
}

lorawan_status_t LoRaMacCommand::add_mac_command(uint8_t cmd, uint8_t p1,
uint8_t p2)
{
lorawan_status_t status = LORAWAN_STATUS_BUSY;
// The maximum buffer length must take MAC commands to re-send into account.
const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH
- mac_cmd_buf_idx_to_repeat;

switch (cmd) {
case MOTE_MAC_LINK_CHECK_REQ:
if (mac_cmd_buf_idx < bufLen) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// No payload for this command
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_LINK_ADR_ANS:
if (mac_cmd_buf_idx < (bufLen - 1)) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// Margin
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_DUTY_CYCLE_ANS:
if (mac_cmd_buf_idx < bufLen) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// No payload for this answer
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_RX_PARAM_SETUP_ANS:
if (mac_cmd_buf_idx < (bufLen - 1)) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// Status: Datarate ACK, Channel ACK
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
// This is a sticky MAC command answer. Setup indication
// _lora_mac.set_mlme_schedule_ul_indication();
sticky_mac_cmd = true;
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_DEV_STATUS_ANS:
if (mac_cmd_buf_idx < (bufLen - 2)) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// 1st byte Battery
// 2nd byte Margin
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
mac_cmd_buffer[mac_cmd_buf_idx++] = p2;
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_NEW_CHANNEL_ANS:
if (mac_cmd_buf_idx < (bufLen - 1)) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// Status: Datarate range OK, Channel frequency OK
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_RX_TIMING_SETUP_ANS:
if (mac_cmd_buf_idx < bufLen) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// No payload for this answer
// This is a sticky MAC command answer. Setup indication
// _lora_mac.set_mlme_schedule_ul_indication();
sticky_mac_cmd = true;
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_TX_PARAM_SETUP_ANS:
if (mac_cmd_buf_idx < bufLen) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// No payload for this answer
status = LORAWAN_STATUS_OK;
}
break;
case MOTE_MAC_DL_CHANNEL_ANS:
if (mac_cmd_buf_idx < bufLen) {
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
// Status: Uplink frequency exists, Channel frequency OK
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
// This is a sticky MAC command answer. Setup indication
// _lora_mac.set_mlme_schedule_ul_indication();
sticky_mac_cmd = true;
status = LORAWAN_STATUS_OK;
}
break;
default:
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
if (status == LORAWAN_STATUS_OK) {
mac_cmd_in_next_tx = true;
}
return status;
}

void LoRaMacCommand::clear_command_buffer()
{
mac_cmd_buf_idx = 0;
Expand Down Expand Up @@ -185,7 +84,8 @@ void LoRaMacCommand::parse_mac_commands_to_repeat()
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i];
break;
}
// NON-STICKY

// NON-STICKY
case MOTE_MAC_DEV_STATUS_ANS: { // 2 bytes payload
i += 2;
break;
Expand Down Expand Up @@ -298,7 +198,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t

// Add the answers to the buffer
for (uint8_t i = 0; i < (linkAdrNbBytesParsed / 5); i++) {
ret_value = add_mac_command(MOTE_MAC_LINK_ADR_ANS, status, 0);
ret_value = add_link_adr_ans(status);
}
// Update MAC index
mac_index += linkAdrNbBytesParsed - 1;
Expand All @@ -307,7 +207,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
case SRV_MAC_DUTY_CYCLE_REQ:
mac_sys_params.max_duty_cycle = payload[mac_index++];
mac_sys_params.aggregated_duty_cycle = 1 << mac_sys_params.max_duty_cycle;
ret_value = add_mac_command(MOTE_MAC_DUTY_CYCLE_ANS, 0, 0);
ret_value = add_duty_cycle_ans();
break;
case SRV_MAC_RX_PARAM_SETUP_REQ: {
rx_param_setup_req_t rxParamSetupReq;
Expand All @@ -317,32 +217,26 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
mac_index++;

rxParamSetupReq.frequency = (uint32_t) payload[mac_index++];
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++]
<< 8;
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++]
<< 16;
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++] << 8;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style

rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++] << 16;
rxParamSetupReq.frequency *= 100;

// Perform request on region
status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq);

if ((status & 0x07) == 0x07) {
mac_sys_params.rx2_channel.datarate =
rxParamSetupReq.datarate;
mac_sys_params.rx2_channel.frequency =
rxParamSetupReq.frequency;
mac_sys_params.rx2_channel.datarate = rxParamSetupReq.datarate;
mac_sys_params.rx2_channel.frequency = rxParamSetupReq.frequency;
mac_sys_params.rx1_dr_offset = rxParamSetupReq.dr_offset;
}
ret_value = add_mac_command(MOTE_MAC_RX_PARAM_SETUP_ANS, status,
0);
ret_value = add_rx_param_setup_ans(status);
}
break;
case SRV_MAC_DEV_STATUS_REQ: {
uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
// we don't have a mechanism at the moment to measure
// battery levels
ret_value = add_mac_command(MOTE_MAC_DEV_STATUS_ANS,
batteryLevel, snr & 0x3F);
ret_value = add_dev_status_ans(batteryLevel, snr & 0x3F);
break;
}
case SRV_MAC_NEW_CHANNEL_REQ: {
Expand All @@ -358,7 +252,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t

status = lora_phy.request_new_channel(channel_id, &chParam);

ret_value = add_mac_command(MOTE_MAC_NEW_CHANNEL_ANS, status, 0);
ret_value = add_new_channel_ans(status);
}
break;
case SRV_MAC_RX_TIMING_SETUP_REQ: {
Expand All @@ -369,7 +263,7 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
}
mac_sys_params.recv_delay1 = delay * 1000;
mac_sys_params.recv_delay2 = mac_sys_params.recv_delay1 + 1000;
ret_value = add_mac_command(MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0);
ret_value = add_rx_timing_setup_ans();
}
break;
case SRV_MAC_TX_PARAM_SETUP_REQ: {
Expand All @@ -392,30 +286,25 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
// Check the status for correctness
if (lora_phy.accept_tx_param_setup_req(ul_dwell_time, dl_dwell_time)) {
// Accept command
mac_sys_params.uplink_dwell_time =
ul_dwell_time;
mac_sys_params.downlink_dwell_time =
dl_dwell_time;
mac_sys_params.max_eirp =
max_eirp_table[max_eirp];
mac_sys_params.uplink_dwell_time = ul_dwell_time;
mac_sys_params.downlink_dwell_time = dl_dwell_time;
mac_sys_params.max_eirp = max_eirp_table[max_eirp];
// Add command response
ret_value = add_mac_command(MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0);
ret_value = add_tx_param_setup_ans();
}
}
break;
case SRV_MAC_DL_CHANNEL_REQ: {

uint8_t channel_id = payload[mac_index++];
uint32_t rx1_frequency;

rx1_frequency = (uint32_t) payload[mac_index++];
rx1_frequency |= (uint32_t) payload[mac_index++] << 8;
rx1_frequency |= (uint32_t) payload[mac_index++] << 16;
rx1_frequency *= 100;

status = lora_phy.dl_channel_request(channel_id, rx1_frequency);

ret_value = add_mac_command(MOTE_MAC_DL_CHANNEL_ANS, status, 0);
ret_value = add_dl_channel_ans(status);
}
break;
default:
Expand All @@ -433,3 +322,129 @@ bool LoRaMacCommand::is_sticky_mac_command_pending()
}
return false;
}

int32_t LoRaMacCommand::cmd_buffer_remaining() const
{
// The maximum buffer length must take MAC commands to re-send into account.
return sizeof(mac_cmd_buffer) - mac_cmd_buf_idx_to_repeat - mac_cmd_buf_idx;
}

lorawan_status_t LoRaMacCommand::add_link_check_req()
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 0) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_LINK_CHECK_REQ;
// No payload for this command
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_link_adr_ans(uint8_t status)
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 1) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_LINK_ADR_ANS;
mac_cmd_buffer[mac_cmd_buf_idx++] = status;
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_duty_cycle_ans()
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 0) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_DUTY_CYCLE_ANS;
// No payload for this answer
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_rx_param_setup_ans(uint8_t status)
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 1) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_RX_PARAM_SETUP_ANS;
// Status: Datarate ACK, Channel ACK
mac_cmd_buffer[mac_cmd_buf_idx++] = status;
// This is a sticky MAC command answer. Setup indication
sticky_mac_cmd = true;
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_dev_status_ans(uint8_t battery, uint8_t margin)
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 2) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_DEV_STATUS_ANS;
// 1st byte Battery
// 2nd byte Margin
mac_cmd_buffer[mac_cmd_buf_idx++] = battery;
mac_cmd_buffer[mac_cmd_buf_idx++] = margin;
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_new_channel_ans(uint8_t status)
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 1) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_NEW_CHANNEL_ANS;
// Status: Datarate range OK, Channel frequency OK
mac_cmd_buffer[mac_cmd_buf_idx++] = status;
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_rx_timing_setup_ans()
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 0) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_RX_TIMING_SETUP_ANS;
// No payload for this answer
// This is a sticky MAC command answer. Setup indication
sticky_mac_cmd = true;
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_tx_param_setup_ans()
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 0) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_TX_PARAM_SETUP_ANS;
// No payload for this answer
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}

lorawan_status_t LoRaMacCommand::add_dl_channel_ans(uint8_t status)
{
lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR;
if (cmd_buffer_remaining() > 0) {
mac_cmd_buffer[mac_cmd_buf_idx++] = MOTE_MAC_DL_CHANNEL_ANS;
// Status: Uplink frequency exists, Channel frequency OK
mac_cmd_buffer[mac_cmd_buf_idx++] = status;
// This is a sticky MAC command answer. Setup indication
sticky_mac_cmd = true;
ret = LORAWAN_STATUS_OK;
mac_cmd_in_next_tx = true;
}
return ret;
}
Loading