Merge pull request #6741 from kivaisan/refactor_maccommand

Lora: Split add_mac_command() into separate methods
pull/6805/head
Cruz Monrreal 2018-04-30 11:58:33 -05:00 committed by GitHub
commit 46379d8438
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 235 additions and 149 deletions

View File

@ -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)

View File

@ -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;
@ -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;
@ -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;
@ -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;
@ -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;
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: {
@ -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: {
@ -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: {
@ -392,19 +286,15 @@ 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;
@ -412,10 +302,9 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, uint8_t
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:
@ -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;
}

View File

@ -55,26 +55,6 @@ class LoRaMacCommand {
public:
LoRaMacCommand();
~LoRaMacCommand();
/**
* @brief Adds a new MAC command to be sent.
*
* @remark MAC layer internal function
*
* @param [in] cmd MAC command to be added
* [MOTE_MAC_LINK_CHECK_REQ,
* MOTE_MAC_LINK_ADR_ANS,
* MOTE_MAC_DUTY_CYCLE_ANS,
* MOTE_MAC_RX2_PARAM_SET_ANS,
* MOTE_MAC_DEV_STATUS_ANS
* MOTE_MAC_NEW_CHANNEL_ANS]
* @param [in] p1 1st parameter (optional depends on the command)
* @param [in] p2 2nd parameter (optional depends on the command)
*
* @return status Function status [0: OK, 1: Unknown command, 2: Buffer full]
*/
lorawan_status_t add_mac_command(uint8_t cmd, uint8_t p1, uint8_t p2);
/**
* @brief Clear MAC command buffer.
@ -159,6 +139,97 @@ public:
*/
bool is_sticky_mac_command_pending();
/**
* @brief Adds a new LinkCheckReq MAC command to be sent.
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_link_check_req();
private:
/**
* @brief Get the remaining size of the MAC command buffer
*
* @return Remaining free space in buffer (bytes).
*/
int32_t cmd_buffer_remaining() const;
/**
* @brief Adds a new LinkAdrAns MAC command to be sent.
*
* @param [in] status Status bits
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_link_adr_ans(uint8_t status);
/**
* @brief Adds a new DutyCycleAns MAC command to be sent.
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_duty_cycle_ans();
/**
* @brief Adds a new RXParamSetupAns MAC command to be sent.
*
* @param [in] status Status bits
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_rx_param_setup_ans(uint8_t status);
/**
* @brief Adds a new DevStatusAns MAC command to be sent.
*
* @param [in] battery Battery level
* @param [in] margin Demodulation signal-to-noise ratio (dB)
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_dev_status_ans(uint8_t battery, uint8_t margin);
/**
* @brief Adds a new NewChannelAns MAC command to be sent.
*
* @param [in] status Status bits
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_new_channel_ans(uint8_t status);
/**
* @brief Adds a new RXTimingSetupAns MAC command to be sent.
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_rx_timing_setup_ans();
/**
* @brief Adds a new TXParamSetupAns MAC command to be sent.
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_tx_param_setup_ans();
/**
* @brief Adds a new DlChannelAns MAC command to be sent.
*
* @param [in] status Status bits
*
* @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/
lorawan_status_t add_dl_channel_ans(uint8_t status);
private:
/**
* Indicates if the MAC layer wants to send MAC commands