mirror of https://github.com/ARMmbed/mbed-os.git
155 lines
4.8 KiB
C++
155 lines
4.8 KiB
C++
/**
|
|
/ _____) _ | |
|
|
( (____ _____ ____ _| |_ _____ ____| |__
|
|
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
_____) ) ____| | | || |_| ____( (___| | | |
|
|
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
(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 "LoRaMac.h"
|
|
#include "lorastack/mac/LoRaMacMcps.h"
|
|
|
|
LoRaMacMcps::LoRaMacMcps()
|
|
: _lora_mac(NULL), _lora_phy(NULL)
|
|
{
|
|
}
|
|
|
|
LoRaMacMcps::~LoRaMacMcps()
|
|
{
|
|
}
|
|
|
|
void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy)
|
|
{
|
|
_lora_mac = mac;
|
|
_lora_phy = phy;
|
|
}
|
|
|
|
LoRaMacStatus_t LoRaMacMcps::set_request(McpsReq_t *mcpsRequest,
|
|
lora_mac_protocol_params *params)
|
|
{
|
|
|
|
if (mcpsRequest == NULL || _lora_phy == NULL || _lora_mac == NULL) {
|
|
return LORAMAC_STATUS_PARAMETER_INVALID;
|
|
}
|
|
|
|
if (params->LoRaMacState != LORAMAC_IDLE) {
|
|
return LORAMAC_STATUS_BUSY;
|
|
}
|
|
|
|
GetPhyParams_t getPhy;
|
|
PhyParam_t phyParam;
|
|
LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
|
|
LoRaMacHeader_t macHdr;
|
|
VerifyParams_t verify;
|
|
uint8_t fPort = 0;
|
|
void *fBuffer;
|
|
uint16_t fBufferSize;
|
|
int8_t datarate = DR_0;
|
|
bool readyToSend = false;
|
|
|
|
macHdr.Value = 0;
|
|
|
|
// Before performing any MCPS request, clear the confirmation structure
|
|
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
|
|
|
|
confirmation.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
|
|
|
// AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed.
|
|
params->AckTimeoutRetriesCounter = 1;
|
|
|
|
switch (mcpsRequest->Type) {
|
|
case MCPS_UNCONFIRMED: {
|
|
readyToSend = true;
|
|
params->AckTimeoutRetries = 1;
|
|
|
|
macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP;
|
|
fPort = mcpsRequest->Req.Unconfirmed.fPort;
|
|
fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer;
|
|
fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize;
|
|
datarate = mcpsRequest->Req.Unconfirmed.Datarate;
|
|
break;
|
|
}
|
|
case MCPS_CONFIRMED: {
|
|
readyToSend = true;
|
|
params->AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials;
|
|
|
|
macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP;
|
|
fPort = mcpsRequest->Req.Confirmed.fPort;
|
|
fBuffer = mcpsRequest->Req.Confirmed.fBuffer;
|
|
fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize;
|
|
datarate = mcpsRequest->Req.Confirmed.Datarate;
|
|
break;
|
|
}
|
|
case MCPS_PROPRIETARY: {
|
|
readyToSend = true;
|
|
params->AckTimeoutRetries = 1;
|
|
|
|
macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY;
|
|
fBuffer = mcpsRequest->Req.Proprietary.fBuffer;
|
|
fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize;
|
|
datarate = mcpsRequest->Req.Proprietary.Datarate;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Filter fPorts
|
|
// TODO: Does not work with PROPRIETARY messages
|
|
// if( IsFPortAllowed( fPort ) == false )
|
|
// {
|
|
// return LORAMAC_STATUS_PARAMETER_INVALID;
|
|
// }
|
|
|
|
// Get the minimum possible datarate
|
|
getPhy.Attribute = PHY_MIN_TX_DR;
|
|
getPhy.UplinkDwellTime = params->sys_params.UplinkDwellTime;
|
|
phyParam = _lora_phy->get_phy_params(&getPhy);
|
|
|
|
// Apply the minimum possible datarate.
|
|
// Some regions have limitations for the minimum datarate.
|
|
datarate = MAX(datarate, phyParam.Value);
|
|
|
|
if (readyToSend == true) {
|
|
if (params->sys_params.AdrCtrlOn == false) {
|
|
verify.DatarateParams.Datarate = datarate;
|
|
verify.DatarateParams.UplinkDwellTime =
|
|
params->sys_params.UplinkDwellTime;
|
|
|
|
if (_lora_phy->verify(&verify, PHY_TX_DR) == true) {
|
|
params->sys_params.ChannelsDatarate =
|
|
verify.DatarateParams.Datarate;
|
|
} else {
|
|
return LORAMAC_STATUS_PARAMETER_INVALID;
|
|
}
|
|
}
|
|
|
|
status = _lora_mac->Send(&macHdr, fPort, fBuffer, fBufferSize);
|
|
if (status == LORAMAC_STATUS_OK) {
|
|
confirmation.McpsRequest = mcpsRequest->Type;
|
|
params->LoRaMacFlags.Bits.McpsReq = 1;
|
|
} else {
|
|
params->NodeAckRequested = false;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|