guiguitant théo / lorawan-master

Dependencies:   mbed

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