Espotel / Mbed 2 deprecated LoRaWAN_ELMO_TxRx_Template

Dependencies:   SX1272lib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RadioHandler.cpp Source File

RadioHandler.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2013 Semtech
00008 Description: LoRaMac classA device implementation
00009 License: Revised BSD License, see LICENSE.TXT file include in the project
00010 Maintainer: Miguel Luis and Gregory Cristian
00011 */
00012 
00013 /*! \file classA/LoRaMote/main.c */
00014 
00015 #include <string.h>
00016 #include <math.h>
00017 #include "mbed.h"
00018 
00019 #include "utilities.h"
00020 #include "LoRaMac.h"
00021 #include "Comissioning.h"
00022 #include "InterruptIn.h"
00023 #include "RadioHandler.h"
00024 
00025 DigitalOut Led2(LED2);
00026 
00027 /*!
00028  * Join requests trials duty cycle.
00029  */
00030 #define OVER_THE_AIR_ACTIVATION_DUTYCYCLE           10000000  // 10 [s] value in us
00031 
00032 /*!
00033  * Defines the application data transmission duty cycle. 5s, value in [us].
00034  */
00035 #define APP_TX_DUTYCYCLE                            10000000
00036 
00037 /*!
00038  * Defines a random delay for application data transmission duty cycle. 1s,
00039  * value in [us].
00040  */
00041 #define APP_TX_DUTYCYCLE_RND                        1000000
00042 
00043 /*!
00044  * LoRaWAN confirmed messages
00045  */
00046 #define LORAWAN_CONFIRMED_MSG_ON                    false
00047 
00048 /*!
00049  * LoRaWAN Adaptive Data Rate
00050  *
00051  * \remark Please note that when ADR is enabled the end-device should be static
00052  */
00053 #define LORAWAN_ADR_ON                              1
00054 
00055 #if defined( USE_BAND_868 )
00056 
00057 #include "LoRaMacTest.h"
00058 
00059 /*!
00060  * LoRaWAN ETSI duty cycle control enable/disable
00061  *
00062  * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
00063  */
00064 #define LORAWAN_DUTYCYCLE_ON                        false
00065 
00066 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP          0
00067 
00068 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 
00069 
00070 #define LC4                { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00071 #define LC5                { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00072 #define LC6                { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00073 #define LC7                { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00074 #define LC8                { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00075 #define LC9                { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
00076 
00077 #endif
00078 
00079 #endif
00080 
00081 /*!
00082  * LoRaWAN application port
00083  */
00084 #define LORAWAN_APP_PORT                            2
00085 
00086 /*!
00087  * User application data buffer size
00088  */
00089 #if defined( USE_BAND_868 )
00090 
00091 #define LORAWAN_APP_DATA_SIZE                       16
00092 
00093 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00094 
00095 #define LORAWAN_APP_DATA_SIZE                       11
00096 
00097 #endif
00098 
00099 #if( OVER_THE_AIR_ACTIVATION != 0 )
00100 
00101 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
00102 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
00103 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
00104 
00105 #else
00106 
00107 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
00108 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
00109 
00110 /*!
00111  * Device address
00112  */
00113 static uint32_t DevAddr;
00114 
00115 #endif
00116 
00117 /*!
00118  * Application port
00119  */
00120 static uint8_t AppPort = LORAWAN_APP_PORT;
00121 
00122 /*!
00123  * User application data size
00124  */
00125 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
00126 
00127 /*!
00128  * User application data buffer size
00129  */
00130 #define LORAWAN_APP_DATA_MAX_SIZE                           64
00131 
00132 /*!
00133  * User application data
00134  */
00135 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
00136 
00137 /*!
00138  * User application data buffer
00139  */
00140 static uint8_t AppDataBuffer[LORAWAN_APP_DATA_MAX_SIZE];
00141 
00142 /*!
00143  * Indicates if the node is sending confirmed or unconfirmed messages
00144  */
00145 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00146 
00147 /*!
00148  * Defines the application data transmission duty cycle
00149  */
00150 static uint32_t TxDutyCycleTime;
00151 
00152 /*!
00153  * Timer to handle the application data transmission duty cycle
00154  */
00155 static Timeout TxNextPacketTimer;
00156 
00157 /*!
00158  * Timer to handle the state of LED2
00159  */
00160 static Timeout Led2Timer;
00161 
00162 /*!
00163  * Indicates if a new packet can be sent
00164  */
00165 static bool NextTx = true;
00166 
00167 /*!
00168  * Packet send request
00169  */
00170 static bool PacketTxReq = false;
00171 
00172 /*!
00173  * Periodic packets enabled
00174  */
00175 static bool PeriodicPackets = false;
00176 /*!
00177  * Device states
00178  */
00179 static enum eDevicState
00180 {
00181     DEVICE_STATE_INIT,
00182     DEVICE_STATE_JOIN,
00183     DEVICE_STATE_SEND,
00184     DEVICE_STATE_CYCLE,
00185     DEVICE_STATE_SLEEP
00186 }DeviceState;
00187 
00188 /*!
00189  * LoRaWAN compliance tests support data
00190  */
00191 struct ComplianceTest_s
00192 {
00193     bool Running;
00194     uint8_t State;
00195     bool IsTxConfirmed;
00196     uint8_t AppPort;
00197     uint8_t AppDataSize;
00198     uint8_t *AppDataBuffer;
00199     uint16_t DownLinkCounter;
00200     bool LinkCheck;
00201     uint8_t DemodMargin;
00202     uint8_t NbGateways;
00203 }ComplianceTest;
00204 
00205 /*!
00206  * \brief   Prepares the payload of the frame
00207  */
00208 static void PrepareTxFrame( uint8_t port )
00209 {
00210     uint16_t i;
00211 
00212     switch( port )
00213     {
00214     case 2:
00215         {
00216 #if defined( USE_BAND_868 )
00217 
00218             for (i=0; i<LORAWAN_APP_DATA_SIZE; i++)
00219             {
00220                 AppData[i] = AppDataBuffer[i];
00221             }
00222 
00223 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00224 
00225             for (i=0; i<LORAWAN_APP_DATA_SIZE; i++)
00226             {
00227                 AppData[i] = AppDataBuffer[i];
00228             }
00229 
00230 #endif
00231         }
00232         break;
00233     case 224:
00234         if( ComplianceTest.LinkCheck == true )
00235         {
00236             ComplianceTest.LinkCheck = false;
00237             AppDataSize = 3;
00238             AppData[0] = 5;
00239             AppData[1] = ComplianceTest.DemodMargin;
00240             AppData[2] = ComplianceTest.NbGateways;
00241             ComplianceTest.State = 1;
00242         }
00243         else
00244         {
00245             switch( ComplianceTest.State )
00246             {
00247             case 4:
00248                 ComplianceTest.State = 1;
00249                 break;
00250             case 1:
00251                 AppDataSize = 2;
00252                 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
00253                 AppData[1] = ComplianceTest.DownLinkCounter;
00254                 break;
00255             }
00256         }
00257         break;
00258     default:
00259         break;
00260     }
00261 }
00262 
00263 /*!
00264  * \brief   Prepares the payload of the frame
00265  *
00266  * \retval  [0: frame could be send, 1: error]
00267  */
00268 static bool SendFrame( void )
00269 {
00270     McpsReq_t  mcpsReq;
00271     LoRaMacTxInfo_t  txInfo;
00272     
00273     if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK  )
00274     {
00275         // Send empty frame in order to flush MAC commands
00276         mcpsReq.Type  = MCPS_UNCONFIRMED ;
00277         mcpsReq.Req.Unconfirmed .fBuffer  = NULL;
00278         mcpsReq.Req.Unconfirmed .fBufferSize  = 0;
00279         mcpsReq.Req.Unconfirmed .Datarate  = DR_0;
00280     }
00281     else
00282     {
00283         if( IsTxConfirmed == false )
00284         {
00285             mcpsReq.Type  = MCPS_UNCONFIRMED ;
00286             mcpsReq.Req.Unconfirmed .fPort  = AppPort;
00287             mcpsReq.Req.Unconfirmed .fBuffer  = AppData;
00288             mcpsReq.Req.Unconfirmed .fBufferSize  = AppDataSize;
00289             mcpsReq.Req.Unconfirmed .Datarate  = DR_0;
00290         }
00291         else
00292         {
00293             mcpsReq.Type  = MCPS_CONFIRMED ;
00294             mcpsReq.Req.Confirmed .fPort  = AppPort;
00295             mcpsReq.Req.Confirmed .fBuffer  = AppData;
00296             mcpsReq.Req.Confirmed .fBufferSize  = AppDataSize;
00297             mcpsReq.Req.Confirmed .NbTrials  = 8;
00298             mcpsReq.Req.Confirmed .Datarate  = DR_0;
00299         }
00300     }
00301 
00302     if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK  )
00303     {
00304         return false;
00305     }
00306     return true;
00307 }
00308 
00309 /*!
00310  * \brief Function executed on TxNextPacket Timeout event
00311  */
00312 static void OnTxNextPacketTimerEvent( void )
00313 {
00314     MibRequestConfirm_t  mibReq;
00315     LoRaMacStatus_t  status;
00316 
00317     TxNextPacketTimer.detach();
00318 
00319     mibReq.Type  = MIB_NETWORK_JOINED ;
00320     status = LoRaMacMibGetRequestConfirm( &mibReq );
00321 
00322     if( status == LORAMAC_STATUS_OK  )
00323     {
00324         if( mibReq.Param .IsNetworkJoined  == true )
00325         {
00326             DeviceState = DEVICE_STATE_SEND;
00327             NextTx = true;
00328         }
00329         else
00330         {
00331             DeviceState = DEVICE_STATE_JOIN;
00332         }
00333     }
00334 }
00335 
00336 /*!
00337  * \brief Function executed on Led 2 Timeout event
00338  */
00339 static void OnLed2TimerEvent( void )
00340 {
00341     Led2Timer.detach();
00342     // Switch LED 2 OFF
00343     Led2 = 1;
00344 }
00345 
00346 /*!
00347  * \brief   MCPS-Confirm event function
00348  *
00349  * \param   [IN] McpsConfirm - Pointer to the confirm structure,
00350  *               containing confirm attributes.
00351  */
00352 static void McpsConfirm( McpsConfirm_t  *McpsConfirm )
00353 {
00354     printf("MCPS Confirm\r\n");
00355     if( McpsConfirm->Status  == LORAMAC_EVENT_INFO_STATUS_OK  )
00356     {
00357         switch( McpsConfirm->McpsRequest  )
00358         {
00359             case MCPS_UNCONFIRMED :
00360             {
00361                 // Check Datarate
00362                 // Check TxPower
00363                 break;
00364             }
00365             case MCPS_CONFIRMED :
00366             {
00367                 // Check Datarate
00368                 // Check TxPower
00369                 // Check AckReceived
00370                 // Check NbTrials
00371                 break;
00372             }
00373             case MCPS_PROPRIETARY :
00374             {
00375                 break;
00376             }
00377             default:
00378                 break;
00379         }
00380     }
00381     NextTx = true;
00382 }
00383 
00384 /*!
00385  * \brief   MCPS-Indication event function
00386  *
00387  * \param   [IN] McpsIndication - Pointer to the indication structure,
00388  *               containing indication attributes.
00389  */
00390 static void McpsIndication( McpsIndication_t  *McpsIndication )
00391 {
00392     printf("MCPS Indication\r\n");
00393     if( McpsIndication->Status  != LORAMAC_EVENT_INFO_STATUS_OK  )
00394     {
00395         return;
00396     }
00397 
00398     switch( McpsIndication->McpsIndication  )
00399     {
00400         case MCPS_UNCONFIRMED :
00401         {
00402             break;
00403         }
00404         case MCPS_CONFIRMED :
00405         {
00406             break;
00407         }
00408         case MCPS_PROPRIETARY :
00409         {
00410             break;
00411         }
00412         case MCPS_MULTICAST :
00413         {
00414             break;
00415         }
00416         default:
00417             break;
00418     }
00419 
00420     // Check Multicast
00421     // Check Port
00422     // Check Datarate
00423     // Check FramePending
00424     // Check Buffer
00425     // Check BufferSize
00426     // Check Rssi
00427     // Check Snr
00428     // Check RxSlot
00429 
00430     if( ComplianceTest.Running == true )
00431     {
00432         ComplianceTest.DownLinkCounter++;
00433     }
00434 
00435     if( McpsIndication->RxData  == true )
00436     {
00437         switch( McpsIndication->Port  )
00438         {
00439         case 1:
00440         case 2:
00441             printf("Receive buffer : %s\r\n", (char*)McpsIndication->Buffer );
00442             break;
00443         case 224:
00444             if( ComplianceTest.Running == false )
00445             {
00446                 // Check compliance test enable command (i)
00447                 if( ( McpsIndication->BufferSize  == 4 ) && 
00448                     ( McpsIndication->Buffer [0] == 0x01 ) &&
00449                     ( McpsIndication->Buffer [1] == 0x01 ) &&
00450                     ( McpsIndication->Buffer [2] == 0x01 ) &&
00451                     ( McpsIndication->Buffer [3] == 0x01 ) )
00452                 {
00453                     IsTxConfirmed = false;
00454                     AppPort = 224;
00455                     AppDataSize = 2;
00456                     ComplianceTest.DownLinkCounter = 0;
00457                     ComplianceTest.LinkCheck = false;
00458                     ComplianceTest.DemodMargin = 0;
00459                     ComplianceTest.NbGateways = 0;
00460                     ComplianceTest.Running = true;
00461                     ComplianceTest.State = 1;
00462                     
00463                     MibRequestConfirm_t  mibReq;
00464                     mibReq.Type  = MIB_ADR ;
00465                     mibReq.Param .AdrEnable  = true;
00466                     LoRaMacMibSetRequestConfirm( &mibReq );
00467 
00468 #if defined( USE_BAND_868 )
00469                     LoRaMacTestSetDutyCycleOn( false );
00470 #endif
00471                 }
00472             }
00473             else
00474             {
00475                 ComplianceTest.State = McpsIndication->Buffer [0];
00476                 switch( ComplianceTest.State )
00477                 {
00478                 case 0: // Check compliance test disable command (ii)
00479                     IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00480                     AppPort = LORAWAN_APP_PORT;
00481                     AppDataSize = LORAWAN_APP_DATA_SIZE;
00482                     ComplianceTest.DownLinkCounter = 0;
00483                     ComplianceTest.Running = false;
00484                     
00485                     MibRequestConfirm_t  mibReq;
00486                     mibReq.Type  = MIB_ADR ;
00487                     mibReq.Param .AdrEnable  = LORAWAN_ADR_ON;
00488                     LoRaMacMibSetRequestConfirm( &mibReq );
00489 #if defined( USE_BAND_868 )
00490                     LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00491 #endif
00492                     break;
00493                 case 1: // (iii, iv)
00494                     AppDataSize = 2;
00495                     break;
00496                 case 2: // Enable confirmed messages (v)
00497                     IsTxConfirmed = true;
00498                     ComplianceTest.State = 1;
00499                     break;
00500                 case 3:  // Disable confirmed messages (vi)
00501                     IsTxConfirmed = false;
00502                     ComplianceTest.State = 1;
00503                     break;
00504                 case 4: // (vii)
00505                     AppDataSize = McpsIndication->BufferSize ;
00506 
00507                     AppData[0] = 4;
00508                     for( uint8_t i = 1; i < AppDataSize; i++ )
00509                     {
00510                         AppData[i] = McpsIndication->Buffer [i] + 1;
00511                     }
00512                     break;
00513                 case 5: // (viii)
00514                     {
00515                         MlmeReq_t mlmeReq;
00516                         mlmeReq.Type = MLME_LINK_CHECK ;
00517                         LoRaMacMlmeRequest( &mlmeReq );
00518                     }
00519                     break;
00520                 default:
00521                     break;
00522                 }
00523             }
00524             break;
00525         default:
00526             break;
00527         }
00528     }
00529 
00530     // Switch LED 2 ON for each received downlink
00531     Led2 = 0;
00532     Led2Timer.attach_us(OnLed2TimerEvent, 25000);
00533 }
00534 
00535 /*!
00536  * \brief   MLME-Confirm event function
00537  *
00538  * \param   [IN] MlmeConfirm - Pointer to the confirm structure,
00539  *               containing confirm attributes.
00540  */
00541 static void MlmeConfirm( MlmeConfirm_t  *MlmeConfirm )
00542 {
00543     printf("MLME Confirm\r\n");
00544     if( MlmeConfirm->Status  == LORAMAC_EVENT_INFO_STATUS_OK  )
00545     {
00546         switch( MlmeConfirm->MlmeRequest  )
00547         {
00548             case MLME_JOIN :
00549             {
00550                 // Status is OK, node has joined the network
00551                 printf("\r\nElmo has joined the network\r\n\r\n");
00552                 break;
00553             }
00554             case MLME_LINK_CHECK :
00555             {
00556                 // Check DemodMargin
00557                 // Check NbGateways
00558                 if( ComplianceTest.Running == true )
00559                 {
00560                     ComplianceTest.LinkCheck = true;
00561                     ComplianceTest.DemodMargin = MlmeConfirm->DemodMargin ;
00562                     ComplianceTest.NbGateways = MlmeConfirm->NbGateways ;
00563                 }
00564                 break;
00565             }
00566             default:
00567                 break;
00568         }
00569     }
00570     NextTx = true;
00571 }
00572 
00573 /**
00574  * Radio state machine initialization
00575  */
00576 void RadioInit( void )
00577 {
00578     DeviceState = DEVICE_STATE_INIT;
00579 }
00580 
00581 /**
00582  * Request packet transmission
00583  */
00584 void RequestPacketTx( char *DataString, bool PeriodicRequested  )
00585 {
00586     PacketTxReq = true;
00587     PeriodicPackets = PeriodicRequested;
00588 
00589     // Copy string to buffer, truncated to max packet size if necessary with trailing zero
00590     // Packet size is always max allowed. Padded with zeroes
00591     strncpy((char*)AppDataBuffer, DataString, LORAWAN_APP_DATA_SIZE-1);
00592     AppDataBuffer[LORAWAN_APP_DATA_SIZE-1] = 0;
00593 }
00594 /**
00595  * Radio state machine.
00596  */
00597 void RadioHandler( void )
00598 {
00599     static LoRaMacPrimitives_t  LoRaMacPrimitives;
00600     static LoRaMacCallback_t LoRaMacCallbacks;
00601     static MibRequestConfirm_t  mibReq;
00602 
00603     switch( DeviceState )
00604     {
00605         case DEVICE_STATE_INIT:
00606         {
00607             LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
00608             LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
00609             LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
00610             //LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
00611             LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
00612 
00613             mibReq.Type  = MIB_ADR ;
00614             mibReq.Param .AdrEnable  = LORAWAN_ADR_ON;
00615             LoRaMacMibSetRequestConfirm( &mibReq );
00616 
00617             mibReq.Type  = MIB_PUBLIC_NETWORK ;
00618             mibReq.Param .EnablePublicNetwork  = LORAWAN_PUBLIC_NETWORK;
00619             LoRaMacMibSetRequestConfirm( &mibReq );
00620 
00621 #if defined( USE_BAND_868 )
00622             LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00623 
00624 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 
00625             LoRaMacChannelAdd( 3, ( ChannelParams_t  )LC4 );
00626             LoRaMacChannelAdd( 4, ( ChannelParams_t  )LC5 );
00627             LoRaMacChannelAdd( 5, ( ChannelParams_t  )LC6 );
00628             LoRaMacChannelAdd( 6, ( ChannelParams_t  )LC7 );
00629             LoRaMacChannelAdd( 7, ( ChannelParams_t  )LC8 );
00630             LoRaMacChannelAdd( 8, ( ChannelParams_t  )LC9 );
00631 #endif
00632 
00633 #endif
00634             DeviceState = DEVICE_STATE_JOIN;
00635             break;
00636         }
00637         case DEVICE_STATE_JOIN:
00638         {
00639 #if( OVER_THE_AIR_ACTIVATION != 0 )
00640             MlmeReq_t mlmeReq;
00641 
00642             #warning BoardGetUniqueId not needed in test software - commented out
00643             // Initialize LoRaMac device unique ID
00644             // BoardGetUniqueId( DevEui );
00645 
00646             mlmeReq.Type = MLME_JOIN ;
00647 
00648             mlmeReq.Req.Join.DevEui = DevEui;
00649             mlmeReq.Req.Join.AppEui = AppEui;
00650             mlmeReq.Req.Join.AppKey = AppKey;
00651 
00652             if( NextTx == true )
00653             {
00654                 LoRaMacMlmeRequest( &mlmeReq );
00655             }
00656 
00657             // Schedule next packet transmission
00658             TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE;
00659             DeviceState = DEVICE_STATE_CYCLE;
00660 
00661 #else
00662             // Random seed initialization
00663             srand1( BoardGetRandomSeed( ) );
00664 
00665             // Choose a random device address
00666             DevAddr = randr( 0, 0x01FFFFFF );
00667 
00668             mibReq.Type  = MIB_NET_ID ;
00669             mibReq.Param .NetID  = LORAWAN_NETWORK_ID;
00670             LoRaMacMibSetRequestConfirm( &mibReq );
00671 
00672             mibReq.Type  = MIB_DEV_ADDR ;
00673             mibReq.Param .DevAddr  = DevAddr;
00674             LoRaMacMibSetRequestConfirm( &mibReq );
00675 
00676             mibReq.Type  = MIB_NWK_SKEY ;
00677             mibReq.Param .NwkSKey  = NwkSKey;
00678             LoRaMacMibSetRequestConfirm( &mibReq );
00679 
00680             mibReq.Type  = MIB_APP_SKEY ;
00681             mibReq.Param .AppSKey  = AppSKey;
00682             LoRaMacMibSetRequestConfirm( &mibReq );
00683 
00684             mibReq.Type  = MIB_NETWORK_JOINED ;
00685             mibReq.Param .IsNetworkJoined  = true;
00686             LoRaMacMibSetRequestConfirm( &mibReq );
00687 
00688             DeviceState = DEVICE_STATE_SEND;
00689 #endif
00690             break;
00691         }
00692         case DEVICE_STATE_SEND:
00693         {
00694             if( NextTx == true )
00695             {
00696                 printf("Packet sent\r\n");
00697                 PrepareTxFrame( AppPort );
00698 
00699                 NextTx = SendFrame( );
00700                 if(PacketTxReq)
00701                 {
00702                     printf("Unscheduled packet transmission\r\n");
00703                     PacketTxReq = false;
00704                 }
00705             }
00706             if( ComplianceTest.Running == true )
00707             {
00708                 // Schedule next packet transmission as soon as possible
00709                 TxDutyCycleTime = 300000; // 300 ms
00710             }
00711             else
00712             {
00713                 // Schedule next packet periodic transmission
00714                 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
00715             }
00716             DeviceState = DEVICE_STATE_CYCLE;
00717             break;
00718         }
00719         case DEVICE_STATE_CYCLE:
00720         {
00721             DeviceState = DEVICE_STATE_SLEEP;
00722 
00723             // Schedule next packet transmission
00724             if(PeriodicPackets)
00725             {
00726                 TxNextPacketTimer.attach_us(OnTxNextPacketTimerEvent, TxDutyCycleTime);
00727             }
00728             break;
00729         }
00730         case DEVICE_STATE_SLEEP:
00731         {
00732             // Wake up through events
00733             if(PacketTxReq)
00734             {
00735                 DeviceState = DEVICE_STATE_SEND;
00736             }
00737             #warning TimerLowPowerHandler disabled
00738             //TimerLowPowerHandler( );
00739             break;
00740         }
00741         default:
00742         {
00743             DeviceState = DEVICE_STATE_INIT;
00744             break;
00745         }
00746     }
00747 }