nimita naik / Mbed 2 deprecated LoRaWAN-STM32

Dependencies:   mbed LoRaWAN-lib SX1276Lib

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2015 Semtech
00008 
00009 Description: LoRaMac classA device implementation
00010 */
00011 #include "mbed.h"
00012 #include "board.h"
00013 #include "radio.h"
00014 
00015 #include "LoRaMac.h"
00016 #include "Commissioning.h"
00017 #include "SerialDisplay.h"
00018 
00019 /*!
00020  * Defines the application data transmission duty cycle. 5s, value in [ms].
00021  */
00022 #define APP_TX_DUTYCYCLE                            5000
00023 
00024 /*!
00025  * Defines a random delay for application data transmission duty cycle. 1s,
00026  * value in [ms].
00027  */
00028 #define APP_TX_DUTYCYCLE_RND                        1000
00029 
00030 /*!
00031  * Default datarate
00032  */
00033 #define LORAWAN_DEFAULT_DATARATE                    DR_0
00034 
00035 /*!
00036  * LoRaWAN confirmed messages
00037  */
00038 #define LORAWAN_CONFIRMED_MSG_ON                    false
00039 
00040 /*!
00041  * LoRaWAN Adaptive Data Rate
00042  *
00043  * \remark Please note that when ADR is enabled the end-device should be static
00044  */
00045 #define LORAWAN_ADR_ON                              1
00046 
00047 #if defined( USE_BAND_868 )
00048 
00049 #include "LoRaMacTest.h"
00050 
00051 /*!
00052  * LoRaWAN ETSI duty cycle control enable/disable
00053  *
00054  * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
00055  */
00056 #define LORAWAN_DUTYCYCLE_ON                        false
00057 
00058 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP          1
00059 
00060 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
00061 
00062 #define LC4                { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00063 #define LC5                { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00064 #define LC6                { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00065 #define LC7                { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00066 #define LC8                { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00067 #define LC9                { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
00068 #define LC10               { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
00069 
00070 #endif
00071 
00072 #endif
00073 
00074 /*!
00075  * LoRaWAN application port
00076  */
00077 #define LORAWAN_APP_PORT                            10
00078 
00079 /*!
00080  * User application data buffer size
00081  */
00082 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
00083 #define LORAWAN_APP_DATA_SIZE                       6
00084 
00085 #else
00086 #define LORAWAN_APP_DATA_SIZE                       5
00087 
00088 #endif
00089 
00090 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
00091 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
00092 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
00093 
00094 #if( OVER_THE_AIR_ACTIVATION == 0 )
00095 
00096 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
00097 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
00098 
00099 /*!
00100  * Device address
00101  */
00102 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
00103 
00104 #endif
00105 
00106 /*!
00107  * Application port
00108  */
00109 static uint8_t AppPort = LORAWAN_APP_PORT;
00110 
00111 /*!
00112  * User application data size
00113  */
00114 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
00115 
00116 /*!
00117  * User application data buffer size
00118  */
00119 #define LORAWAN_APP_DATA_MAX_SIZE                           64
00120 
00121 /*!
00122  * User application data
00123  */
00124 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
00125 
00126 /*!
00127  * Indicates if the node is sending confirmed or unconfirmed messages
00128  */
00129 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00130 
00131 /*!
00132  * Defines the application data transmission duty cycle
00133  */
00134 static uint32_t TxDutyCycleTime;
00135 
00136 /*!
00137  * Timer to handle the application data transmission duty cycle
00138  */
00139 static TimerEvent_t TxNextPacketTimer;
00140 
00141 /*!
00142  * Specifies the state of the application LED
00143  */
00144 static bool AppLedStateOn = false;
00145 volatile bool Led3StateChanged = false;
00146 /*!
00147  * Timer to handle the state of LED1
00148  */
00149 static TimerEvent_t Led1Timer;
00150 volatile bool Led1State = false;
00151 volatile bool Led1StateChanged = false;
00152 /*!
00153  * Timer to handle the state of LED2
00154  */
00155 static TimerEvent_t Led2Timer;
00156 volatile bool Led2State = false;
00157 volatile bool Led2StateChanged = false;
00158 
00159 
00160 DigitalOut myled(PA_5, 1);
00161 
00162 /*!
00163  * Indicates if a new packet can be sent
00164  */
00165 static bool NextTx = true;
00166 
00167 /*!
00168  * Device states
00169  */
00170 static enum eDeviceState
00171 {
00172     DEVICE_STATE_INIT,
00173     DEVICE_STATE_JOIN,
00174     DEVICE_STATE_SEND,
00175     DEVICE_STATE_CYCLE,
00176     DEVICE_STATE_SLEEP
00177 }DeviceState;
00178 
00179 /*!
00180  * LoRaWAN compliance tests support data
00181  */
00182 struct ComplianceTest_s
00183 {
00184     bool Running;
00185     uint8_t State;
00186     bool IsTxConfirmed;
00187     uint8_t AppPort;
00188     uint8_t AppDataSize;
00189     uint8_t *AppDataBuffer;
00190     uint16_t DownLinkCounter;
00191     bool LinkCheck;
00192     uint8_t DemodMargin;
00193     uint8_t NbGateways;
00194 }ComplianceTest;
00195 
00196 /*
00197  * SerialDisplay managment variables
00198  */
00199 
00200 /*!
00201  * Indicates if the MAC layer network join status has changed.
00202  */
00203 static bool IsNetworkJoinedStatusUpdate = false;
00204 
00205 /*!
00206  * Strucure containing the Uplink status
00207  */
00208 struct sLoRaMacUplinkStatus
00209 {
00210     uint8_t Acked;
00211     int8_t Datarate;
00212     uint16_t UplinkCounter;
00213     uint8_t Port;
00214     uint8_t *Buffer;
00215     uint8_t BufferSize;
00216 }LoRaMacUplinkStatus;
00217 volatile bool UplinkStatusUpdated = false;
00218 
00219 /*!
00220  * Strucure containing the Downlink status
00221  */
00222 struct sLoRaMacDownlinkStatus
00223 {
00224     int16_t Rssi;
00225     int8_t Snr;
00226     uint16_t DownlinkCounter;
00227     bool RxData;
00228     uint8_t Port;
00229     uint8_t *Buffer;
00230     uint8_t BufferSize;
00231 }LoRaMacDownlinkStatus;
00232 volatile bool DownlinkStatusUpdated = false;
00233 
00234 void SerialDisplayRefresh( void )
00235 {
00236     MibRequestConfirm_t mibReq;
00237 
00238     SerialDisplayInit( );
00239     SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00240 
00241 #if( OVER_THE_AIR_ACTIVATION == 0 )
00242     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00243     SerialDisplayUpdateDevAddr( DevAddr );
00244     SerialDisplayUpdateKey( 12, NwkSKey );
00245     SerialDisplayUpdateKey( 13, AppSKey );
00246 #endif
00247     SerialDisplayUpdateEui( 5, DevEui );
00248     SerialDisplayUpdateEui( 6, AppEui );
00249     SerialDisplayUpdateKey( 7, AppKey );
00250 
00251     mibReq.Type = MIB_NETWORK_JOINED;
00252     LoRaMacMibGetRequestConfirm( &mibReq );
00253     SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00254 
00255     SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00256 #if defined( USE_BAND_868 )
00257     SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00258 #else
00259     SerialDisplayUpdateDutyCycle( false );
00260 #endif
00261     SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00262     
00263     SerialDisplayUpdateLedState( 3, AppLedStateOn );
00264 }
00265 
00266 void SerialRxProcess( void )
00267 {
00268     if( SerialDisplayReadable( ) == true )
00269     {
00270         switch( SerialDisplayGetChar( ) )
00271         {
00272             case 'R':
00273             case 'r':
00274                 // Refresh Serial screen
00275                 SerialDisplayRefresh( );
00276                 break;
00277             default:
00278                 break;
00279         }
00280     }
00281 }
00282 
00283 /*!
00284  * \brief   Prepares the payload of the frame
00285  */
00286 static void PrepareTxFrame( uint8_t port )
00287 {
00288     switch( port )
00289     {
00290     case 10:
00291         {  
00292             static uint32_t counter = ( uint32_t )480;
00293             AppData[0] = counter>>24 & 0xFF;
00294             AppData[1] = counter>>16 & 0xFF;
00295             AppData[2] = counter>>8 & 0xFF;
00296             AppData[3] = counter & 0xFF;
00297             
00298             counter ++;
00299         }
00300         break;
00301     case 15:
00302         {
00303             AppData[0] = AppLedStateOn;
00304             if( IsTxConfirmed == true )
00305             {
00306                 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
00307                 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
00308                 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
00309                 AppData[4] = LoRaMacDownlinkStatus.Rssi;
00310                 AppData[5] = LoRaMacDownlinkStatus.Snr;
00311             }
00312         }
00313         break;
00314     case 224:
00315         if( ComplianceTest.LinkCheck == true )
00316         {
00317             ComplianceTest.LinkCheck = false;
00318             AppDataSize = 3;
00319             AppData[0] = 5;
00320             AppData[1] = ComplianceTest.DemodMargin;
00321             AppData[2] = ComplianceTest.NbGateways;
00322             ComplianceTest.State = 1;
00323         }
00324         else
00325         {
00326             switch( ComplianceTest.State )
00327             {
00328             case 4:
00329                 ComplianceTest.State = 1;
00330                 break;
00331             case 1:
00332                 AppDataSize = 2;
00333                 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
00334                 AppData[1] = ComplianceTest.DownLinkCounter;
00335                 break;
00336             }
00337         }
00338         break;
00339     default:
00340         break;
00341     }
00342 }
00343 
00344 /*!
00345  * \brief   Prepares the payload of the frame
00346  *
00347  * \retval  [0: frame could be send, 1: error]
00348  */
00349 static bool SendFrame( void )
00350 {
00351     McpsReq_t mcpsReq;
00352     LoRaMacTxInfo_t txInfo;
00353 
00354     if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
00355     {
00356         // Send empty frame in order to flush MAC commands
00357         mcpsReq.Type = MCPS_UNCONFIRMED;
00358         mcpsReq.Req.Unconfirmed.fBuffer = NULL;
00359         mcpsReq.Req.Unconfirmed.fBufferSize = 0;
00360         mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00361 
00362         LoRaMacUplinkStatus.Acked = false;
00363         LoRaMacUplinkStatus.Port = 0;
00364         LoRaMacUplinkStatus.Buffer = NULL;
00365         LoRaMacUplinkStatus.BufferSize = 0;
00366         SerialDisplayUpdateFrameType( false );
00367     }
00368     else
00369     {
00370         LoRaMacUplinkStatus.Acked = false;
00371         LoRaMacUplinkStatus.Port = AppPort;
00372         LoRaMacUplinkStatus.Buffer = AppData;
00373         LoRaMacUplinkStatus.BufferSize = AppDataSize;
00374         SerialDisplayUpdateFrameType( IsTxConfirmed );
00375 
00376         if( IsTxConfirmed == false )
00377         {
00378             mcpsReq.Type = MCPS_UNCONFIRMED;
00379             mcpsReq.Req.Unconfirmed.fPort = AppPort;
00380             mcpsReq.Req.Unconfirmed.fBuffer = AppData;
00381             mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
00382             mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00383         }
00384         else
00385         {
00386             mcpsReq.Type = MCPS_CONFIRMED;
00387             mcpsReq.Req.Confirmed.fPort = AppPort;
00388             mcpsReq.Req.Confirmed.fBuffer = AppData;
00389             mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
00390             mcpsReq.Req.Confirmed.NbTrials = 8;
00391             mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00392         }
00393     }
00394 
00395     if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
00396     {
00397         return false;
00398     }
00399     return true;
00400 }
00401 
00402 /*!
00403  * \brief Function executed on TxNextPacket Timeout event
00404  */
00405 static void OnTxNextPacketTimerEvent( void )
00406 {
00407     MibRequestConfirm_t mibReq;
00408     LoRaMacStatus_t status;
00409 
00410     TimerStop( &TxNextPacketTimer );
00411 
00412     mibReq.Type = MIB_NETWORK_JOINED;
00413     status = LoRaMacMibGetRequestConfirm( &mibReq );
00414 
00415     if( status == LORAMAC_STATUS_OK )
00416     {
00417         if( mibReq.Param.IsNetworkJoined == true )
00418         {
00419             DeviceState = DEVICE_STATE_SEND;
00420             NextTx = true;
00421         }
00422         else
00423         {
00424             DeviceState = DEVICE_STATE_JOIN;
00425         }
00426     }
00427 }
00428 
00429 /*!
00430  * \brief Function executed on Led 1 Timeout event
00431  */
00432 static void OnLed1TimerEvent( void )
00433 {
00434     TimerStop( &Led1Timer );
00435     // Switch LED 1 OFF
00436     Led1State = false;
00437     Led1StateChanged = true;
00438 }
00439 
00440 /*!
00441  * \brief Function executed on Led 2 Timeout event
00442  */
00443 static void OnLed2TimerEvent( void )
00444 {
00445     TimerStop( &Led2Timer );
00446     // Switch LED 2 OFF
00447     Led2State = false;
00448     Led2StateChanged = true;
00449 }
00450 
00451 /*!
00452  * \brief   MCPS-Confirm event function
00453  *
00454  * \param   [IN] mcpsConfirm - Pointer to the confirm structure,
00455  *               containing confirm attributes.
00456  */
00457 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
00458 {
00459     if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00460     {
00461         switch( mcpsConfirm->McpsRequest )
00462         {
00463             case MCPS_UNCONFIRMED:
00464             {
00465                 // Check Datarate
00466                 // Check TxPower
00467                 break;
00468             }
00469             case MCPS_CONFIRMED:
00470             {
00471                 // Check Datarate
00472                 // Check TxPower
00473                 // Check AckReceived
00474                 // Check NbTrials
00475                 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
00476                 break;
00477             }
00478             case MCPS_PROPRIETARY:
00479             {
00480                 break;
00481             }
00482             default:
00483                 break;
00484         }
00485         LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
00486         LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
00487 
00488         // Switch LED 1 ON
00489         Led1State = true;
00490         Led1StateChanged = true;
00491         TimerStart( &Led1Timer );
00492 
00493         UplinkStatusUpdated = true;
00494     }
00495     NextTx = true;
00496 }
00497 
00498 /*!
00499  * \brief   MCPS-Indication event function
00500  *
00501  * \param   [IN] mcpsIndication - Pointer to the indication structure,
00502  *               containing indication attributes.
00503  */
00504 static void McpsIndication( McpsIndication_t *mcpsIndication )
00505 {
00506     if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
00507     {
00508         return;
00509     }
00510 
00511     switch( mcpsIndication->McpsIndication )
00512     {
00513         case MCPS_UNCONFIRMED:
00514         {
00515             break;
00516         }
00517         case MCPS_CONFIRMED:
00518         {
00519             break;
00520         }
00521         case MCPS_PROPRIETARY:
00522         {
00523             break;
00524         }
00525         case MCPS_MULTICAST:
00526         {
00527             break;
00528         }
00529         default:
00530             break;
00531     }
00532 
00533     // Check Multicast
00534     // Check Port
00535     // Check Datarate
00536     // Check FramePending
00537     // Check Buffer
00538     // Check BufferSize
00539     // Check Rssi
00540     // Check Snr
00541     // Check RxSlot
00542     LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
00543     if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
00544     {
00545         // Invert and divide by 4
00546         LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
00547         LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
00548     }
00549     else
00550     {
00551         // Divide by 4
00552         LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
00553     }
00554     LoRaMacDownlinkStatus.DownlinkCounter++;
00555     LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
00556     LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
00557     LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
00558     LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
00559     
00560     SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
00561     
00562     if( ComplianceTest.Running == true )
00563     {
00564         ComplianceTest.DownLinkCounter++;
00565     }
00566 
00567     if( mcpsIndication->RxData == true )
00568     {
00569         switch( mcpsIndication->Port )
00570         {
00571         case 1: // The application LED can be controlled on port 1 or 2
00572         case 2:
00573             if( mcpsIndication->BufferSize == 1 )
00574             {
00575                 AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
00576                 myled = 1;
00577                 Led3StateChanged = true;
00578             }
00579             break;
00580         case 224:
00581             if( ComplianceTest.Running == false )
00582             {
00583                 // Check compliance test enable command (i)
00584                 if( ( mcpsIndication->BufferSize == 4 ) &&
00585                     ( mcpsIndication->Buffer[0] == 0x01 ) &&
00586                     ( mcpsIndication->Buffer[1] == 0x01 ) &&
00587                     ( mcpsIndication->Buffer[2] == 0x01 ) &&
00588                     ( mcpsIndication->Buffer[3] == 0x01 ) )
00589                 {
00590                     IsTxConfirmed = false;
00591                     AppPort = 224;
00592                     AppDataSize = 2;
00593                     ComplianceTest.DownLinkCounter = 0;
00594                     ComplianceTest.LinkCheck = false;
00595                     ComplianceTest.DemodMargin = 0;
00596                     ComplianceTest.NbGateways = 0;
00597                     ComplianceTest.Running = true;
00598                     ComplianceTest.State = 1;
00599 
00600                     MibRequestConfirm_t mibReq;
00601                     mibReq.Type = MIB_ADR;
00602                     mibReq.Param.AdrEnable = true;
00603                     LoRaMacMibSetRequestConfirm( &mibReq );
00604 
00605 #if defined( USE_BAND_868 )
00606                     LoRaMacTestSetDutyCycleOn( false );
00607 #endif
00608                 }
00609             }
00610             else
00611             {
00612                 ComplianceTest.State = mcpsIndication->Buffer[0];
00613                 switch( ComplianceTest.State )
00614                 {
00615                 case 0: // Check compliance test disable command (ii)
00616                     IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00617                     AppPort = LORAWAN_APP_PORT;
00618                     AppDataSize = LORAWAN_APP_DATA_SIZE;
00619                     ComplianceTest.DownLinkCounter = 0;
00620                     ComplianceTest.Running = false;
00621 
00622                     MibRequestConfirm_t mibReq;
00623                     mibReq.Type = MIB_ADR;
00624                     mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00625                     LoRaMacMibSetRequestConfirm( &mibReq );
00626 #if defined( USE_BAND_868 )
00627                     LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00628 #endif
00629                     break;
00630                 case 1: // (iii, iv)
00631                     AppDataSize = 2;
00632                     break;
00633                 case 2: // Enable confirmed messages (v)
00634                     IsTxConfirmed = true;
00635                     ComplianceTest.State = 1;
00636                     break;
00637                 case 3:  // Disable confirmed messages (vi)
00638                     IsTxConfirmed = false;
00639                     ComplianceTest.State = 1;
00640                     break;
00641                 case 4: // (vii)
00642                     AppDataSize = mcpsIndication->BufferSize;
00643 
00644                     AppData[0] = 4;
00645                     for( uint8_t i = 1; i < AppDataSize; i++ )
00646                     {
00647                         AppData[i] = mcpsIndication->Buffer[i] + 1;
00648                     }
00649                     break;
00650                 case 5: // (viii)
00651                     {
00652                         MlmeReq_t mlmeReq;
00653                         mlmeReq.Type = MLME_LINK_CHECK;
00654                         LoRaMacMlmeRequest( &mlmeReq );
00655                     }
00656                     break;
00657                 case 6: // (ix)
00658                     {
00659                         MlmeReq_t mlmeReq;
00660 
00661                         // Disable TestMode and revert back to normal operation
00662                         IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00663                         AppPort = LORAWAN_APP_PORT;
00664                         AppDataSize = LORAWAN_APP_DATA_SIZE;
00665                         ComplianceTest.DownLinkCounter = 0;
00666                         ComplianceTest.Running = false;
00667 
00668                         MibRequestConfirm_t mibReq;
00669                         mibReq.Type = MIB_ADR;
00670                         mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00671                         LoRaMacMibSetRequestConfirm( &mibReq );
00672 #if defined( USE_BAND_868 )
00673                         LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00674 #endif
00675 
00676                         mlmeReq.Type = MLME_JOIN;
00677 
00678                         mlmeReq.Req.Join.DevEui = DevEui;
00679                         mlmeReq.Req.Join.AppEui = AppEui;
00680                         mlmeReq.Req.Join.AppKey = AppKey;
00681                         mlmeReq.Req.Join.NbTrials = 3;
00682 
00683                         LoRaMacMlmeRequest( &mlmeReq );
00684                         DeviceState = DEVICE_STATE_SLEEP;
00685                     }
00686                     break;
00687                 case 7: // (x)
00688                     {
00689                         if( mcpsIndication->BufferSize == 3 )
00690                         {
00691                             MlmeReq_t mlmeReq;
00692                             mlmeReq.Type = MLME_TXCW;
00693                             mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
00694                             LoRaMacMlmeRequest( &mlmeReq );
00695                         }
00696                         else if( mcpsIndication->BufferSize == 7 )
00697                         {
00698                             MlmeReq_t mlmeReq;
00699                             mlmeReq.Type = MLME_TXCW_1;
00700                             mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
00701                             mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100;
00702                             mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
00703                             LoRaMacMlmeRequest( &mlmeReq );
00704                         }
00705                         ComplianceTest.State = 1;
00706                     }
00707                     break;
00708                 default:
00709                     break;
00710                 }
00711             }
00712             break;
00713         default:
00714             break;
00715         }
00716     }
00717 
00718     // Switch LED 2 ON for each received downlink
00719     Led2State = true;
00720     Led2StateChanged = true;
00721     TimerStart( &Led2Timer );
00722     DownlinkStatusUpdated = true;
00723 }
00724 
00725 /*!
00726  * \brief   MLME-Confirm event function
00727  *
00728  * \param   [IN] mlmeConfirm - Pointer to the confirm structure,
00729  *               containing confirm attributes.
00730  */
00731 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
00732 {
00733     switch( mlmeConfirm->MlmeRequest )
00734     {
00735         case MLME_JOIN:
00736         {
00737             if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00738             {
00739                 // Status is OK, node has joined the network
00740                 IsNetworkJoinedStatusUpdate = true;
00741                 DeviceState = DEVICE_STATE_SEND;
00742             }
00743             else
00744             {
00745                 // Join was not successful. Try to join again
00746                 DeviceState = DEVICE_STATE_JOIN;
00747             }
00748             break;
00749         }
00750         case MLME_LINK_CHECK:
00751         {
00752             if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00753             {
00754                 // Check DemodMargin
00755                 // Check NbGateways
00756                 if( ComplianceTest.Running == true )
00757                 {
00758                     ComplianceTest.LinkCheck = true;
00759                     ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
00760                     ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
00761                 }
00762             }
00763             break;
00764         }
00765         default:
00766             break;
00767     }
00768     NextTx = true;
00769     UplinkStatusUpdated = true;
00770 }
00771 
00772 /**
00773  * Main application entry point.
00774  */
00775 int main( void )
00776 {
00777     LoRaMacPrimitives_t LoRaMacPrimitives;
00778     LoRaMacCallback_t LoRaMacCallbacks;
00779     MibRequestConfirm_t mibReq;
00780 
00781     BoardInit( );
00782     SerialDisplayInit( );
00783 
00784     SerialDisplayUpdateEui( 5, DevEui );
00785     SerialDisplayUpdateEui( 6, AppEui );
00786     SerialDisplayUpdateKey( 7, AppKey );
00787 
00788 #if( OVER_THE_AIR_ACTIVATION == 0 )
00789     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00790     SerialDisplayUpdateDevAddr( DevAddr );
00791     SerialDisplayUpdateKey( 12, NwkSKey );
00792     SerialDisplayUpdateKey( 13, AppSKey );
00793 #endif
00794 
00795     DeviceState = DEVICE_STATE_INIT;
00796 
00797     while( 1 )
00798     {
00799         SerialRxProcess( );
00800         if( IsNetworkJoinedStatusUpdate == true )
00801         {
00802             IsNetworkJoinedStatusUpdate = false;
00803             mibReq.Type = MIB_NETWORK_JOINED;
00804             LoRaMacMibGetRequestConfirm( &mibReq );
00805             SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00806         }
00807         if( Led1StateChanged == true )
00808         {
00809             Led1StateChanged = false;
00810             SerialDisplayUpdateLedState( 1, Led1State );
00811         }
00812         if( Led2StateChanged == true )
00813         {
00814             Led2StateChanged = false;
00815             SerialDisplayUpdateLedState( 2, Led2State );
00816         }
00817         if( Led3StateChanged == true )
00818         {
00819             Led3StateChanged = false;
00820             SerialDisplayUpdateLedState( 3, AppLedStateOn );
00821         }
00822         if( UplinkStatusUpdated == true )
00823         {
00824             UplinkStatusUpdated = false;
00825             SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
00826         }
00827         if( DownlinkStatusUpdated == true )
00828         {
00829             DownlinkStatusUpdated = false;
00830             SerialDisplayUpdateLedState( 2, Led2State );
00831             SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
00832         }
00833         
00834         switch( DeviceState )
00835         {
00836             case DEVICE_STATE_INIT:
00837             {
00838                 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
00839                 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
00840                 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
00841                 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
00842                 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
00843 
00844                 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
00845 
00846                 TimerInit( &Led1Timer, OnLed1TimerEvent );
00847                 TimerSetValue( &Led1Timer, 25 );
00848 
00849                 TimerInit( &Led2Timer, OnLed2TimerEvent );
00850                 TimerSetValue( &Led2Timer, 25 );
00851 
00852                 mibReq.Type = MIB_ADR;
00853                 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00854                 LoRaMacMibSetRequestConfirm( &mibReq );
00855 
00856                 mibReq.Type = MIB_PUBLIC_NETWORK;
00857                 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
00858                 LoRaMacMibSetRequestConfirm( &mibReq );
00859 
00860 #if defined( USE_BAND_868 )
00861                 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00862                 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00863 
00864 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
00865                 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
00866                 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
00867                 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
00868                 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
00869                 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
00870                 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
00871                 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
00872 
00873                 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
00874                 mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00875                 LoRaMacMibSetRequestConfirm( &mibReq );
00876 
00877                 mibReq.Type = MIB_RX2_CHANNEL;
00878                 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00879                 LoRaMacMibSetRequestConfirm( &mibReq );
00880 #endif
00881 
00882 #endif
00883                 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00884                 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00885                 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00886 
00887                 LoRaMacDownlinkStatus.DownlinkCounter = 0;
00888 
00889                 DeviceState = DEVICE_STATE_JOIN;
00890                 break;
00891             }
00892             case DEVICE_STATE_JOIN:
00893             {
00894 #if( OVER_THE_AIR_ACTIVATION != 0 )
00895                 MlmeReq_t mlmeReq;
00896 
00897                 mlmeReq.Type = MLME_JOIN;
00898 
00899                 mlmeReq.Req.Join.DevEui = DevEui;
00900                 mlmeReq.Req.Join.AppEui = AppEui;
00901                 mlmeReq.Req.Join.AppKey = AppKey;
00902 
00903                 if( NextTx == true )
00904                 {
00905                     LoRaMacMlmeRequest( &mlmeReq );
00906                 }
00907                 DeviceState = DEVICE_STATE_SLEEP;
00908 #else
00909                 mibReq.Type = MIB_NET_ID;
00910                 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
00911                 LoRaMacMibSetRequestConfirm( &mibReq );
00912 
00913                 mibReq.Type = MIB_DEV_ADDR;
00914                 mibReq.Param.DevAddr = DevAddr;
00915                 LoRaMacMibSetRequestConfirm( &mibReq );
00916 
00917                 mibReq.Type = MIB_NWK_SKEY;
00918                 mibReq.Param.NwkSKey = NwkSKey;
00919                 LoRaMacMibSetRequestConfirm( &mibReq );
00920 
00921                 mibReq.Type = MIB_APP_SKEY;
00922                 mibReq.Param.AppSKey = AppSKey;
00923                 LoRaMacMibSetRequestConfirm( &mibReq );
00924 
00925                 mibReq.Type = MIB_NETWORK_JOINED;
00926                 mibReq.Param.IsNetworkJoined = true;
00927                 LoRaMacMibSetRequestConfirm( &mibReq );
00928 
00929                 DeviceState = DEVICE_STATE_SEND;
00930 #endif
00931                 IsNetworkJoinedStatusUpdate = true;
00932                 break;
00933             }
00934             case DEVICE_STATE_SEND:
00935             {
00936                 if( NextTx == true )
00937                 {
00938                     SerialDisplayUpdateUplinkAcked( false );
00939                     SerialDisplayUpdateDonwlinkRxData( false );
00940                     PrepareTxFrame( AppPort );
00941 
00942                     NextTx = SendFrame( );
00943                 }
00944                 if( ComplianceTest.Running == true )
00945                 {
00946                     // Schedule next packet transmission
00947                     TxDutyCycleTime = 5000; // 5000 ms
00948                 }
00949                 else
00950                 {
00951                     // Schedule next packet transmission
00952                     TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
00953                 }
00954                 DeviceState = DEVICE_STATE_CYCLE;
00955                 break;
00956             }
00957             case DEVICE_STATE_CYCLE:
00958             {
00959                 DeviceState = DEVICE_STATE_SLEEP;
00960 
00961                 // Schedule next packet transmission
00962                 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
00963                 TimerStart( &TxNextPacketTimer );
00964                 break;
00965             }
00966             case DEVICE_STATE_SLEEP:
00967             {
00968                 // Wake up through events
00969                 break;
00970             }
00971             default:
00972             {
00973                 DeviceState = DEVICE_STATE_INIT;
00974                 break;
00975             }
00976         }
00977     }
00978 }