guiguitant théo / greenhouse1

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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