first draft

Dependencies:   mbed LoRaWAN-lib SX1272Liby

Fork of LoRaWAN-demo-72 by Semtech

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