Fork of Semtech LoRaWAN stack
Fork of LoRaWAN-lib by
Revision 3:b9d87593a8ae, committed 2016-03-14
- Comitter:
- mluis
- Date:
- Mon Mar 14 09:09:54 2016 +0000
- Parent:
- 2:14a5d6ad92d5
- Child:
- 4:37c12dbc8dc7
- Commit message:
- Synchronized with https://github.com/Lora-net/LoRaMac-node git revision 5a25e2f1593bc382200e848e6db967d1c4550021
Changed in this revision
--- a/LoRaMac-api-v3.cpp Tue Jan 05 16:41:54 2016 +0000
+++ b/LoRaMac-api-v3.cpp Mon Mar 14 09:09:54 2016 +0000
@@ -340,7 +340,7 @@
mcpsRequest.Req.Confirmed.fBuffer = fBuffer;
mcpsRequest.Req.Confirmed.fBufferSize = fBufferSize;
mcpsRequest.Req.Confirmed.fPort = fPort;
- mcpsRequest.Req.Confirmed.nbRetries = nbRetries;
+ mcpsRequest.Req.Confirmed.NbTrials = nbRetries;
mcpsRequest.Req.Confirmed.Datarate = mibGet.Param.ChannelsDatarate;
switch( LoRaMacMcpsRequest( &mcpsRequest ) )
--- a/LoRaMac-board.h Tue Jan 05 16:41:54 2016 +0000
+++ b/LoRaMac-board.h Mon Mar 14 09:09:54 2016 +0000
@@ -311,12 +311,6 @@
#define LC1 { 868100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
#define LC2 { 868300000, { ( ( DR_6 << 4 ) | DR_0 ) }, 1 }
#define LC3 { 868500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
-#define LC4 { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC5 { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC6 { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC7 { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC8 { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
-#define LC9 { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
--- a/LoRaMac.cpp Tue Jan 05 16:41:54 2016 +0000
+++ b/LoRaMac.cpp Mon Mar 14 09:09:54 2016 +0000
@@ -300,12 +300,6 @@
LC1,
LC2,
LC3,
- LC4,
- LC5,
- LC6,
- LC7,
- LC8,
- LC9,
};
#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
/*!
@@ -447,6 +441,7 @@
MAC_ACK_REQ = 0x00000004,
MAC_ACK_RETRY = 0x00000008,
MAC_TX_DELAYED = 0x00000010,
+ MAC_TX_CONFIG = 0x00000020,
};
/*!
@@ -562,6 +557,12 @@
static void OnRadioTxDone( void );
/*!
+ * \brief This function prepares the MAC to abort the execution of function
+ * OnRadioRxDone in case of a reception error.
+ */
+static void PrepareRxDoneAbort( void );
+
+/*!
* \brief Function to be executed on Radio Rx Done event
*/
static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
@@ -609,9 +610,13 @@
/*!
* \brief Searches and set the next random available channel
*
- * \retval status Function status [0: OK, 1: Unable to find a free channel]
+ * \param [OUT] Time to wait for the next transmission according to the duty
+ * cycle.
+ *
+ * \retval status Function status [1: OK, 0: Unable to find a channel on the
+ * current datarate]
*/
-static TimerTime_t SetNextChannel( void );
+static bool SetNextChannel( TimerTime_t* time );
/*!
* \brief Sets the network to public or private. Updates the sync byte.
@@ -833,6 +838,28 @@
}
}
+static void PrepareRxDoneAbort( void )
+{
+ LoRaMacState &= ~MAC_TX_RUNNING;
+
+ if( NodeAckRequested )
+ {
+ OnAckTimeoutTimerEvent( );
+ }
+
+ if( ( RxSlot == 0 ) && ( LoRaMacDeviceClass == CLASS_C ) )
+ {
+ OnRxWindow2TimerEvent( );
+ }
+
+ LoRaMacFlags.Bits.McpsInd = 1;
+ LoRaMacFlags.Bits.MacDone = 1;
+
+ // Trig OnMacCheckTimerEvent call as soon as possible
+ TimerSetValue( &MacStateCheckTimer, 1000 );
+ TimerStart( &MacStateCheckTimer );
+}
+
static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
LoRaMacHeader_t macHdr;
@@ -941,11 +968,13 @@
ChannelParams_t param;
param.DrRange.Value = ( DR_5 << 4 ) | DR_0;
+ LoRaMacState |= MAC_TX_CONFIG;
for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 )
{
param.Frequency = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100;
LoRaMacChannelAdd( i, param );
}
+ LoRaMacState &= ~MAC_TX_CONFIG;
}
#endif
MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
@@ -960,8 +989,6 @@
case FRAME_TYPE_DATA_CONFIRMED_DOWN:
case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
{
- LoRaMacFlags.Bits.McpsInd = 1;
-
address = payload[pktHeaderLen++];
address |= ( (uint32_t)payload[pktHeaderLen++] << 8 );
address |= ( (uint32_t)payload[pktHeaderLen++] << 16 );
@@ -985,13 +1012,8 @@
if( multicast == 0 )
{
// We are not the destination of this frame.
- LoRaMacFlags.Bits.MacDone = 1;
McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL;
- LoRaMacState &= ~MAC_TX_RUNNING;
- if( NodeAckRequested )
- {
- OnAckTimeoutTimerEvent( );
- }
+ PrepareRxDoneAbort( );
return;
}
}
@@ -1003,12 +1025,6 @@
downLinkCounter = DownLinkCounter;
}
- if( LoRaMacDeviceClass != CLASS_A )
- {
- LoRaMacState |= MAC_RX;
- // Starts the MAC layer status check timer
- TimerStart( &MacStateCheckTimer );
- }
fCtrl.Value = payload[pktHeaderLen++];
sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
@@ -1066,14 +1082,9 @@
if( ( curMulticastParams->DownLinkCounter == downLinkCounter ) &&
( curMulticastParams->DownLinkCounter != 0 ) )
{
- LoRaMacFlags.Bits.MacDone = 1;
McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
McpsIndication.DownLinkCounter = downLinkCounter;
- LoRaMacState &= ~MAC_TX_RUNNING;
- if( NodeAckRequested == true )
- {
- OnAckTimeoutTimerEvent( );
- }
+ PrepareRxDoneAbort( );
return;
}
curMulticastParams->DownLinkCounter = downLinkCounter;
@@ -1082,36 +1093,25 @@
{
if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN )
{
+ SrvAckRequested = true;
McpsIndication.McpsIndication = MCPS_CONFIRMED;
}
else
{
+ SrvAckRequested = false;
McpsIndication.McpsIndication = MCPS_UNCONFIRMED;
}
if( ( DownLinkCounter == downLinkCounter ) &&
( DownLinkCounter != 0 ) )
{
- LoRaMacFlags.Bits.MacDone = 1;
McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
McpsIndication.DownLinkCounter = downLinkCounter;
- LoRaMacState &= ~MAC_TX_RUNNING;
- if( NodeAckRequested == true )
- {
- OnAckTimeoutTimerEvent( );
- }
+ PrepareRxDoneAbort( );
return;
}
DownLinkCounter = downLinkCounter;
}
- if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN )
- {
- SrvAckRequested = true;
- }
- else
- {
- SrvAckRequested = false;
- }
// Check if the frame is an acknowledgement
if( fCtrl.Bits.Ack == 1 )
{
@@ -1174,34 +1174,32 @@
McpsIndication.RxData = true;
}
}
+ LoRaMacFlags.Bits.McpsInd = 1;
}
else
{
McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
- LoRaMacState &= ~MAC_TX_RUNNING;
- if( NodeAckRequested == true )
- {
- OnAckTimeoutTimerEvent( );
- }
+
+ PrepareRxDoneAbort( );
+ return;
}
}
break;
case FRAME_TYPE_PROPRIETARY:
{
- LoRaMacFlags.Bits.McpsInd = 1;
-
memcpy1( LoRaMacRxPayload, &payload[pktHeaderLen], size );
McpsIndication.McpsIndication = MCPS_PROPRIETARY;
McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK;
McpsIndication.Buffer = LoRaMacRxPayload;
McpsIndication.BufferSize = size - pktHeaderLen;
+
+ LoRaMacFlags.Bits.McpsInd = 1;
break;
}
default:
- LoRaMacFlags.Bits.McpsInd = 1;
McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
- LoRaMacState &= ~MAC_TX_RUNNING;
+ PrepareRxDoneAbort( );
break;
}
@@ -1209,8 +1207,11 @@
{
OnRxWindow2TimerEvent( );
}
-
LoRaMacFlags.Bits.MacDone = 1;
+
+ // Trig OnMacCheckTimerEvent call as soon as possible
+ TimerSetValue( &MacStateCheckTimer, 1000 );
+ TimerStart( &MacStateCheckTimer );
}
static void OnRadioTxTimeout( void )
@@ -1336,6 +1337,7 @@
if( ( McpsConfirm.AckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) )
{
AckTimeoutRetry = false;
+ NodeAckRequested = false;
if( IsUpLinkCounterFixed == false )
{
UpLinkCounter++;
@@ -1387,6 +1389,7 @@
#endif
LoRaMacState &= ~MAC_TX_RUNNING;
+ NodeAckRequested = false;
McpsConfirm.AckReceived = false;
McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
if( IsUpLinkCounterFixed == false )
@@ -1420,6 +1423,7 @@
else
{
// Operation not finished restart timer
+ TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
TimerStart( &MacStateCheckTimer );
}
@@ -1546,9 +1550,10 @@
}
}
-static TimerTime_t SetNextChannel( void )
+static bool SetNextChannel( TimerTime_t* time )
{
uint8_t nbEnabledChannels = 0;
+ uint8_t delayTx = 0;
uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
TimerTime_t curTime = TimerGetCurrentTime( );
TimerTime_t nextTxDelay = ( TimerTime_t )( -1 );
@@ -1556,11 +1561,28 @@
memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
- if( ( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) +
- ( ChannelsMaskRemaining[4] & 0x00FF ) ) == 0 )
+ if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 )
+ { // Restore default channels
+ memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, 8 );
+ }
+ if( ( ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
+ { // Make sure, that the channels are activated
+ ChannelsMaskRemaining[4] = ChannelsMask[4];
+ }
+#else
+ uint8_t chanCnt = 0;
+ for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
{
- memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask,
- sizeof( ChannelsMask ) );
+ if( ChannelsMask[k] != 0 )
+ {
+ chanCnt++;
+ break;
+ }
+ }
+ if( chanCnt == 0 )
+ {
+ // Re-enable default channels, if no channel is enabled
+ ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
}
#endif
@@ -1605,21 +1627,16 @@
{
if( Channels[i + j].Frequency == 0 )
{ // Check if the channel is enabled
-#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
- DisableChannelInMask( i + j, ChannelsMaskRemaining );
-#endif
continue;
}
if( ( ( Channels[i + j].DrRange.Fields.Min <= ChannelsDatarate ) &&
( ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
{ // Check if the current channel selection supports the given datarate
-#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
- DisableChannelInMask( i + j, ChannelsMaskRemaining );
-#endif
continue;
}
if( Bands[Channels[i + j].Band].TimeOff > 0 )
{ // Check if the band is available for transmission
+ delayTx++;
continue;
}
enabledChannels[nbEnabledChannels++] = i + j;
@@ -1629,6 +1646,7 @@
}
else
{
+ delayTx++;
nextTxDelay = AggregatedTimeOff - ( curTime - AggregatedLastTxDoneTime );
}
@@ -1636,14 +1654,25 @@
{
Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
- DisableChannelInMask( Channel, ChannelsMaskRemaining );
+ if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) )
+ {
+ DisableChannelInMask( Channel, ChannelsMaskRemaining );
+ }
#endif
- return 0;
+ *time = 0;
+ return true;
}
else
{
- // Protect the function of returning the initialization value of nextTxDelay
- return ( nextTxDelay == ( TimerTime_t )( -1 ) ) ? 0 : nextTxDelay;
+ if( delayTx > 0 )
+ {
+ // Delay transmission due to AggregatedTimeOff or to a band time off
+ *time = nextTxDelay;
+ return true;
+ }
+ // Datarate not supported by any channel
+ *time = 0;
+ return false;
}
}
@@ -1813,38 +1842,10 @@
{
AdrAckCounter = 0;
adrAckReq = false;
-
- if( updateChannelMask == true )
- {
-#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
- // Re-enable default channels LC1, LC2, LC3
- ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
-#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
-#if defined( USE_BAND_915 )
- // Re-enable default channels
- ChannelsMask[0] = 0xFFFF;
- ChannelsMask[1] = 0xFFFF;
- ChannelsMask[2] = 0xFFFF;
- ChannelsMask[3] = 0xFFFF;
- ChannelsMask[4] = 0x00FF;
- ChannelsMask[5] = 0x0000;
-#else // defined( USE_BAND_915_HYBRID )
- // Re-enable default channels
- ChannelsMask[0] = 0x00FF;
- ChannelsMask[1] = 0x0000;
- ChannelsMask[2] = 0x0000;
- ChannelsMask[3] = 0x0000;
- ChannelsMask[4] = 0x0001;
- ChannelsMask[5] = 0x0000;
-#endif
-#else
-#error "Please define a frequency band in the compiler options."
-#endif
- }
}
else
{
- if( AdrAckCounter > ADR_ACK_LIMIT )
+ if( AdrAckCounter >= ADR_ACK_LIMIT )
{
adrAckReq = true;
}
@@ -1852,26 +1853,60 @@
{
adrAckReq = false;
}
- if( AdrAckCounter > ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
+ if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
{
- AdrAckCounter = 0;
+ if( ( ( AdrAckCounter - ADR_ACK_DELAY ) % ADR_ACK_LIMIT ) == 0 )
+ {
#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
- if( datarate > LORAMAC_MIN_DATARATE )
- {
- datarate--;
- }
+ if( datarate > LORAMAC_MIN_DATARATE )
+ {
+ datarate--;
+ }
+ if( datarate == LORAMAC_MIN_DATARATE )
+ {
+ if( updateChannelMask == true )
+ {
+
+ // Re-enable default channels LC1, LC2, LC3
+ ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
+ }
+ }
#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
- if( ( datarate > LORAMAC_MIN_DATARATE ) && ( datarate == DR_8 ) )
- {
- datarate = DR_4;
- }
- else if( datarate > LORAMAC_MIN_DATARATE )
- {
- datarate--;
- }
+ if( ( datarate > LORAMAC_MIN_DATARATE ) && ( datarate == DR_8 ) )
+ {
+ datarate = DR_4;
+ }
+ else if( datarate > LORAMAC_MIN_DATARATE )
+ {
+ datarate--;
+ }
+ if( datarate == LORAMAC_MIN_DATARATE )
+ {
+ if( updateChannelMask == true )
+ {
+#if defined( USE_BAND_915 )
+ // Re-enable default channels
+ ChannelsMask[0] = 0xFFFF;
+ ChannelsMask[1] = 0xFFFF;
+ ChannelsMask[2] = 0xFFFF;
+ ChannelsMask[3] = 0xFFFF;
+ ChannelsMask[4] = 0x00FF;
+ ChannelsMask[5] = 0x0000;
+#else // defined( USE_BAND_915_HYBRID )
+ // Re-enable default channels
+ ChannelsMask[0] = 0x00FF;
+ ChannelsMask[1] = 0x0000;
+ ChannelsMask[2] = 0x0000;
+ ChannelsMask[3] = 0x0000;
+ ChannelsMask[4] = 0x0001;
+ ChannelsMask[5] = 0x0000;
+#endif
+ }
+ }
#else
#error "Please define a frequency band in the compiler options."
#endif
+ }
}
}
}
@@ -2193,8 +2228,10 @@
case SRV_MAC_NEW_CHANNEL_REQ:
{
uint8_t status = 0x03;
+
#if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
- status &= 0xFE; // Channel frequency KO
+ status &= 0xFC; // Channel frequency and datarate KO
+ macIndex += 5;
#else
int8_t channelIndex = 0;
ChannelParams_t chParam;
@@ -2206,21 +2243,52 @@
chParam.Frequency *= 100;
chParam.DrRange.Value = payload[macIndex++];
- if( ValueInRange( channelIndex, 3, LORA_MAX_NB_CHANNELS - 1 ) == false )
-
+ LoRaMacState |= MAC_TX_CONFIG;
+ if( chParam.Frequency == 0 )
{
- status &= 0xFE; // Channel frequency KO
+ if( channelIndex < 3 )
+ {
+ status &= 0xFC;
+ }
+ else
+ {
+ if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK )
+ {
+ status &= 0xFC;
+ }
+ }
}
-
- if( Radio.CheckRfFrequency( chParam.Frequency ) == false )
+ else
{
- status &= 0xFE; // Channel frequency KO
+ switch( LoRaMacChannelAdd( channelIndex, chParam ) )
+ {
+ case LORAMAC_STATUS_OK:
+ {
+ break;
+ }
+ case LORAMAC_STATUS_FREQUENCY_INVALID:
+ {
+ status &= 0xFE;
+ break;
+ }
+ case LORAMAC_STATUS_DATARATE_INVALID:
+ {
+ status &= 0xFD;
+ break;
+ }
+ case LORAMAC_STATUS_FREQ_AND_DR_INVALID:
+ {
+ status &= 0xFC;
+ break;
+ }
+ default:
+ {
+ status &= 0xFC;
+ break;
+ }
+ }
}
-
- if( LoRaMacChannelAdd( channelIndex, chParam ) != LORAMAC_STATUS_OK )
- {
- status &= 0xFD; // Datarate range KO
- }
+ LoRaMacState &= ~MAC_TX_CONFIG;
#endif
AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 );
}
@@ -2291,7 +2359,16 @@
}
// Select channel
- dutyCycleTimeOff = SetNextChannel( );
+ while( SetNextChannel( &dutyCycleTimeOff ) == false )
+ {
+ // Set the default datarate
+ ChannelsDatarate = ChannelsDefaultDatarate;
+
+#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
+ // Re-enable default channels LC1, LC2, LC3
+ ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
+#endif
+ }
// Schedule transmission of frame
if( dutyCycleTimeOff == 0 )
@@ -2365,6 +2442,8 @@
return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet
}
+ fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &ChannelsDatarate );
+
if( ValidatePayloadLength( fBufferSize, ChannelsDatarate, MacCommandsBufferIndex ) == false )
{
return LORAMAC_STATUS_LENGTH_ERROR;
@@ -2379,8 +2458,6 @@
fCtrl->Bits.Ack = 1;
}
- fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &ChannelsDatarate );
-
LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
@@ -2513,6 +2590,7 @@
MlmeConfirm.TxTimeOnAir = TxTimeOnAir;
// Starts the MAC layer status check timer
+ TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
TimerStart( &MacStateCheckTimer );
// Send now
@@ -3048,117 +3126,142 @@
LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
{
+#if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
+ return LORAMAC_STATUS_PARAMETER_INVALID;
+#else
+ bool datarateInvalid = false;
+ bool frequencyInvalid = false;
+ uint8_t band = 0;
+
+ // The id must not exceed LORA_MAX_NB_CHANNELS
if( id >= LORA_MAX_NB_CHANNELS )
{
return LORAMAC_STATUS_PARAMETER_INVALID;
}
+ // Validate if the MAC is in a correct state
if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
{
- return LORAMAC_STATUS_BUSY;
+ if( ( LoRaMacState & MAC_TX_CONFIG ) != MAC_TX_CONFIG )
+ {
+ return LORAMAC_STATUS_BUSY;
+ }
}
+ // Validate the datarate
if( ( params.DrRange.Fields.Min > params.DrRange.Fields.Max ) ||
( ValueInRange( params.DrRange.Fields.Min, LORAMAC_MIN_DATARATE,
LORAMAC_MAX_DATARATE ) == false ) ||
( ValueInRange( params.DrRange.Fields.Max, LORAMAC_MIN_DATARATE,
LORAMAC_MAX_DATARATE ) == false ) )
{
- return LORAMAC_STATUS_PARAMETER_INVALID;
+ datarateInvalid = true;
}
- params.Band = 0;
-
-#if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
- return LORAMAC_STATUS_PARAMETER_INVALID;
-#else
-#if defined( USE_BAND_433 ) || defined( USE_BAND_780 )
- Channels[id] = params;
- Channels[id].Band = 0; // No duty cycle on EU433 and CN470 bands
-#elif defined( USE_BAND_868 )
- Channels[id] = params;
- if( ( Channels[id].Frequency >= 865000000 ) && ( Channels[id].Frequency <= 868000000 ) )
+#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
+ if( id < 3 )
{
- if( Channels[id].Band != BAND_G1_0 )
+ if( params.Frequency != Channels[id].Frequency )
{
- Channels[id].Band = BAND_G1_0;
+ frequencyInvalid = true;
+ }
+
+ if( params.DrRange.Fields.Min > LORAMAC_DEFAULT_DATARATE )
+ {
+ datarateInvalid = true;
+ }
+ if( ValueInRange( params.DrRange.Fields.Max, DR_5, LORAMAC_MAX_DATARATE ) == false )
+ {
+ datarateInvalid = true;
}
}
- else if( ( Channels[id].Frequency > 868000000 ) && ( Channels[id].Frequency <= 868600000 ) )
+#endif
+
+ // Validate the frequency
+ if( ( Radio.CheckRfFrequency( params.Frequency ) == true ) && ( params.Frequency > 0 ) && ( frequencyInvalid == false ) )
{
- if( Channels[id].Band != BAND_G1_1 )
+#if defined( USE_BAND_868 )
+ if( ( params.Frequency >= 865000000 ) && ( params.Frequency <= 868000000 ) )
{
- Channels[id].Band = BAND_G1_1;
+ band = BAND_G1_0;
}
- }
- else if( ( Channels[id].Frequency >= 868700000 ) && ( Channels[id].Frequency <= 869200000 ) )
- {
- if( Channels[id].Band != BAND_G1_2 )
+ else if( ( params.Frequency > 868000000 ) && ( params.Frequency <= 868600000 ) )
{
- Channels[id].Band = BAND_G1_2;
+ band = BAND_G1_1;
}
- }
- else if( ( Channels[id].Frequency >= 869400000 ) && ( Channels[id].Frequency <= 869650000 ) )
- {
- if( Channels[id].Band != BAND_G1_3 )
+ else if( ( params.Frequency >= 868700000 ) && ( params.Frequency <= 869200000 ) )
{
- Channels[id].Band = BAND_G1_3;
+ band = BAND_G1_2;
+ }
+ else if( ( params.Frequency >= 869400000 ) && ( params.Frequency <= 869650000 ) )
+ {
+ band = BAND_G1_3;
}
- }
- else if( ( Channels[id].Frequency >= 869700000 ) && ( Channels[id].Frequency <= 870000000 ) )
- {
- if( Channels[id].Band != BAND_G1_4 )
+ else if( ( params.Frequency >= 869700000 ) && ( params.Frequency <= 870000000 ) )
{
- Channels[id].Band = BAND_G1_4;
+ band = BAND_G1_4;
}
+ else
+ {
+ frequencyInvalid = true;
+ }
+#endif
}
else
{
- Channels[id].Frequency = 0;
- Channels[id].DrRange.Value = 0;
+ frequencyInvalid = true;
+ }
+
+ if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
+ {
+ return LORAMAC_STATUS_FREQ_AND_DR_INVALID;
}
-#else
- #error "Please define a frequency band in the compiler options."
-#endif
- // Check if it is a valid channel
- if( Channels[id].Frequency > 0 )
+ if( datarateInvalid == true )
+ {
+ return LORAMAC_STATUS_DATARATE_INVALID;
+ }
+ if( frequencyInvalid == true )
{
- // Activate the newly created channel
- if( id < 16 )
- {
- ChannelsMask[0] |= 1 << id;
- }
+ return LORAMAC_STATUS_FREQUENCY_INVALID;
}
+ // Every parameter is valid, activate the channel
+ Channels[id] = params;
+ Channels[id].Band = band;
+ ChannelsMask[0] |= ( 1 << id );
+
return LORAMAC_STATUS_OK;
#endif
}
LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id )
{
+#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
{
- return LORAMAC_STATUS_BUSY;
+ if( ( LoRaMacState & MAC_TX_CONFIG ) != MAC_TX_CONFIG )
+ {
+ return LORAMAC_STATUS_BUSY;
+ }
}
-#if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
- if( id < 64 )
+
+ if( id < 3 )
{
- if( CountNbEnabled125kHzChannels( ChannelsMask ) <= 6 )
+ return LORAMAC_STATUS_PARAMETER_INVALID;
+ }
+ else
+ {
+ // Remove the channel from the list of channels
+ Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 };
+
+ // Disable the channel as it doesn't exist anymore
+ if( DisableChannelInMask( id, ChannelsMask ) == false )
{
return LORAMAC_STATUS_PARAMETER_INVALID;
}
}
-#else
- if( id < 3 )
- {
- return LORAMAC_STATUS_PARAMETER_INVALID;
- }
+ return LORAMAC_STATUS_OK;
+#elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
+ return LORAMAC_STATUS_PARAMETER_INVALID;
#endif
-
- if( DisableChannelInMask( id, ChannelsMask ) == false )
- {
- return LORAMAC_STATUS_PARAMETER_INVALID;
- }
-
- return LORAMAC_STATUS_OK;
}
LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam )
@@ -3283,6 +3386,14 @@
IsLoRaMacNetworkJoined = false;
#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+#if defined( USE_BAND_915 )
+ // Re-enable 500 kHz default channels
+ ChannelsMask[4] = 0x00FF;
+#else // defined( USE_BAND_915_HYBRID )
+ // Re-enable 500 kHz default channels
+ ChannelsMask[4] = 0x0001;
+#endif
+
static uint8_t drSwitch = 0;
if( ( ++drSwitch & 0x01 ) == 0x01 )
@@ -3362,7 +3473,7 @@
{
readyToSend = true;
AckTimeoutRetriesCounter = 1;
- AckTimeoutRetries = mcpsRequest->Req.Confirmed.nbRetries;
+ AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials;
macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP;
fPort = mcpsRequest->Req.Confirmed.fPort;
--- a/LoRaMac.h Tue Jan 05 16:41:54 2016 +0000
+++ b/LoRaMac.h Mon Mar 14 09:09:54 2016 +0000
@@ -674,10 +674,26 @@
*/
int8_t Datarate;
/*!
- * Number of attempts to transmit the frame, if frame could not be send, or
- * if the LoRaMAC layer did not receive an acknowledgment
+ * 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, chapter 18.4, according
+ * to 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 NbTrials is set to 1 or 2, the MAC will not decrease
+ * the datarate, in case the LoRaMAC layer did not receive an acknowledgment
*/
- uint8_t nbRetries;
+ uint8_t NbTrials;
}McpsReqConfirmed_t;
/*!
@@ -958,6 +974,7 @@
* \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
@@ -1341,6 +1358,18 @@
*/
LORAMAC_STATUS_PARAMETER_INVALID,
/*!
+ * Service not started - invalid frequency
+ */
+ LORAMAC_STATUS_FREQUENCY_INVALID,
+ /*!
+ * Service not started - invalid datarate
+ */
+ LORAMAC_STATUS_DATARATE_INVALID,
+ /*!
+ * Service not started - invalid frequency and datarate
+ */
+ LORAMAC_STATUS_FREQ_AND_DR_INVALID,
+ /*!
* Service not started - the device is not in a LoRaWAN
*/
LORAMAC_STATUS_NO_NETWORK_JOINED,
