wayne roberts / lorawan1v1

Dependencies:   sx12xx_hal

Dependents:   LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more

Committer:
Wayne Roberts
Date:
Mon Mar 05 16:49:15 2018 -0800
Revision:
3:eb174e10afbb
Parent:
0:6b3ac9c5a042
Child:
7:4b6f960dcca2
correct ADR_ACK_CNT

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:6b3ac9c5a042 1 //#include "Commissioning.h"
Wayne Roberts 0:6b3ac9c5a042 2 #include "board.h"
Wayne Roberts 0:6b3ac9c5a042 3 #if defined(USE_BAND_ARIB_8CH)
Wayne Roberts 0:6b3ac9c5a042 4 #include <stdint.h>
Wayne Roberts 0:6b3ac9c5a042 5 #include "LoRaMacPrivate.h"
Wayne Roberts 0:6b3ac9c5a042 6
Wayne Roberts 0:6b3ac9c5a042 7 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
Wayne Roberts 0:6b3ac9c5a042 8 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
Wayne Roberts 0:6b3ac9c5a042 9 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 };
Wayne Roberts 0:6b3ac9c5a042 10
Wayne Roberts 0:6b3ac9c5a042 11 ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
Wayne Roberts 0:6b3ac9c5a042 12 {
Wayne Roberts 0:6b3ac9c5a042 13 LC1,
Wayne Roberts 0:6b3ac9c5a042 14 LC2
Wayne Roberts 0:6b3ac9c5a042 15 /* other channels given by mac command */
Wayne Roberts 0:6b3ac9c5a042 16 };
Wayne Roberts 0:6b3ac9c5a042 17
Wayne Roberts 0:6b3ac9c5a042 18 uint32_t region_GetRxBandwidth( int8_t datarate )
Wayne Roberts 0:6b3ac9c5a042 19 {
Wayne Roberts 0:6b3ac9c5a042 20 if( datarate == DR_6 )
Wayne Roberts 0:6b3ac9c5a042 21 {// LoRa 250 kHz
Wayne Roberts 0:6b3ac9c5a042 22 return 1;
Wayne Roberts 0:6b3ac9c5a042 23 }
Wayne Roberts 0:6b3ac9c5a042 24 return 0; // LoRa 125 kHz
Wayne Roberts 0:6b3ac9c5a042 25 }
Wayne Roberts 0:6b3ac9c5a042 26
Wayne Roberts 0:6b3ac9c5a042 27 uint16_t region_GetRxSymbolTimeout( int8_t datarate )
Wayne Roberts 0:6b3ac9c5a042 28 {
Wayne Roberts 0:6b3ac9c5a042 29 if( ( datarate == DR_3 ) || ( datarate == DR_4 ) )
Wayne Roberts 0:6b3ac9c5a042 30 { // DR_4, DR_3
Wayne Roberts 0:6b3ac9c5a042 31 return 8;
Wayne Roberts 0:6b3ac9c5a042 32 }
Wayne Roberts 0:6b3ac9c5a042 33 else if( datarate == DR_5 )
Wayne Roberts 0:6b3ac9c5a042 34 {
Wayne Roberts 0:6b3ac9c5a042 35 return 10;
Wayne Roberts 0:6b3ac9c5a042 36 }
Wayne Roberts 0:6b3ac9c5a042 37 else if( datarate == DR_6 )
Wayne Roberts 0:6b3ac9c5a042 38 {
Wayne Roberts 0:6b3ac9c5a042 39 return 14;
Wayne Roberts 0:6b3ac9c5a042 40 }
Wayne Roberts 0:6b3ac9c5a042 41 return 5; // DR_2, DR_1, DR_0
Wayne Roberts 0:6b3ac9c5a042 42 }
Wayne Roberts 0:6b3ac9c5a042 43
Wayne Roberts 0:6b3ac9c5a042 44 void region_rx1_setup(uint8_t chan)
Wayne Roberts 0:6b3ac9c5a042 45 {
Wayne Roberts 0:6b3ac9c5a042 46 int8_t datarate = LoRaMacParams.ChannelsDatarate - LoRaMacParams.Rx1DrOffset;
Wayne Roberts 0:6b3ac9c5a042 47 if( datarate < 0 )
Wayne Roberts 0:6b3ac9c5a042 48 {
Wayne Roberts 0:6b3ac9c5a042 49 datarate = DR_0;
Wayne Roberts 0:6b3ac9c5a042 50 }
Wayne Roberts 0:6b3ac9c5a042 51
Wayne Roberts 0:6b3ac9c5a042 52 RxWindowSetup(
Wayne Roberts 0:6b3ac9c5a042 53 Channels[chan].FreqHz,
Wayne Roberts 0:6b3ac9c5a042 54 datarate,
Wayne Roberts 0:6b3ac9c5a042 55 region_GetRxBandwidth(datarate),
Wayne Roberts 0:6b3ac9c5a042 56 region_GetRxSymbolTimeout(datarate)
Wayne Roberts 0:6b3ac9c5a042 57 );
Wayne Roberts 0:6b3ac9c5a042 58 }
Wayne Roberts 0:6b3ac9c5a042 59
Wayne Roberts 0:6b3ac9c5a042 60 static bool SetNextChannel(LoRaMacStatus_t* status)
Wayne Roberts 0:6b3ac9c5a042 61 {
Wayne Roberts 0:6b3ac9c5a042 62 uint8_t nbEnabledChannels = 0;
Wayne Roberts 0:6b3ac9c5a042 63 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
Wayne Roberts 0:6b3ac9c5a042 64
Wayne Roberts 0:6b3ac9c5a042 65 memset( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
Wayne Roberts 0:6b3ac9c5a042 66
Wayne Roberts 0:6b3ac9c5a042 67 *status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Wayne Roberts 0:6b3ac9c5a042 68 if( CountBits( LoRaMacParams.ChannelsMask[0], 16 ) == 0 )
Wayne Roberts 0:6b3ac9c5a042 69 {
Wayne Roberts 0:6b3ac9c5a042 70 // Re-enable default channels, if no channel is enabled
Wayne Roberts 0:6b3ac9c5a042 71 LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
Wayne Roberts 0:6b3ac9c5a042 72 }
Wayne Roberts 0:6b3ac9c5a042 73
Wayne Roberts 0:6b3ac9c5a042 74 // Search how many channels are enabled
Wayne Roberts 0:6b3ac9c5a042 75 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
Wayne Roberts 0:6b3ac9c5a042 76 {
Wayne Roberts 0:6b3ac9c5a042 77 for( uint8_t j = 0; j < 16; j++ )
Wayne Roberts 0:6b3ac9c5a042 78 {
Wayne Roberts 0:6b3ac9c5a042 79 if( ( LoRaMacParams.ChannelsMask[k] & ( 1 << j ) ) != 0 )
Wayne Roberts 0:6b3ac9c5a042 80 {
Wayne Roberts 0:6b3ac9c5a042 81 if( Channels[i + j].FreqHz == 0 )
Wayne Roberts 0:6b3ac9c5a042 82 { // Check if the channel is enabled
Wayne Roberts 0:6b3ac9c5a042 83 continue;
Wayne Roberts 0:6b3ac9c5a042 84 }
Wayne Roberts 0:6b3ac9c5a042 85 #ifdef OVER_THE_AIR_ACTIVATION
Wayne Roberts 0:6b3ac9c5a042 86 if (!flags.IsLoRaMacNetworkJoined)
Wayne Roberts 0:6b3ac9c5a042 87 {
Wayne Roberts 0:6b3ac9c5a042 88 if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 )
Wayne Roberts 0:6b3ac9c5a042 89 {
Wayne Roberts 0:6b3ac9c5a042 90 continue;
Wayne Roberts 0:6b3ac9c5a042 91 }
Wayne Roberts 0:6b3ac9c5a042 92 }
Wayne Roberts 0:6b3ac9c5a042 93 #endif /* OVER_THE_AIR_ACTIVATION */
Wayne Roberts 0:6b3ac9c5a042 94 if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate ) &&
Wayne Roberts 0:6b3ac9c5a042 95 ( LoRaMacParams.ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
Wayne Roberts 0:6b3ac9c5a042 96 { // Check if the current channel selection supports the given datarate
Wayne Roberts 0:6b3ac9c5a042 97 *status = LORAMAC_STATUS_DATARATE_INVALID;
Wayne Roberts 0:6b3ac9c5a042 98 continue;
Wayne Roberts 0:6b3ac9c5a042 99 }
Wayne Roberts 0:6b3ac9c5a042 100 enabledChannels[nbEnabledChannels++] = i + j;
Wayne Roberts 0:6b3ac9c5a042 101 }
Wayne Roberts 0:6b3ac9c5a042 102 }
Wayne Roberts 0:6b3ac9c5a042 103 }
Wayne Roberts 0:6b3ac9c5a042 104
Wayne Roberts 0:6b3ac9c5a042 105 if( nbEnabledChannels > 0 )
Wayne Roberts 0:6b3ac9c5a042 106 {
Wayne Roberts 0:6b3ac9c5a042 107 Channel = enabledChannels[random_at_most(nbEnabledChannels - 1)];
Wayne Roberts 0:6b3ac9c5a042 108 *status = LORAMAC_STATUS_OK;
Wayne Roberts 0:6b3ac9c5a042 109 return true;
Wayne Roberts 0:6b3ac9c5a042 110 }
Wayne Roberts 0:6b3ac9c5a042 111 else
Wayne Roberts 0:6b3ac9c5a042 112 {
Wayne Roberts 0:6b3ac9c5a042 113 // Datarate not supported by any channel
Wayne Roberts 0:6b3ac9c5a042 114 return false;
Wayne Roberts 0:6b3ac9c5a042 115 }
Wayne Roberts 0:6b3ac9c5a042 116 }
Wayne Roberts 0:6b3ac9c5a042 117
Wayne Roberts 0:6b3ac9c5a042 118
Wayne Roberts 0:6b3ac9c5a042 119 static us_timestamp_t defer_uplink_us;
Wayne Roberts 0:6b3ac9c5a042 120
Wayne Roberts 0:6b3ac9c5a042 121 void region_ScheduleTx( )
Wayne Roberts 0:6b3ac9c5a042 122 {
Wayne Roberts 0:6b3ac9c5a042 123 LoRaMacStatus_t ret;
Wayne Roberts 0:6b3ac9c5a042 124
Wayne Roberts 0:6b3ac9c5a042 125 if (defer_uplink_us > 0) {
Wayne Roberts 0:6b3ac9c5a042 126 TxDelayedEvent.attach_us(OnTxDelayedTimerEvent, defer_uplink_us);
Wayne Roberts 0:6b3ac9c5a042 127 defer_uplink_us = 0;
Wayne Roberts 0:6b3ac9c5a042 128 return;
Wayne Roberts 0:6b3ac9c5a042 129 }
Wayne Roberts 0:6b3ac9c5a042 130
Wayne Roberts 0:6b3ac9c5a042 131 // Select channel
Wayne Roberts 0:6b3ac9c5a042 132 if (!SetNextChannel(&ret))
Wayne Roberts 0:6b3ac9c5a042 133 {
Wayne Roberts 0:6b3ac9c5a042 134 // Set the default datarate
Wayne Roberts 0:6b3ac9c5a042 135 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
Wayne Roberts 0:6b3ac9c5a042 136 // re-enable default channels
Wayne Roberts 0:6b3ac9c5a042 137 LoRaMacParams.ChannelsMask[0] = LoRaMacParamsDefaults.ChannelsMask[0];
Wayne Roberts 0:6b3ac9c5a042 138 if (!SetNextChannel(&ret))
Wayne Roberts 0:6b3ac9c5a042 139 return;
Wayne Roberts 0:6b3ac9c5a042 140 }
Wayne Roberts 0:6b3ac9c5a042 141
Wayne Roberts 0:6b3ac9c5a042 142 // Schedule transmission of frame
Wayne Roberts 0:6b3ac9c5a042 143 // Try to send now
Wayne Roberts 0:6b3ac9c5a042 144 SendFrameOnChannel( Channel );
Wayne Roberts 0:6b3ac9c5a042 145 }
Wayne Roberts 0:6b3ac9c5a042 146
Wayne Roberts 3:eb174e10afbb 147 #define RECEIVE_DELAY2_us 2000000
Wayne Roberts 3:eb174e10afbb 148 #define JOIN_ACCEPT_DELAY1_us 5000000
Wayne Roberts 3:eb174e10afbb 149 #define JOIN_ACCEPT_DELAY2_us 6000000
Wayne Roberts 3:eb174e10afbb 150 const LoRaMacParams_t LoRaMacParamsDefaults = {
Wayne Roberts 3:eb174e10afbb 151 /* int8_t ChannelsTxPower; */ LORAMAC_DEFAULT_TX_POWER,
Wayne Roberts 3:eb174e10afbb 152 /* int8_t ChannelsDatarate;*/ LORAMAC_DEFAULT_DATARATE,
Wayne Roberts 3:eb174e10afbb 153 /* uint32_t MaxRxWindow_us;*/ MAX_RX_WINDOW_us,
Wayne Roberts 3:eb174e10afbb 154 /* uint32_t ReceiveDelay1_us;*/ RECEIVE_DELAY1_us,
Wayne Roberts 3:eb174e10afbb 155 /* uint32_t ReceiveDelay2_us;*/ RECEIVE_DELAY2_us,
Wayne Roberts 3:eb174e10afbb 156 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 3:eb174e10afbb 157 /* uint32_t JoinAcceptDelay1_us;*/ JOIN_ACCEPT_DELAY1_us,
Wayne Roberts 3:eb174e10afbb 158 /* uint32_t JoinAcceptDelay2_us;*/ JOIN_ACCEPT_DELAY2_us,
Wayne Roberts 3:eb174e10afbb 159 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 3:eb174e10afbb 160 /* uint8_t NbTrans;*/ 1,
Wayne Roberts 3:eb174e10afbb 161 /* uint8_t Rx1DrOffset;*/ 0,
Wayne Roberts 3:eb174e10afbb 162 /* Rx2ChannelParams_t Rx2Channel;*/ RX_WND_2_CHANNEL,
Wayne Roberts 3:eb174e10afbb 163 /* uint16_t ChannelsMask[6];*/ { (LC(1)+LC(2)), 0, 0, 0, 0, 0},/* only boot channels enabled */
Wayne Roberts 3:eb174e10afbb 164 /* uint8_t NbEnabledChannels;*/ 2,
Wayne Roberts 3:eb174e10afbb 165 };
Wayne Roberts 3:eb174e10afbb 166
Wayne Roberts 0:6b3ac9c5a042 167 void region_mac_init()
Wayne Roberts 0:6b3ac9c5a042 168 {
Wayne Roberts 0:6b3ac9c5a042 169 }
Wayne Roberts 0:6b3ac9c5a042 170
Wayne Roberts 0:6b3ac9c5a042 171 void region_adr_request(adr_t* adr)
Wayne Roberts 0:6b3ac9c5a042 172 {
Wayne Roberts 0:6b3ac9c5a042 173 uint8_t i;
Wayne Roberts 0:6b3ac9c5a042 174
Wayne Roberts 0:6b3ac9c5a042 175 if( ( adr->chMaskCntl == 0 ) && ( adr->chMask == 0 ) )
Wayne Roberts 0:6b3ac9c5a042 176 {
Wayne Roberts 0:6b3ac9c5a042 177 adr->status &= 0xFE; // Channel mask KO
Wayne Roberts 0:6b3ac9c5a042 178 }
Wayne Roberts 0:6b3ac9c5a042 179 else if( ( ( adr->chMaskCntl >= 1 ) && ( adr->chMaskCntl <= 5 )) ||
Wayne Roberts 0:6b3ac9c5a042 180 ( adr->chMaskCntl >= 7 ) )
Wayne Roberts 0:6b3ac9c5a042 181 {
Wayne Roberts 0:6b3ac9c5a042 182 // RFU
Wayne Roberts 0:6b3ac9c5a042 183 adr->status &= 0xFE; // Channel mask KO
Wayne Roberts 0:6b3ac9c5a042 184 }
Wayne Roberts 0:6b3ac9c5a042 185 else
Wayne Roberts 0:6b3ac9c5a042 186 {
Wayne Roberts 0:6b3ac9c5a042 187 for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
Wayne Roberts 0:6b3ac9c5a042 188 {
Wayne Roberts 0:6b3ac9c5a042 189 if( adr->chMaskCntl == 6 )
Wayne Roberts 0:6b3ac9c5a042 190 {
Wayne Roberts 0:6b3ac9c5a042 191 if( Channels[i].FreqHz != 0 )
Wayne Roberts 0:6b3ac9c5a042 192 {
Wayne Roberts 0:6b3ac9c5a042 193 adr->chMask |= 1 << i;
Wayne Roberts 0:6b3ac9c5a042 194 }
Wayne Roberts 0:6b3ac9c5a042 195 }
Wayne Roberts 0:6b3ac9c5a042 196 else
Wayne Roberts 0:6b3ac9c5a042 197 {
Wayne Roberts 0:6b3ac9c5a042 198 if( ( ( adr->chMask & ( 1 << i ) ) != 0 ) &&
Wayne Roberts 0:6b3ac9c5a042 199 ( Channels[i].FreqHz == 0 ) )
Wayne Roberts 0:6b3ac9c5a042 200 {// Trying to enable an undefined channel
Wayne Roberts 0:6b3ac9c5a042 201 adr->status &= 0xFE; // Channel mask KO
Wayne Roberts 0:6b3ac9c5a042 202 }
Wayne Roberts 0:6b3ac9c5a042 203 }
Wayne Roberts 0:6b3ac9c5a042 204 }
Wayne Roberts 0:6b3ac9c5a042 205 adr->channelsMask[0] = adr->chMask;
Wayne Roberts 0:6b3ac9c5a042 206 MAC_PRINTF("arib set channelsMask:%04x ", adr->channelsMask[0]);
Wayne Roberts 0:6b3ac9c5a042 207 }
Wayne Roberts 0:6b3ac9c5a042 208 }
Wayne Roberts 0:6b3ac9c5a042 209
Wayne Roberts 0:6b3ac9c5a042 210 void region_tx_setup(int8_t txPower, uint8_t pktLen)
Wayne Roberts 0:6b3ac9c5a042 211 {
Wayne Roberts 0:6b3ac9c5a042 212 int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate];
Wayne Roberts 0:6b3ac9c5a042 213
Wayne Roberts 0:6b3ac9c5a042 214 if( LoRaMacParams.ChannelsDatarate == DR_7 )
Wayne Roberts 0:6b3ac9c5a042 215 { // High Speed FSK channel
Wayne Roberts 0:6b3ac9c5a042 216 Radio::SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, false);
Wayne Roberts 0:6b3ac9c5a042 217 //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_FSK, LoRaMacBufferPktLen );
Wayne Roberts 0:6b3ac9c5a042 218
Wayne Roberts 0:6b3ac9c5a042 219 }
Wayne Roberts 0:6b3ac9c5a042 220 else if( LoRaMacParams.ChannelsDatarate == DR_6 )
Wayne Roberts 0:6b3ac9c5a042 221 { // High speed LoRa channel
Wayne Roberts 0:6b3ac9c5a042 222 Radio::SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, false);
Wayne Roberts 0:6b3ac9c5a042 223 //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_LORA, LoRaMacBufferPktLen );
Wayne Roberts 0:6b3ac9c5a042 224 }
Wayne Roberts 0:6b3ac9c5a042 225 else
Wayne Roberts 0:6b3ac9c5a042 226 { // Normal LoRa channel
Wayne Roberts 0:6b3ac9c5a042 227 Radio::SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, false);
Wayne Roberts 0:6b3ac9c5a042 228 //TxTimeOnAir_us = Radio.TimeOnAir_us( MODEM_LORA, LoRaMacBufferPktLen );
Wayne Roberts 0:6b3ac9c5a042 229 }
Wayne Roberts 0:6b3ac9c5a042 230 }
Wayne Roberts 0:6b3ac9c5a042 231
Wayne Roberts 0:6b3ac9c5a042 232 static bool DisableChannelInMask( uint8_t id, uint16_t* mask )
Wayne Roberts 0:6b3ac9c5a042 233 {
Wayne Roberts 0:6b3ac9c5a042 234 uint8_t index = 0;
Wayne Roberts 0:6b3ac9c5a042 235 index = id / 16;
Wayne Roberts 0:6b3ac9c5a042 236
Wayne Roberts 0:6b3ac9c5a042 237 if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
Wayne Roberts 0:6b3ac9c5a042 238 {
Wayne Roberts 0:6b3ac9c5a042 239 return false;
Wayne Roberts 0:6b3ac9c5a042 240 }
Wayne Roberts 0:6b3ac9c5a042 241
Wayne Roberts 0:6b3ac9c5a042 242 // Deactivate channel
Wayne Roberts 0:6b3ac9c5a042 243 mask[index] &= ~( 1 << ( id % 16 ) );
Wayne Roberts 0:6b3ac9c5a042 244
Wayne Roberts 0:6b3ac9c5a042 245 return true;
Wayne Roberts 0:6b3ac9c5a042 246 }
Wayne Roberts 0:6b3ac9c5a042 247
Wayne Roberts 0:6b3ac9c5a042 248 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id )
Wayne Roberts 0:6b3ac9c5a042 249 {
Wayne Roberts 0:6b3ac9c5a042 250 /*if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
Wayne Roberts 0:6b3ac9c5a042 251 {
Wayne Roberts 0:6b3ac9c5a042 252 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
Wayne Roberts 0:6b3ac9c5a042 253 {
Wayne Roberts 0:6b3ac9c5a042 254 return LORAMAC_STATUS_BUSY;
Wayne Roberts 0:6b3ac9c5a042 255 }
Wayne Roberts 0:6b3ac9c5a042 256 }*/
Wayne Roberts 0:6b3ac9c5a042 257
Wayne Roberts 0:6b3ac9c5a042 258 if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
Wayne Roberts 0:6b3ac9c5a042 259 {
Wayne Roberts 0:6b3ac9c5a042 260 return LORAMAC_STATUS_PARAMETER_INVALID;
Wayne Roberts 0:6b3ac9c5a042 261 }
Wayne Roberts 0:6b3ac9c5a042 262 else
Wayne Roberts 0:6b3ac9c5a042 263 {
Wayne Roberts 0:6b3ac9c5a042 264 // Remove the channel from the list of channels
Wayne Roberts 0:6b3ac9c5a042 265 Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 };
Wayne Roberts 0:6b3ac9c5a042 266
Wayne Roberts 0:6b3ac9c5a042 267 // Disable the channel as it doesn't exist anymore
Wayne Roberts 0:6b3ac9c5a042 268 if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask ) == false )
Wayne Roberts 0:6b3ac9c5a042 269 {
Wayne Roberts 0:6b3ac9c5a042 270 return LORAMAC_STATUS_PARAMETER_INVALID;
Wayne Roberts 0:6b3ac9c5a042 271 }
Wayne Roberts 0:6b3ac9c5a042 272 }
Wayne Roberts 0:6b3ac9c5a042 273 return LORAMAC_STATUS_OK;
Wayne Roberts 0:6b3ac9c5a042 274 }
Wayne Roberts 0:6b3ac9c5a042 275
Wayne Roberts 0:6b3ac9c5a042 276 static bool ValidateDrRange( DrRange_t drRange, int8_t min, int8_t max )
Wayne Roberts 0:6b3ac9c5a042 277 {
Wayne Roberts 0:6b3ac9c5a042 278 int8_t drMin = drRange.Fields.Min & 0x0F;
Wayne Roberts 0:6b3ac9c5a042 279 int8_t drMax = drRange.Fields.Max & 0x0F;
Wayne Roberts 0:6b3ac9c5a042 280
Wayne Roberts 0:6b3ac9c5a042 281 if( drMin > drMax )
Wayne Roberts 0:6b3ac9c5a042 282 {
Wayne Roberts 0:6b3ac9c5a042 283 return false;
Wayne Roberts 0:6b3ac9c5a042 284 }
Wayne Roberts 0:6b3ac9c5a042 285 if( ValueInRange( drMin, min, max ) == false )
Wayne Roberts 0:6b3ac9c5a042 286 {
Wayne Roberts 0:6b3ac9c5a042 287 return false;
Wayne Roberts 0:6b3ac9c5a042 288 }
Wayne Roberts 0:6b3ac9c5a042 289 if( ValueInRange( drMax, min, max ) == false )
Wayne Roberts 0:6b3ac9c5a042 290 {
Wayne Roberts 0:6b3ac9c5a042 291 return false;
Wayne Roberts 0:6b3ac9c5a042 292 }
Wayne Roberts 0:6b3ac9c5a042 293 return true;
Wayne Roberts 0:6b3ac9c5a042 294 }
Wayne Roberts 0:6b3ac9c5a042 295
Wayne Roberts 0:6b3ac9c5a042 296 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
Wayne Roberts 0:6b3ac9c5a042 297 {
Wayne Roberts 0:6b3ac9c5a042 298 bool datarateInvalid = false;
Wayne Roberts 0:6b3ac9c5a042 299 bool frequencyInvalid = false;
Wayne Roberts 0:6b3ac9c5a042 300 uint8_t band = 0;
Wayne Roberts 0:6b3ac9c5a042 301
Wayne Roberts 0:6b3ac9c5a042 302 //MAC_PRINTF("channelAdd(%u,%u)\r\n", id, params.Frequency);
Wayne Roberts 0:6b3ac9c5a042 303 // The id must not exceed LORA_MAX_NB_CHANNELS
Wayne Roberts 0:6b3ac9c5a042 304 if( id >= LORA_MAX_NB_CHANNELS )
Wayne Roberts 0:6b3ac9c5a042 305 {
Wayne Roberts 0:6b3ac9c5a042 306 return LORAMAC_STATUS_PARAMETER_INVALID;
Wayne Roberts 0:6b3ac9c5a042 307 }
Wayne Roberts 0:6b3ac9c5a042 308
Wayne Roberts 0:6b3ac9c5a042 309 // Validate the datarate
Wayne Roberts 0:6b3ac9c5a042 310 if( ValidateDrRange( params.DrRange, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false )
Wayne Roberts 0:6b3ac9c5a042 311 {
Wayne Roberts 0:6b3ac9c5a042 312 datarateInvalid = true;
Wayne Roberts 0:6b3ac9c5a042 313 }
Wayne Roberts 0:6b3ac9c5a042 314
Wayne Roberts 0:6b3ac9c5a042 315 // Validate the frequency
Wayne Roberts 0:6b3ac9c5a042 316 if( ( Radio::CheckRfFrequency( params.FreqHz ) == true ) && ( params.FreqHz > 0 ) && ( frequencyInvalid == false ) )
Wayne Roberts 0:6b3ac9c5a042 317 {
Wayne Roberts 0:6b3ac9c5a042 318 frequencyInvalid = false;
Wayne Roberts 0:6b3ac9c5a042 319 }
Wayne Roberts 0:6b3ac9c5a042 320 else
Wayne Roberts 0:6b3ac9c5a042 321 {
Wayne Roberts 0:6b3ac9c5a042 322 frequencyInvalid = true;
Wayne Roberts 0:6b3ac9c5a042 323 }
Wayne Roberts 0:6b3ac9c5a042 324
Wayne Roberts 0:6b3ac9c5a042 325 if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
Wayne Roberts 0:6b3ac9c5a042 326 {
Wayne Roberts 0:6b3ac9c5a042 327 return LORAMAC_STATUS_FREQ_AND_DR_INVALID;
Wayne Roberts 0:6b3ac9c5a042 328 }
Wayne Roberts 0:6b3ac9c5a042 329 if( datarateInvalid == true )
Wayne Roberts 0:6b3ac9c5a042 330 {
Wayne Roberts 0:6b3ac9c5a042 331 return LORAMAC_STATUS_DATARATE_INVALID;
Wayne Roberts 0:6b3ac9c5a042 332 }
Wayne Roberts 0:6b3ac9c5a042 333 if( frequencyInvalid == true )
Wayne Roberts 0:6b3ac9c5a042 334 {
Wayne Roberts 0:6b3ac9c5a042 335 return LORAMAC_STATUS_FREQUENCY_INVALID;
Wayne Roberts 0:6b3ac9c5a042 336 }
Wayne Roberts 0:6b3ac9c5a042 337
Wayne Roberts 0:6b3ac9c5a042 338 // Every parameter is valid, activate the channel
Wayne Roberts 0:6b3ac9c5a042 339 Channels[id] = params;
Wayne Roberts 0:6b3ac9c5a042 340 Channels[id].Band = band;
Wayne Roberts 0:6b3ac9c5a042 341 LoRaMacParams.ChannelsMask[0] |= ( 1 << id );
Wayne Roberts 0:6b3ac9c5a042 342
Wayne Roberts 0:6b3ac9c5a042 343 return LORAMAC_STATUS_OK;
Wayne Roberts 0:6b3ac9c5a042 344 }
Wayne Roberts 0:6b3ac9c5a042 345
Wayne Roberts 0:6b3ac9c5a042 346 void
Wayne Roberts 0:6b3ac9c5a042 347 region_session_start(LoRaMacEventInfoStatus_t status)
Wayne Roberts 0:6b3ac9c5a042 348 {
Wayne Roberts 0:6b3ac9c5a042 349 McpsReq_t mcpsReq;
Wayne Roberts 0:6b3ac9c5a042 350
Wayne Roberts 0:6b3ac9c5a042 351 if (LoRaMacParams.ChannelsMask[0] == 0x003c) {
Wayne Roberts 0:6b3ac9c5a042 352 return;
Wayne Roberts 0:6b3ac9c5a042 353 }
Wayne Roberts 0:6b3ac9c5a042 354 /* send mac commands until desired channel mask */
Wayne Roberts 0:6b3ac9c5a042 355
Wayne Roberts 0:6b3ac9c5a042 356 mcpsReq.Type = MCPS_UNCONFIRMED;
Wayne Roberts 0:6b3ac9c5a042 357 mcpsReq.Req.fPort = 1;
Wayne Roberts 0:6b3ac9c5a042 358 mcpsReq.Req.fBuffer = NULL;
Wayne Roberts 0:6b3ac9c5a042 359 mcpsReq.Req.fBufferSize = 0;
Wayne Roberts 0:6b3ac9c5a042 360 mcpsReq.Req.Datarate = DR_3;
Wayne Roberts 0:6b3ac9c5a042 361
Wayne Roberts 0:6b3ac9c5a042 362 defer_uplink_us = 2000000 + random_at_most(2000000);
Wayne Roberts 0:6b3ac9c5a042 363 LoRaMacMcpsRequest( &mcpsReq );
Wayne Roberts 0:6b3ac9c5a042 364 }
Wayne Roberts 0:6b3ac9c5a042 365
Wayne Roberts 3:eb174e10afbb 366 int8_t region_LimitTxPower( int8_t txPower )
Wayne Roberts 3:eb174e10afbb 367 {
Wayne Roberts 3:eb174e10afbb 368 return txPower;
Wayne Roberts 3:eb174e10afbb 369 }
Wayne Roberts 3:eb174e10afbb 370
Wayne Roberts 3:eb174e10afbb 371 uint8_t region_CountNbEnabledChannels()
Wayne Roberts 3:eb174e10afbb 372 {
Wayne Roberts 3:eb174e10afbb 373 return CountBits(LoRaMacParams.ChannelsMask[4], 16);
Wayne Roberts 3:eb174e10afbb 374 }
Wayne Roberts 3:eb174e10afbb 375
Wayne Roberts 3:eb174e10afbb 376 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 3:eb174e10afbb 377 int8_t
Wayne Roberts 3:eb174e10afbb 378 region_AlternateDatarate( uint16_t nbTrials )
Wayne Roberts 3:eb174e10afbb 379 {
Wayne Roberts 3:eb174e10afbb 380 if( ( nbTrials % 48 ) == 0 )
Wayne Roberts 3:eb174e10afbb 381 {
Wayne Roberts 3:eb174e10afbb 382 return DR_0;
Wayne Roberts 3:eb174e10afbb 383 }
Wayne Roberts 3:eb174e10afbb 384 else if( ( nbTrials % 32 ) == 0 )
Wayne Roberts 3:eb174e10afbb 385 {
Wayne Roberts 3:eb174e10afbb 386 return DR_1;
Wayne Roberts 3:eb174e10afbb 387 }
Wayne Roberts 3:eb174e10afbb 388 else if( ( nbTrials % 24 ) == 0 )
Wayne Roberts 3:eb174e10afbb 389 {
Wayne Roberts 3:eb174e10afbb 390 return DR_2;
Wayne Roberts 3:eb174e10afbb 391 }
Wayne Roberts 3:eb174e10afbb 392 else if( ( nbTrials % 16 ) == 0 )
Wayne Roberts 3:eb174e10afbb 393 {
Wayne Roberts 3:eb174e10afbb 394 return DR_3;
Wayne Roberts 3:eb174e10afbb 395 }
Wayne Roberts 3:eb174e10afbb 396 else if( ( nbTrials % 8 ) == 0 )
Wayne Roberts 3:eb174e10afbb 397 {
Wayne Roberts 3:eb174e10afbb 398 return DR_4;
Wayne Roberts 3:eb174e10afbb 399 }
Wayne Roberts 3:eb174e10afbb 400 else
Wayne Roberts 3:eb174e10afbb 401 {
Wayne Roberts 3:eb174e10afbb 402 return DR_5;
Wayne Roberts 3:eb174e10afbb 403 }
Wayne Roberts 3:eb174e10afbb 404 }
Wayne Roberts 3:eb174e10afbb 405 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 3:eb174e10afbb 406
Wayne Roberts 0:6b3ac9c5a042 407 #endif /* USE_BAND_ARIB_8CH */
Wayne Roberts 0:6b3ac9c5a042 408