Application example using LoRaWAN-lib MAC layer implementation

Dependencies:   mbed LoRaWAN-lib SX1272Lib

LoRaWAN-demo is a ClassA device example project using LoRaWAN-lib and SX1272Lib libraries.

This demo application sends a frame every 4 to 6 seconds (randomly) and displays its current status using a serial port as display(VT100).

The serial port settings are as shown in below image. To access the serial port settings please click on "Setup" menu and then "Serial port..."

/media/uploads/mluis/serial_port_settings.png

The terminal window should be setup as shown in below image. To access the terminal window settings please click on "Setup" menu and then "Terminal..."

/media/uploads/mluis/terminal_window_settings.png

The image below shows the VT100 application status.

Application main screen

The application gives the possibility to either activate the device using

  • Over The Air Activation (OTAA)
  • Personalization activation (PA)

The activation mode can be adjusted in Comissioning.h by changing the following parameter:

/*!
 * When set to 1 the application uses the Over-the-Air activation procedure
 * When set to 0 the application uses the Personalization activation procedure
 */
#define OVER_THE_AIR_ACTIVATION                     1


The application gives the possibility to select which kind of network we are connecting to.

  • Public Network (true)
  • Private Network (false)

The netork type can be changed as follows:

/*!
 * Indicates if the end-device is to be connected to a private or public network
 */
#define LORAWAN_PUBLIC_NETWORK                      true


OTAA
When OTAA is selected the user must porvide a device EUI, an application EUI and an application key.
These can be adjusted by changing the following parameters:

/*!
 * Mote device IEEE EUI (big endian)
 */
#define LORAWAN_DEVICE_EUI                          { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }

/*!
 * Application IEEE EUI (big endian)
 */
#define LORAWAN_APPLICATION_EUI                     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

/*!
 * AES encryption/decryption cipher application key
 */
#define LORAWAN_APPLICATION_KEY                     { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }


PA
When PA is selected the user must porvide a network ID, a device address, a network session key and an application session key.
These can be adjusted by changing the following parameters:

/*!
 * Current network ID
 */
#define LORAWAN_NETWORK_ID                          ( uint32_t )0

/*!
 * Device address on the network (big endian)
 */
#define LORAWAN_DEVICE_ADDRESS                      ( uint32_t )0x12345678

/*!
 * AES encryption/decryption cipher network session key
 */
#define LORAWAN_NWKSKEY                             { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }

/*!
 * AES encryption/decryption cipher application session key
 */
#define LORAWAN_APPSKEY                             { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }


On top of main.c the user has the possibility to tweak some application settings such as:

  • Join requests transmission frequency
  • Frames transmission frequency
  • Application default datarate
  • Confirmed or Unconfirmed frames transmission
  • ADR (Adaptive Datarate) ON/OFF
  • Application port to be used by the transmitted frames

The join requests transmission frequency can be adjusted by changing the follwoing parameter:

/*!
 * Join requests trials duty cycle.
 */
#define OVER_THE_AIR_ACTIVATION_DUTYCYCLE           10000000  // 10 [s] value in us


The frame transmission frequency can be adjusted by changing the follwoing parameters:

/*!
 * Defines the application data transmission duty cycle. 5s, value in [us].
 */
#define APP_TX_DUTYCYCLE                            5000000

/*!
 * Defines a random delay for application data transmission duty cycle. 1s,
 * value in [us].
 */
#define APP_TX_DUTYCYCLE_RND                        1000000


The frame transmission scheduling is then executed as follows:

        if( ScheduleNextTx == true )
        {
            ScheduleNextTx = false;
            // Schedule next packet transmission
            TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
            TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
            TimerStart( &TxNextPacketTimer );
        }


The application default datarate can be adjusted by changing the following parameter:

Quote:

When ADR is off this setting is the fixed datarate that will be used by the application.
When ADR is on this setting is the initial datarate used by the application.

/*!
 * Default mote datarate
 */
#define LORAWAN_DEFAULT_DATARATE                    DR_0


The transmitted frame contents will depend on LORAWAN_CONFIRMED_MSG_ON value.

/*!
 * LoRaWAN confirmed messages
 */
#define LORAWAN_CONFIRMED_MSG_ON                    true
  • If LORAWAN_CONFIRMED_MSG_ON equals false then the application payload is one byte corresponding to the AppLed state.
  • If LORAWAN_CONFIRMED_MSG_ON equals true then the application payload is six bytes corresponding to the AppLed state, Downlink counter (unsigned 16 bits), received RSSI (signed 16 bits) and received SNR (signed 8 bits).

/*!
 * \brief   Prepares the payload of the frame
 */
static void PrepareTxFrame( uint8_t port )
{

    switch( port )
    {
    case 15:
        {
            AppData[0] = AppLedStateOn;
            if( IsTxConfirmed == true )
            {
                AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
                AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
                AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
                AppData[4] = LoRaMacDownlinkStatus.Rssi;
                AppData[5] = LoRaMacDownlinkStatus.Snr;
            }
        }
        break;
    case 224:
...
}


The ADR enabling/disabling can be adjusted by changing the following parameter:

/*!
 * LoRaWAN Adaptive Data Rate
 *
 * \remark Please note that when ADR is enabled the end-device should be static
 */
#define LORAWAN_ADR_ON                              1


The application port can be adjusted by changing the following parameter:

/*!
 * LoRaWAN application port
 */
#define LORAWAN_APP_PORT                            15
Committer:
mluis
Date:
Thu Jan 07 15:11:08 2016 +0000
Revision:
0:45496a70a8a5
Child:
2:2eeaeae2c725
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:45496a70a8a5 1 /*
mluis 0:45496a70a8a5 2 / _____) _ | |
mluis 0:45496a70a8a5 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:45496a70a8a5 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:45496a70a8a5 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:45496a70a8a5 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 0:45496a70a8a5 7 (C)2015 Semtech
mluis 0:45496a70a8a5 8
mluis 0:45496a70a8a5 9 Description: LoRaMac classA device implementation
mluis 0:45496a70a8a5 10
mluis 0:45496a70a8a5 11 License: Revised BSD License, see LICENSE.TXT file include in the project
mluis 0:45496a70a8a5 12
mluis 0:45496a70a8a5 13 Maintainer: Miguel Luis and Gregory Cristian
mluis 0:45496a70a8a5 14 */
mluis 0:45496a70a8a5 15 #include "mbed.h"
mluis 0:45496a70a8a5 16 #include "board.h"
mluis 0:45496a70a8a5 17 #include "radio.h"
mluis 0:45496a70a8a5 18
mluis 0:45496a70a8a5 19 #include "LoRaMac.h"
mluis 0:45496a70a8a5 20 #include "Comissioning.h"
mluis 0:45496a70a8a5 21 #include "SerialDisplay.h"
mluis 0:45496a70a8a5 22
mluis 0:45496a70a8a5 23 /*!
mluis 0:45496a70a8a5 24 * Join requests trials duty cycle.
mluis 0:45496a70a8a5 25 */
mluis 0:45496a70a8a5 26 #define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us
mluis 0:45496a70a8a5 27
mluis 0:45496a70a8a5 28 /*!
mluis 0:45496a70a8a5 29 * Defines the application data transmission duty cycle. 5s, value in [us].
mluis 0:45496a70a8a5 30 */
mluis 0:45496a70a8a5 31 #define APP_TX_DUTYCYCLE 5000000
mluis 0:45496a70a8a5 32
mluis 0:45496a70a8a5 33 /*!
mluis 0:45496a70a8a5 34 * Defines a random delay for application data transmission duty cycle. 1s,
mluis 0:45496a70a8a5 35 * value in [us].
mluis 0:45496a70a8a5 36 */
mluis 0:45496a70a8a5 37 #define APP_TX_DUTYCYCLE_RND 1000000
mluis 0:45496a70a8a5 38
mluis 0:45496a70a8a5 39 /*!
mluis 0:45496a70a8a5 40 * Default mote datarate
mluis 0:45496a70a8a5 41 */
mluis 0:45496a70a8a5 42 #define LORAWAN_DEFAULT_DATARATE DR_0
mluis 0:45496a70a8a5 43
mluis 0:45496a70a8a5 44 /*!
mluis 0:45496a70a8a5 45 * LoRaWAN confirmed messages
mluis 0:45496a70a8a5 46 */
mluis 0:45496a70a8a5 47 #define LORAWAN_CONFIRMED_MSG_ON true
mluis 0:45496a70a8a5 48
mluis 0:45496a70a8a5 49 /*!
mluis 0:45496a70a8a5 50 * LoRaWAN Adaptive Data Rate
mluis 0:45496a70a8a5 51 *
mluis 0:45496a70a8a5 52 * \remark Please note that when ADR is enabled the end-device should be static
mluis 0:45496a70a8a5 53 */
mluis 0:45496a70a8a5 54 #define LORAWAN_ADR_ON 1
mluis 0:45496a70a8a5 55
mluis 0:45496a70a8a5 56 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 57
mluis 0:45496a70a8a5 58 #include "LoRaMacTest.h"
mluis 0:45496a70a8a5 59
mluis 0:45496a70a8a5 60 /*!
mluis 0:45496a70a8a5 61 * LoRaWAN ETSI duty cycle control enable/disable
mluis 0:45496a70a8a5 62 *
mluis 0:45496a70a8a5 63 * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
mluis 0:45496a70a8a5 64 */
mluis 0:45496a70a8a5 65 #define LORAWAN_DUTYCYCLE_ON true
mluis 0:45496a70a8a5 66
mluis 0:45496a70a8a5 67 #endif
mluis 0:45496a70a8a5 68
mluis 0:45496a70a8a5 69 /*!
mluis 0:45496a70a8a5 70 * LoRaWAN application port
mluis 0:45496a70a8a5 71 */
mluis 0:45496a70a8a5 72 #define LORAWAN_APP_PORT 15
mluis 0:45496a70a8a5 73
mluis 0:45496a70a8a5 74 /*!
mluis 0:45496a70a8a5 75 * User application data buffer size
mluis 0:45496a70a8a5 76 */
mluis 0:45496a70a8a5 77 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 0:45496a70a8a5 78 #define LORAWAN_APP_DATA_SIZE 6
mluis 0:45496a70a8a5 79
mluis 0:45496a70a8a5 80 #else
mluis 0:45496a70a8a5 81 #define LORAWAN_APP_DATA_SIZE 1
mluis 0:45496a70a8a5 82
mluis 0:45496a70a8a5 83 #endif
mluis 0:45496a70a8a5 84
mluis 0:45496a70a8a5 85 #if( OVER_THE_AIR_ACTIVATION != 0 )
mluis 0:45496a70a8a5 86
mluis 0:45496a70a8a5 87 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
mluis 0:45496a70a8a5 88 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
mluis 0:45496a70a8a5 89 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
mluis 0:45496a70a8a5 90
mluis 0:45496a70a8a5 91 #else
mluis 0:45496a70a8a5 92
mluis 0:45496a70a8a5 93 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
mluis 0:45496a70a8a5 94 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
mluis 0:45496a70a8a5 95
mluis 0:45496a70a8a5 96 /*!
mluis 0:45496a70a8a5 97 * Device address
mluis 0:45496a70a8a5 98 */
mluis 0:45496a70a8a5 99 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
mluis 0:45496a70a8a5 100
mluis 0:45496a70a8a5 101 #endif
mluis 0:45496a70a8a5 102
mluis 0:45496a70a8a5 103 /*!
mluis 0:45496a70a8a5 104 * Application port
mluis 0:45496a70a8a5 105 */
mluis 0:45496a70a8a5 106 static uint8_t AppPort = LORAWAN_APP_PORT;
mluis 0:45496a70a8a5 107
mluis 0:45496a70a8a5 108 /*!
mluis 0:45496a70a8a5 109 * User application data size
mluis 0:45496a70a8a5 110 */
mluis 0:45496a70a8a5 111 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
mluis 0:45496a70a8a5 112
mluis 0:45496a70a8a5 113 /*!
mluis 0:45496a70a8a5 114 * User application data buffer size
mluis 0:45496a70a8a5 115 */
mluis 0:45496a70a8a5 116 #define LORAWAN_APP_DATA_MAX_SIZE 64
mluis 0:45496a70a8a5 117
mluis 0:45496a70a8a5 118 /*!
mluis 0:45496a70a8a5 119 * User application data
mluis 0:45496a70a8a5 120 */
mluis 0:45496a70a8a5 121 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
mluis 0:45496a70a8a5 122
mluis 0:45496a70a8a5 123 /*!
mluis 0:45496a70a8a5 124 * Indicates if the node is sending confirmed or unconfirmed messages
mluis 0:45496a70a8a5 125 */
mluis 0:45496a70a8a5 126 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
mluis 0:45496a70a8a5 127
mluis 0:45496a70a8a5 128 /*!
mluis 0:45496a70a8a5 129 * Defines the application data transmission duty cycle
mluis 0:45496a70a8a5 130 */
mluis 0:45496a70a8a5 131 static uint32_t TxDutyCycleTime;
mluis 0:45496a70a8a5 132
mluis 0:45496a70a8a5 133 /*!
mluis 0:45496a70a8a5 134 * Timer to handle the application data transmission duty cycle
mluis 0:45496a70a8a5 135 */
mluis 0:45496a70a8a5 136 static TimerEvent_t TxNextPacketTimer;
mluis 0:45496a70a8a5 137
mluis 0:45496a70a8a5 138 /*!
mluis 0:45496a70a8a5 139 * Specifies the state of the application LED
mluis 0:45496a70a8a5 140 */
mluis 0:45496a70a8a5 141 static bool AppLedStateOn = false;
mluis 0:45496a70a8a5 142 volatile bool Led3StateChanged = false;
mluis 0:45496a70a8a5 143 /*!
mluis 0:45496a70a8a5 144 * Timer to handle the state of LED1
mluis 0:45496a70a8a5 145 */
mluis 0:45496a70a8a5 146 static TimerEvent_t Led1Timer;
mluis 0:45496a70a8a5 147 volatile bool Led1State = false;
mluis 0:45496a70a8a5 148 volatile bool Led1StateChanged = false;
mluis 0:45496a70a8a5 149 /*!
mluis 0:45496a70a8a5 150 * Timer to handle the state of LED2
mluis 0:45496a70a8a5 151 */
mluis 0:45496a70a8a5 152 static TimerEvent_t Led2Timer;
mluis 0:45496a70a8a5 153 volatile bool Led2State = false;
mluis 0:45496a70a8a5 154 volatile bool Led2StateChanged = false;
mluis 0:45496a70a8a5 155
mluis 0:45496a70a8a5 156 /*!
mluis 0:45496a70a8a5 157 * Indicates if a new packet can be sent
mluis 0:45496a70a8a5 158 */
mluis 0:45496a70a8a5 159 static bool NextTx = true;
mluis 0:45496a70a8a5 160
mluis 0:45496a70a8a5 161 /*!
mluis 0:45496a70a8a5 162 * Device states
mluis 0:45496a70a8a5 163 */
mluis 0:45496a70a8a5 164 static enum eDevicState
mluis 0:45496a70a8a5 165 {
mluis 0:45496a70a8a5 166 DEVICE_STATE_INIT,
mluis 0:45496a70a8a5 167 DEVICE_STATE_JOIN,
mluis 0:45496a70a8a5 168 DEVICE_STATE_SEND,
mluis 0:45496a70a8a5 169 DEVICE_STATE_CYCLE,
mluis 0:45496a70a8a5 170 DEVICE_STATE_SLEEP
mluis 0:45496a70a8a5 171 }DeviceState;
mluis 0:45496a70a8a5 172
mluis 0:45496a70a8a5 173 /*!
mluis 0:45496a70a8a5 174 * LoRaWAN compliance tests support data
mluis 0:45496a70a8a5 175 */
mluis 0:45496a70a8a5 176 struct ComplianceTest_s
mluis 0:45496a70a8a5 177 {
mluis 0:45496a70a8a5 178 bool Running;
mluis 0:45496a70a8a5 179 uint8_t State;
mluis 0:45496a70a8a5 180 bool IsTxConfirmed;
mluis 0:45496a70a8a5 181 uint8_t AppPort;
mluis 0:45496a70a8a5 182 uint8_t AppDataSize;
mluis 0:45496a70a8a5 183 uint8_t *AppDataBuffer;
mluis 0:45496a70a8a5 184 uint16_t DownLinkCounter;
mluis 0:45496a70a8a5 185 bool LinkCheck;
mluis 0:45496a70a8a5 186 uint8_t DemodMargin;
mluis 0:45496a70a8a5 187 uint8_t NbGateways;
mluis 0:45496a70a8a5 188 }ComplianceTest;
mluis 0:45496a70a8a5 189
mluis 0:45496a70a8a5 190 /*
mluis 0:45496a70a8a5 191 * SerialDisplay managment variables
mluis 0:45496a70a8a5 192 */
mluis 0:45496a70a8a5 193
mluis 0:45496a70a8a5 194 /*!
mluis 0:45496a70a8a5 195 * Indicates if the MAC layer network join status has changed.
mluis 0:45496a70a8a5 196 */
mluis 0:45496a70a8a5 197 static bool IsNetworkJoinedStatusUpdate = false;
mluis 0:45496a70a8a5 198
mluis 0:45496a70a8a5 199 /*!
mluis 0:45496a70a8a5 200 * Strucure containing the Uplink status
mluis 0:45496a70a8a5 201 */
mluis 0:45496a70a8a5 202 struct sLoRaMacUplinkStatus
mluis 0:45496a70a8a5 203 {
mluis 0:45496a70a8a5 204 uint8_t Acked;
mluis 0:45496a70a8a5 205 int8_t Datarate;
mluis 0:45496a70a8a5 206 uint16_t UplinkCounter;
mluis 0:45496a70a8a5 207 uint8_t Port;
mluis 0:45496a70a8a5 208 uint8_t *Buffer;
mluis 0:45496a70a8a5 209 uint8_t BufferSize;
mluis 0:45496a70a8a5 210 }LoRaMacUplinkStatus;
mluis 0:45496a70a8a5 211 volatile bool UplinkStatusUpdated = false;
mluis 0:45496a70a8a5 212
mluis 0:45496a70a8a5 213 /*!
mluis 0:45496a70a8a5 214 * Strucure containing the Downlink status
mluis 0:45496a70a8a5 215 */
mluis 0:45496a70a8a5 216 struct sLoRaMacDownlinkStatus
mluis 0:45496a70a8a5 217 {
mluis 0:45496a70a8a5 218 int16_t Rssi;
mluis 0:45496a70a8a5 219 int8_t Snr;
mluis 0:45496a70a8a5 220 uint16_t DownlinkCounter;
mluis 0:45496a70a8a5 221 bool RxData;
mluis 0:45496a70a8a5 222 uint8_t Port;
mluis 0:45496a70a8a5 223 uint8_t *Buffer;
mluis 0:45496a70a8a5 224 uint8_t BufferSize;
mluis 0:45496a70a8a5 225 }LoRaMacDownlinkStatus;
mluis 0:45496a70a8a5 226 volatile bool DownlinkStatusUpdated = false;
mluis 0:45496a70a8a5 227
mluis 0:45496a70a8a5 228 void SerialDisplayRefresh( void )
mluis 0:45496a70a8a5 229 {
mluis 0:45496a70a8a5 230 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 231
mluis 0:45496a70a8a5 232 SerialDisplayInit( );
mluis 0:45496a70a8a5 233 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:45496a70a8a5 234
mluis 0:45496a70a8a5 235 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 0:45496a70a8a5 236 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 0:45496a70a8a5 237 SerialDisplayUpdateDevAddr( DevAddr );
mluis 0:45496a70a8a5 238 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 0:45496a70a8a5 239 SerialDisplayUpdateKey( 13, AppSKey );
mluis 0:45496a70a8a5 240 #else
mluis 0:45496a70a8a5 241 SerialDisplayUpdateEui( 5, DevEui );
mluis 0:45496a70a8a5 242 SerialDisplayUpdateEui( 6, AppEui );
mluis 0:45496a70a8a5 243 SerialDisplayUpdateKey( 7, AppKey );
mluis 0:45496a70a8a5 244 #endif
mluis 0:45496a70a8a5 245
mluis 0:45496a70a8a5 246 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 247 LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 248 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
mluis 0:45496a70a8a5 249
mluis 0:45496a70a8a5 250 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:45496a70a8a5 251 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 252 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 253 #else
mluis 0:45496a70a8a5 254 SerialDisplayUpdateDutyCycle( false );
mluis 0:45496a70a8a5 255 #endif
mluis 0:45496a70a8a5 256 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
mluis 0:45496a70a8a5 257
mluis 0:45496a70a8a5 258 SerialDisplayUpdateLedState( 3, AppLedStateOn );
mluis 0:45496a70a8a5 259 }
mluis 0:45496a70a8a5 260
mluis 0:45496a70a8a5 261 void SerialRxProcess( void )
mluis 0:45496a70a8a5 262 {
mluis 0:45496a70a8a5 263 if( SerialDisplayReadable( ) == true )
mluis 0:45496a70a8a5 264 {
mluis 0:45496a70a8a5 265 switch( SerialDisplayGetChar( ) )
mluis 0:45496a70a8a5 266 {
mluis 0:45496a70a8a5 267 case 'R':
mluis 0:45496a70a8a5 268 case 'r':
mluis 0:45496a70a8a5 269 // Refresh Serial screen
mluis 0:45496a70a8a5 270 SerialDisplayRefresh( );
mluis 0:45496a70a8a5 271 break;
mluis 0:45496a70a8a5 272 default:
mluis 0:45496a70a8a5 273 break;
mluis 0:45496a70a8a5 274 }
mluis 0:45496a70a8a5 275 }
mluis 0:45496a70a8a5 276 }
mluis 0:45496a70a8a5 277
mluis 0:45496a70a8a5 278 /*!
mluis 0:45496a70a8a5 279 * \brief Prepares the payload of the frame
mluis 0:45496a70a8a5 280 */
mluis 0:45496a70a8a5 281 static void PrepareTxFrame( uint8_t port )
mluis 0:45496a70a8a5 282 {
mluis 0:45496a70a8a5 283 switch( port )
mluis 0:45496a70a8a5 284 {
mluis 0:45496a70a8a5 285 case 15:
mluis 0:45496a70a8a5 286 {
mluis 0:45496a70a8a5 287 AppData[0] = AppLedStateOn;
mluis 0:45496a70a8a5 288 if( IsTxConfirmed == true )
mluis 0:45496a70a8a5 289 {
mluis 0:45496a70a8a5 290 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
mluis 0:45496a70a8a5 291 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
mluis 0:45496a70a8a5 292 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
mluis 0:45496a70a8a5 293 AppData[4] = LoRaMacDownlinkStatus.Rssi;
mluis 0:45496a70a8a5 294 AppData[5] = LoRaMacDownlinkStatus.Snr;
mluis 0:45496a70a8a5 295 }
mluis 0:45496a70a8a5 296 }
mluis 0:45496a70a8a5 297 break;
mluis 0:45496a70a8a5 298 case 224:
mluis 0:45496a70a8a5 299 if( ComplianceTest.LinkCheck == true )
mluis 0:45496a70a8a5 300 {
mluis 0:45496a70a8a5 301 ComplianceTest.LinkCheck = false;
mluis 0:45496a70a8a5 302 AppDataSize = 3;
mluis 0:45496a70a8a5 303 AppData[0] = 5;
mluis 0:45496a70a8a5 304 AppData[1] = ComplianceTest.DemodMargin;
mluis 0:45496a70a8a5 305 AppData[2] = ComplianceTest.NbGateways;
mluis 0:45496a70a8a5 306 ComplianceTest.State = 1;
mluis 0:45496a70a8a5 307 }
mluis 0:45496a70a8a5 308 else
mluis 0:45496a70a8a5 309 {
mluis 0:45496a70a8a5 310 switch( ComplianceTest.State )
mluis 0:45496a70a8a5 311 {
mluis 0:45496a70a8a5 312 case 4:
mluis 0:45496a70a8a5 313 ComplianceTest.State = 1;
mluis 0:45496a70a8a5 314 break;
mluis 0:45496a70a8a5 315 case 1:
mluis 0:45496a70a8a5 316 AppDataSize = 2;
mluis 0:45496a70a8a5 317 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
mluis 0:45496a70a8a5 318 AppData[1] = ComplianceTest.DownLinkCounter;
mluis 0:45496a70a8a5 319 break;
mluis 0:45496a70a8a5 320 }
mluis 0:45496a70a8a5 321 }
mluis 0:45496a70a8a5 322 break;
mluis 0:45496a70a8a5 323 default:
mluis 0:45496a70a8a5 324 break;
mluis 0:45496a70a8a5 325 }
mluis 0:45496a70a8a5 326 }
mluis 0:45496a70a8a5 327
mluis 0:45496a70a8a5 328 /*!
mluis 0:45496a70a8a5 329 * \brief Prepares the payload of the frame
mluis 0:45496a70a8a5 330 *
mluis 0:45496a70a8a5 331 * \retval [0: frame could be send, 1: error]
mluis 0:45496a70a8a5 332 */
mluis 0:45496a70a8a5 333 static bool SendFrame( void )
mluis 0:45496a70a8a5 334 {
mluis 0:45496a70a8a5 335 McpsReq_t mcpsReq;
mluis 0:45496a70a8a5 336 LoRaMacTxInfo_t txInfo;
mluis 0:45496a70a8a5 337
mluis 0:45496a70a8a5 338 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
mluis 0:45496a70a8a5 339 {
mluis 0:45496a70a8a5 340 // Send empty frame in order to flush MAC commands
mluis 0:45496a70a8a5 341 mcpsReq.Type = MCPS_UNCONFIRMED;
mluis 0:45496a70a8a5 342 mcpsReq.Req.Unconfirmed.fBuffer = NULL;
mluis 0:45496a70a8a5 343 mcpsReq.Req.Unconfirmed.fBufferSize = 0;
mluis 0:45496a70a8a5 344 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
mluis 0:45496a70a8a5 345
mluis 0:45496a70a8a5 346 LoRaMacUplinkStatus.Acked = false;
mluis 0:45496a70a8a5 347 LoRaMacUplinkStatus.Port = 0;
mluis 0:45496a70a8a5 348 LoRaMacUplinkStatus.Buffer = NULL;
mluis 0:45496a70a8a5 349 LoRaMacUplinkStatus.BufferSize = 0;
mluis 0:45496a70a8a5 350 SerialDisplayUpdateFrameType( false );
mluis 0:45496a70a8a5 351 }
mluis 0:45496a70a8a5 352 else
mluis 0:45496a70a8a5 353 {
mluis 0:45496a70a8a5 354 LoRaMacUplinkStatus.Acked = false;
mluis 0:45496a70a8a5 355 LoRaMacUplinkStatus.Port = AppPort;
mluis 0:45496a70a8a5 356 LoRaMacUplinkStatus.Buffer = AppData;
mluis 0:45496a70a8a5 357 LoRaMacUplinkStatus.BufferSize = AppDataSize;
mluis 0:45496a70a8a5 358 SerialDisplayUpdateFrameType( IsTxConfirmed );
mluis 0:45496a70a8a5 359
mluis 0:45496a70a8a5 360 if( IsTxConfirmed == false )
mluis 0:45496a70a8a5 361 {
mluis 0:45496a70a8a5 362 mcpsReq.Type = MCPS_UNCONFIRMED;
mluis 0:45496a70a8a5 363 mcpsReq.Req.Unconfirmed.fPort = AppPort;
mluis 0:45496a70a8a5 364 mcpsReq.Req.Unconfirmed.fBuffer = AppData;
mluis 0:45496a70a8a5 365 mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
mluis 0:45496a70a8a5 366 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
mluis 0:45496a70a8a5 367 }
mluis 0:45496a70a8a5 368 else
mluis 0:45496a70a8a5 369 {
mluis 0:45496a70a8a5 370 mcpsReq.Type = MCPS_CONFIRMED;
mluis 0:45496a70a8a5 371 mcpsReq.Req.Confirmed.fPort = AppPort;
mluis 0:45496a70a8a5 372 mcpsReq.Req.Confirmed.fBuffer = AppData;
mluis 0:45496a70a8a5 373 mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
mluis 0:45496a70a8a5 374 mcpsReq.Req.Confirmed.nbRetries = 8;
mluis 0:45496a70a8a5 375 mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
mluis 0:45496a70a8a5 376 }
mluis 0:45496a70a8a5 377 }
mluis 0:45496a70a8a5 378
mluis 0:45496a70a8a5 379 if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
mluis 0:45496a70a8a5 380 {
mluis 0:45496a70a8a5 381 return false;
mluis 0:45496a70a8a5 382 }
mluis 0:45496a70a8a5 383 return true;
mluis 0:45496a70a8a5 384 }
mluis 0:45496a70a8a5 385
mluis 0:45496a70a8a5 386 /*!
mluis 0:45496a70a8a5 387 * \brief Function executed on TxNextPacket Timeout event
mluis 0:45496a70a8a5 388 */
mluis 0:45496a70a8a5 389 static void OnTxNextPacketTimerEvent( void )
mluis 0:45496a70a8a5 390 {
mluis 0:45496a70a8a5 391 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 392 LoRaMacStatus_t status;
mluis 0:45496a70a8a5 393
mluis 0:45496a70a8a5 394 TimerStop( &TxNextPacketTimer );
mluis 0:45496a70a8a5 395
mluis 0:45496a70a8a5 396 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 397 status = LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 398
mluis 0:45496a70a8a5 399 if( status == LORAMAC_STATUS_OK )
mluis 0:45496a70a8a5 400 {
mluis 0:45496a70a8a5 401 if( mibReq.Param.IsNetworkJoined == true )
mluis 0:45496a70a8a5 402 {
mluis 0:45496a70a8a5 403 DeviceState = DEVICE_STATE_SEND;
mluis 0:45496a70a8a5 404 NextTx = true;
mluis 0:45496a70a8a5 405 }
mluis 0:45496a70a8a5 406 else
mluis 0:45496a70a8a5 407 {
mluis 0:45496a70a8a5 408 DeviceState = DEVICE_STATE_JOIN;
mluis 0:45496a70a8a5 409 }
mluis 0:45496a70a8a5 410 }
mluis 0:45496a70a8a5 411 }
mluis 0:45496a70a8a5 412
mluis 0:45496a70a8a5 413 /*!
mluis 0:45496a70a8a5 414 * \brief Function executed on Led 1 Timeout event
mluis 0:45496a70a8a5 415 */
mluis 0:45496a70a8a5 416 static void OnLed1TimerEvent( void )
mluis 0:45496a70a8a5 417 {
mluis 0:45496a70a8a5 418 TimerStop( &Led1Timer );
mluis 0:45496a70a8a5 419 // Switch LED 1 OFF
mluis 0:45496a70a8a5 420 Led1State = false;
mluis 0:45496a70a8a5 421 Led1StateChanged = true;
mluis 0:45496a70a8a5 422 }
mluis 0:45496a70a8a5 423
mluis 0:45496a70a8a5 424 /*!
mluis 0:45496a70a8a5 425 * \brief Function executed on Led 2 Timeout event
mluis 0:45496a70a8a5 426 */
mluis 0:45496a70a8a5 427 static void OnLed2TimerEvent( void )
mluis 0:45496a70a8a5 428 {
mluis 0:45496a70a8a5 429 TimerStop( &Led2Timer );
mluis 0:45496a70a8a5 430 // Switch LED 2 OFF
mluis 0:45496a70a8a5 431 Led2State = false;
mluis 0:45496a70a8a5 432 Led2StateChanged = true;
mluis 0:45496a70a8a5 433 }
mluis 0:45496a70a8a5 434
mluis 0:45496a70a8a5 435 /*!
mluis 0:45496a70a8a5 436 * \brief MCPS-Confirm event function
mluis 0:45496a70a8a5 437 *
mluis 0:45496a70a8a5 438 * \param [IN] McpsConfirm - Pointer to the confirm structure,
mluis 0:45496a70a8a5 439 * containing confirm attributes.
mluis 0:45496a70a8a5 440 */
mluis 0:45496a70a8a5 441 static void McpsConfirm( McpsConfirm_t *McpsConfirm )
mluis 0:45496a70a8a5 442 {
mluis 0:45496a70a8a5 443 if( McpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
mluis 0:45496a70a8a5 444 {
mluis 0:45496a70a8a5 445 switch( McpsConfirm->McpsRequest )
mluis 0:45496a70a8a5 446 {
mluis 0:45496a70a8a5 447 case MCPS_UNCONFIRMED:
mluis 0:45496a70a8a5 448 {
mluis 0:45496a70a8a5 449 // Check Datarate
mluis 0:45496a70a8a5 450 // Check TxPower
mluis 0:45496a70a8a5 451 break;
mluis 0:45496a70a8a5 452 }
mluis 0:45496a70a8a5 453 case MCPS_CONFIRMED:
mluis 0:45496a70a8a5 454 {
mluis 0:45496a70a8a5 455 // Check Datarate
mluis 0:45496a70a8a5 456 // Check TxPower
mluis 0:45496a70a8a5 457 // Check AckReceived
mluis 0:45496a70a8a5 458 // Check NbRetries
mluis 0:45496a70a8a5 459 LoRaMacUplinkStatus.Acked = McpsConfirm->AckReceived;
mluis 0:45496a70a8a5 460 break;
mluis 0:45496a70a8a5 461 }
mluis 0:45496a70a8a5 462 case MCPS_PROPRIETARY:
mluis 0:45496a70a8a5 463 {
mluis 0:45496a70a8a5 464 break;
mluis 0:45496a70a8a5 465 }
mluis 0:45496a70a8a5 466 default:
mluis 0:45496a70a8a5 467 break;
mluis 0:45496a70a8a5 468 }
mluis 0:45496a70a8a5 469 LoRaMacUplinkStatus.Datarate = McpsConfirm->Datarate;
mluis 0:45496a70a8a5 470 LoRaMacUplinkStatus.UplinkCounter = McpsConfirm->UpLinkCounter;
mluis 0:45496a70a8a5 471
mluis 0:45496a70a8a5 472 UplinkStatusUpdated = true;
mluis 0:45496a70a8a5 473 }
mluis 0:45496a70a8a5 474 NextTx = true;
mluis 0:45496a70a8a5 475 }
mluis 0:45496a70a8a5 476
mluis 0:45496a70a8a5 477 /*!
mluis 0:45496a70a8a5 478 * \brief MCPS-Indication event function
mluis 0:45496a70a8a5 479 *
mluis 0:45496a70a8a5 480 * \param [IN] McpsIndication - Pointer to the indication structure,
mluis 0:45496a70a8a5 481 * containing indication attributes.
mluis 0:45496a70a8a5 482 */
mluis 0:45496a70a8a5 483 static void McpsIndication( McpsIndication_t *McpsIndication )
mluis 0:45496a70a8a5 484 {
mluis 0:45496a70a8a5 485 if( McpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
mluis 0:45496a70a8a5 486 {
mluis 0:45496a70a8a5 487 return;
mluis 0:45496a70a8a5 488 }
mluis 0:45496a70a8a5 489
mluis 0:45496a70a8a5 490 switch( McpsIndication->McpsIndication )
mluis 0:45496a70a8a5 491 {
mluis 0:45496a70a8a5 492 case MCPS_UNCONFIRMED:
mluis 0:45496a70a8a5 493 {
mluis 0:45496a70a8a5 494 break;
mluis 0:45496a70a8a5 495 }
mluis 0:45496a70a8a5 496 case MCPS_CONFIRMED:
mluis 0:45496a70a8a5 497 {
mluis 0:45496a70a8a5 498 break;
mluis 0:45496a70a8a5 499 }
mluis 0:45496a70a8a5 500 case MCPS_PROPRIETARY:
mluis 0:45496a70a8a5 501 {
mluis 0:45496a70a8a5 502 break;
mluis 0:45496a70a8a5 503 }
mluis 0:45496a70a8a5 504 case MCPS_MULTICAST:
mluis 0:45496a70a8a5 505 {
mluis 0:45496a70a8a5 506 break;
mluis 0:45496a70a8a5 507 }
mluis 0:45496a70a8a5 508 default:
mluis 0:45496a70a8a5 509 break;
mluis 0:45496a70a8a5 510 }
mluis 0:45496a70a8a5 511
mluis 0:45496a70a8a5 512 // Check Multicast
mluis 0:45496a70a8a5 513 // Check Port
mluis 0:45496a70a8a5 514 // Check Datarate
mluis 0:45496a70a8a5 515 // Check FramePending
mluis 0:45496a70a8a5 516 // Check Buffer
mluis 0:45496a70a8a5 517 // Check BufferSize
mluis 0:45496a70a8a5 518 // Check Rssi
mluis 0:45496a70a8a5 519 // Check Snr
mluis 0:45496a70a8a5 520 // Check RxSlot
mluis 0:45496a70a8a5 521 LoRaMacDownlinkStatus.Rssi = McpsIndication->Rssi;
mluis 0:45496a70a8a5 522 if( McpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
mluis 0:45496a70a8a5 523 {
mluis 0:45496a70a8a5 524 // Invert and divide by 4
mluis 0:45496a70a8a5 525 LoRaMacDownlinkStatus.Snr = ( ( ~McpsIndication->Snr + 1 ) & 0xFF ) >> 2;
mluis 0:45496a70a8a5 526 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
mluis 0:45496a70a8a5 527 }
mluis 0:45496a70a8a5 528 else
mluis 0:45496a70a8a5 529 {
mluis 0:45496a70a8a5 530 // Divide by 4
mluis 0:45496a70a8a5 531 LoRaMacDownlinkStatus.Snr = ( McpsIndication->Snr & 0xFF ) >> 2;
mluis 0:45496a70a8a5 532 }
mluis 0:45496a70a8a5 533 LoRaMacDownlinkStatus.DownlinkCounter++;
mluis 0:45496a70a8a5 534 LoRaMacDownlinkStatus.RxData = McpsIndication->RxData;
mluis 0:45496a70a8a5 535 LoRaMacDownlinkStatus.Port = McpsIndication->Port;
mluis 0:45496a70a8a5 536 LoRaMacDownlinkStatus.Buffer = McpsIndication->Buffer;
mluis 0:45496a70a8a5 537 LoRaMacDownlinkStatus.BufferSize = McpsIndication->BufferSize;
mluis 0:45496a70a8a5 538
mluis 0:45496a70a8a5 539 if( ComplianceTest.Running == true )
mluis 0:45496a70a8a5 540 {
mluis 0:45496a70a8a5 541 ComplianceTest.DownLinkCounter++;
mluis 0:45496a70a8a5 542 }
mluis 0:45496a70a8a5 543
mluis 0:45496a70a8a5 544 if( McpsIndication->RxData == true )
mluis 0:45496a70a8a5 545 {
mluis 0:45496a70a8a5 546 switch( McpsIndication->Port )
mluis 0:45496a70a8a5 547 {
mluis 0:45496a70a8a5 548 case 1: // The application LED can be controlled on port 1 or 2
mluis 0:45496a70a8a5 549 case 2:
mluis 0:45496a70a8a5 550 if( McpsIndication->BufferSize == 1 )
mluis 0:45496a70a8a5 551 {
mluis 0:45496a70a8a5 552 AppLedStateOn = McpsIndication->Buffer[0] & 0x01;
mluis 0:45496a70a8a5 553 Led3StateChanged = true;
mluis 0:45496a70a8a5 554 }
mluis 0:45496a70a8a5 555 break;
mluis 0:45496a70a8a5 556 case 224:
mluis 0:45496a70a8a5 557 if( ComplianceTest.Running == false )
mluis 0:45496a70a8a5 558 {
mluis 0:45496a70a8a5 559 // Check compliance test enable command (i)
mluis 0:45496a70a8a5 560 if( ( McpsIndication->BufferSize == 4 ) &&
mluis 0:45496a70a8a5 561 ( McpsIndication->Buffer[0] == 0x01 ) &&
mluis 0:45496a70a8a5 562 ( McpsIndication->Buffer[1] == 0x01 ) &&
mluis 0:45496a70a8a5 563 ( McpsIndication->Buffer[2] == 0x01 ) &&
mluis 0:45496a70a8a5 564 ( McpsIndication->Buffer[3] == 0x01 ) )
mluis 0:45496a70a8a5 565 {
mluis 0:45496a70a8a5 566 IsTxConfirmed = false;
mluis 0:45496a70a8a5 567 AppPort = 224;
mluis 0:45496a70a8a5 568 AppDataSize = 2;
mluis 0:45496a70a8a5 569 ComplianceTest.DownLinkCounter = 0;
mluis 0:45496a70a8a5 570 ComplianceTest.LinkCheck = false;
mluis 0:45496a70a8a5 571 ComplianceTest.DemodMargin = 0;
mluis 0:45496a70a8a5 572 ComplianceTest.NbGateways = 0;
mluis 0:45496a70a8a5 573 ComplianceTest.Running = true;
mluis 0:45496a70a8a5 574 ComplianceTest.State = 1;
mluis 0:45496a70a8a5 575
mluis 0:45496a70a8a5 576 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 577 mibReq.Type = MIB_ADR;
mluis 0:45496a70a8a5 578 mibReq.Param.AdrEnable = true;
mluis 0:45496a70a8a5 579 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 580
mluis 0:45496a70a8a5 581 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 582 LoRaMacTestSetDutyCycleOn( false );
mluis 0:45496a70a8a5 583 #endif
mluis 0:45496a70a8a5 584 }
mluis 0:45496a70a8a5 585 }
mluis 0:45496a70a8a5 586 else
mluis 0:45496a70a8a5 587 {
mluis 0:45496a70a8a5 588 ComplianceTest.State = McpsIndication->Buffer[0];
mluis 0:45496a70a8a5 589 switch( ComplianceTest.State )
mluis 0:45496a70a8a5 590 {
mluis 0:45496a70a8a5 591 case 0: // Check compliance test disable command (ii)
mluis 0:45496a70a8a5 592 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
mluis 0:45496a70a8a5 593 AppPort = LORAWAN_APP_PORT;
mluis 0:45496a70a8a5 594 AppDataSize = LORAWAN_APP_DATA_SIZE;
mluis 0:45496a70a8a5 595 ComplianceTest.DownLinkCounter = 0;
mluis 0:45496a70a8a5 596 ComplianceTest.Running = false;
mluis 0:45496a70a8a5 597
mluis 0:45496a70a8a5 598 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 599 mibReq.Type = MIB_ADR;
mluis 0:45496a70a8a5 600 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
mluis 0:45496a70a8a5 601 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 602 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 603 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 604 #endif
mluis 0:45496a70a8a5 605 break;
mluis 0:45496a70a8a5 606 case 1: // (iii, iv)
mluis 0:45496a70a8a5 607 AppDataSize = 2;
mluis 0:45496a70a8a5 608 break;
mluis 0:45496a70a8a5 609 case 2: // Enable confirmed messages (v)
mluis 0:45496a70a8a5 610 IsTxConfirmed = true;
mluis 0:45496a70a8a5 611 ComplianceTest.State = 1;
mluis 0:45496a70a8a5 612 break;
mluis 0:45496a70a8a5 613 case 3: // Disable confirmed messages (vi)
mluis 0:45496a70a8a5 614 IsTxConfirmed = false;
mluis 0:45496a70a8a5 615 ComplianceTest.State = 1;
mluis 0:45496a70a8a5 616 break;
mluis 0:45496a70a8a5 617 case 4: // (vii)
mluis 0:45496a70a8a5 618 AppDataSize = McpsIndication->BufferSize;
mluis 0:45496a70a8a5 619
mluis 0:45496a70a8a5 620 AppData[0] = 4;
mluis 0:45496a70a8a5 621 for( uint8_t i = 1; i < AppDataSize; i++ )
mluis 0:45496a70a8a5 622 {
mluis 0:45496a70a8a5 623 AppData[i] = McpsIndication->Buffer[i] + 1;
mluis 0:45496a70a8a5 624 }
mluis 0:45496a70a8a5 625 break;
mluis 0:45496a70a8a5 626 case 5: // (viii)
mluis 0:45496a70a8a5 627 {
mluis 0:45496a70a8a5 628 MlmeReq_t mlmeReq;
mluis 0:45496a70a8a5 629 mlmeReq.Type = MLME_LINK_CHECK;
mluis 0:45496a70a8a5 630 LoRaMacMlmeRequest( &mlmeReq );
mluis 0:45496a70a8a5 631 }
mluis 0:45496a70a8a5 632 break;
mluis 0:45496a70a8a5 633 default:
mluis 0:45496a70a8a5 634 break;
mluis 0:45496a70a8a5 635 }
mluis 0:45496a70a8a5 636 }
mluis 0:45496a70a8a5 637 break;
mluis 0:45496a70a8a5 638 default:
mluis 0:45496a70a8a5 639 break;
mluis 0:45496a70a8a5 640 }
mluis 0:45496a70a8a5 641 }
mluis 0:45496a70a8a5 642
mluis 0:45496a70a8a5 643 // Switch LED 2 ON for each received downlink
mluis 0:45496a70a8a5 644 Led2State = true;
mluis 0:45496a70a8a5 645 Led2StateChanged = true;
mluis 0:45496a70a8a5 646 TimerStart( &Led2Timer );
mluis 0:45496a70a8a5 647 DownlinkStatusUpdated = true;
mluis 0:45496a70a8a5 648 }
mluis 0:45496a70a8a5 649
mluis 0:45496a70a8a5 650 /*!
mluis 0:45496a70a8a5 651 * \brief MLME-Confirm event function
mluis 0:45496a70a8a5 652 *
mluis 0:45496a70a8a5 653 * \param [IN] MlmeConfirm - Pointer to the confirm structure,
mluis 0:45496a70a8a5 654 * containing confirm attributes.
mluis 0:45496a70a8a5 655 */
mluis 0:45496a70a8a5 656 static void MlmeConfirm( MlmeConfirm_t *MlmeConfirm )
mluis 0:45496a70a8a5 657 {
mluis 0:45496a70a8a5 658 if( MlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
mluis 0:45496a70a8a5 659 {
mluis 0:45496a70a8a5 660 switch( MlmeConfirm->MlmeRequest )
mluis 0:45496a70a8a5 661 {
mluis 0:45496a70a8a5 662 case MLME_JOIN:
mluis 0:45496a70a8a5 663 {
mluis 0:45496a70a8a5 664 // Status is OK, node has joined the network
mluis 0:45496a70a8a5 665 IsNetworkJoinedStatusUpdate = true;
mluis 0:45496a70a8a5 666 break;
mluis 0:45496a70a8a5 667 }
mluis 0:45496a70a8a5 668 case MLME_LINK_CHECK:
mluis 0:45496a70a8a5 669 {
mluis 0:45496a70a8a5 670 // Check DemodMargin
mluis 0:45496a70a8a5 671 // Check NbGateways
mluis 0:45496a70a8a5 672 if( ComplianceTest.Running == true )
mluis 0:45496a70a8a5 673 {
mluis 0:45496a70a8a5 674 ComplianceTest.LinkCheck = true;
mluis 0:45496a70a8a5 675 ComplianceTest.DemodMargin = MlmeConfirm->DemodMargin;
mluis 0:45496a70a8a5 676 ComplianceTest.NbGateways = MlmeConfirm->NbGateways;
mluis 0:45496a70a8a5 677 }
mluis 0:45496a70a8a5 678 break;
mluis 0:45496a70a8a5 679 }
mluis 0:45496a70a8a5 680 default:
mluis 0:45496a70a8a5 681 break;
mluis 0:45496a70a8a5 682 }
mluis 0:45496a70a8a5 683 }
mluis 0:45496a70a8a5 684 NextTx = true;
mluis 0:45496a70a8a5 685 UplinkStatusUpdated = true;
mluis 0:45496a70a8a5 686 }
mluis 0:45496a70a8a5 687
mluis 0:45496a70a8a5 688 /**
mluis 0:45496a70a8a5 689 * Main application entry point.
mluis 0:45496a70a8a5 690 */
mluis 0:45496a70a8a5 691 int main( void )
mluis 0:45496a70a8a5 692 {
mluis 0:45496a70a8a5 693 LoRaMacPrimitives_t LoRaMacPrimitives;
mluis 0:45496a70a8a5 694 LoRaMacCallback_t LoRaMacCallbacks;
mluis 0:45496a70a8a5 695 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 696
mluis 0:45496a70a8a5 697 BoardInit( );
mluis 0:45496a70a8a5 698 SerialDisplayInit( );
mluis 0:45496a70a8a5 699
mluis 0:45496a70a8a5 700 DeviceState = DEVICE_STATE_INIT;
mluis 0:45496a70a8a5 701
mluis 0:45496a70a8a5 702 while( 1 )
mluis 0:45496a70a8a5 703 {
mluis 0:45496a70a8a5 704 SerialRxProcess( );
mluis 0:45496a70a8a5 705 if( IsNetworkJoinedStatusUpdate == true )
mluis 0:45496a70a8a5 706 {
mluis 0:45496a70a8a5 707 IsNetworkJoinedStatusUpdate = false;
mluis 0:45496a70a8a5 708 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 709 LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 710 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
mluis 0:45496a70a8a5 711 }
mluis 0:45496a70a8a5 712 if( Led1StateChanged == true )
mluis 0:45496a70a8a5 713 {
mluis 0:45496a70a8a5 714 Led1StateChanged = false;
mluis 0:45496a70a8a5 715 SerialDisplayUpdateLedState( 1, Led1State );
mluis 0:45496a70a8a5 716 }
mluis 0:45496a70a8a5 717 if( Led2StateChanged == true )
mluis 0:45496a70a8a5 718 {
mluis 0:45496a70a8a5 719 Led2StateChanged = false;
mluis 0:45496a70a8a5 720 SerialDisplayUpdateLedState( 2, Led2State );
mluis 0:45496a70a8a5 721 }
mluis 0:45496a70a8a5 722 if( Led3StateChanged == true )
mluis 0:45496a70a8a5 723 {
mluis 0:45496a70a8a5 724 Led3StateChanged = false;
mluis 0:45496a70a8a5 725 SerialDisplayUpdateLedState( 3, AppLedStateOn );
mluis 0:45496a70a8a5 726 }
mluis 0:45496a70a8a5 727 if( UplinkStatusUpdated == true )
mluis 0:45496a70a8a5 728 {
mluis 0:45496a70a8a5 729 UplinkStatusUpdated = false;
mluis 0:45496a70a8a5 730 SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
mluis 0:45496a70a8a5 731 }
mluis 0:45496a70a8a5 732 if( DownlinkStatusUpdated == true )
mluis 0:45496a70a8a5 733 {
mluis 0:45496a70a8a5 734 DownlinkStatusUpdated = false;
mluis 0:45496a70a8a5 735 SerialDisplayUpdateLedState( 2, Led2State );
mluis 0:45496a70a8a5 736 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
mluis 0:45496a70a8a5 737 }
mluis 0:45496a70a8a5 738
mluis 0:45496a70a8a5 739 switch( DeviceState )
mluis 0:45496a70a8a5 740 {
mluis 0:45496a70a8a5 741 case DEVICE_STATE_INIT:
mluis 0:45496a70a8a5 742 {
mluis 0:45496a70a8a5 743 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
mluis 0:45496a70a8a5 744 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
mluis 0:45496a70a8a5 745 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
mluis 0:45496a70a8a5 746 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
mluis 0:45496a70a8a5 747 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
mluis 0:45496a70a8a5 748
mluis 0:45496a70a8a5 749 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
mluis 0:45496a70a8a5 750
mluis 0:45496a70a8a5 751 TimerInit( &Led1Timer, OnLed1TimerEvent );
mluis 0:45496a70a8a5 752 TimerSetValue( &Led1Timer, 25000 );
mluis 0:45496a70a8a5 753
mluis 0:45496a70a8a5 754 TimerInit( &Led2Timer, OnLed2TimerEvent );
mluis 0:45496a70a8a5 755 TimerSetValue( &Led2Timer, 25000 );
mluis 0:45496a70a8a5 756
mluis 0:45496a70a8a5 757 mibReq.Type = MIB_ADR;
mluis 0:45496a70a8a5 758 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
mluis 0:45496a70a8a5 759 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 760
mluis 0:45496a70a8a5 761 mibReq.Type = MIB_PUBLIC_NETWORK;
mluis 0:45496a70a8a5 762 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
mluis 0:45496a70a8a5 763 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 764
mluis 0:45496a70a8a5 765 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 766 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 767 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 768 #endif
mluis 0:45496a70a8a5 769 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:45496a70a8a5 770 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:45496a70a8a5 771 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
mluis 0:45496a70a8a5 772
mluis 0:45496a70a8a5 773 LoRaMacDownlinkStatus.DownlinkCounter = 0;
mluis 0:45496a70a8a5 774
mluis 0:45496a70a8a5 775 DeviceState = DEVICE_STATE_JOIN;
mluis 0:45496a70a8a5 776 break;
mluis 0:45496a70a8a5 777 }
mluis 0:45496a70a8a5 778 case DEVICE_STATE_JOIN:
mluis 0:45496a70a8a5 779 {
mluis 0:45496a70a8a5 780 #if( OVER_THE_AIR_ACTIVATION != 0 )
mluis 0:45496a70a8a5 781 MlmeReq_t mlmeReq;
mluis 0:45496a70a8a5 782
mluis 0:45496a70a8a5 783 mlmeReq.Type = MLME_JOIN;
mluis 0:45496a70a8a5 784
mluis 0:45496a70a8a5 785 mlmeReq.Req.Join.DevEui = DevEui;
mluis 0:45496a70a8a5 786 mlmeReq.Req.Join.AppEui = AppEui;
mluis 0:45496a70a8a5 787 mlmeReq.Req.Join.AppKey = AppKey;
mluis 0:45496a70a8a5 788
mluis 0:45496a70a8a5 789 if( NextTx == true )
mluis 0:45496a70a8a5 790 {
mluis 0:45496a70a8a5 791 LoRaMacMlmeRequest( &mlmeReq );
mluis 0:45496a70a8a5 792 }
mluis 0:45496a70a8a5 793
mluis 0:45496a70a8a5 794 SerialDisplayUpdateEui( 5, DevEui );
mluis 0:45496a70a8a5 795 SerialDisplayUpdateEui( 6, AppEui );
mluis 0:45496a70a8a5 796 SerialDisplayUpdateKey( 7, AppKey );
mluis 0:45496a70a8a5 797
mluis 0:45496a70a8a5 798 // Schedule next packet transmission
mluis 0:45496a70a8a5 799 TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE;
mluis 0:45496a70a8a5 800 DeviceState = DEVICE_STATE_CYCLE;
mluis 0:45496a70a8a5 801
mluis 0:45496a70a8a5 802 #else
mluis 0:45496a70a8a5 803 mibReq.Type = MIB_NET_ID;
mluis 0:45496a70a8a5 804 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
mluis 0:45496a70a8a5 805 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 806
mluis 0:45496a70a8a5 807 mibReq.Type = MIB_DEV_ADDR;
mluis 0:45496a70a8a5 808 mibReq.Param.DevAddr = DevAddr;
mluis 0:45496a70a8a5 809 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 810
mluis 0:45496a70a8a5 811 mibReq.Type = MIB_NWK_SKEY;
mluis 0:45496a70a8a5 812 mibReq.Param.NwkSKey = NwkSKey;
mluis 0:45496a70a8a5 813 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 814
mluis 0:45496a70a8a5 815 mibReq.Type = MIB_APP_SKEY;
mluis 0:45496a70a8a5 816 mibReq.Param.AppSKey = AppSKey;
mluis 0:45496a70a8a5 817 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 818
mluis 0:45496a70a8a5 819 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 820 mibReq.Param.IsNetworkJoined = true;
mluis 0:45496a70a8a5 821 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 822
mluis 0:45496a70a8a5 823 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 0:45496a70a8a5 824 SerialDisplayUpdateDevAddr( DevAddr );
mluis 0:45496a70a8a5 825 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 0:45496a70a8a5 826 SerialDisplayUpdateKey( 13, AppSKey );
mluis 0:45496a70a8a5 827
mluis 0:45496a70a8a5 828 DeviceState = DEVICE_STATE_SEND;
mluis 0:45496a70a8a5 829 #endif
mluis 0:45496a70a8a5 830 IsNetworkJoinedStatusUpdate = true;
mluis 0:45496a70a8a5 831 break;
mluis 0:45496a70a8a5 832 }
mluis 0:45496a70a8a5 833 case DEVICE_STATE_SEND:
mluis 0:45496a70a8a5 834 {
mluis 0:45496a70a8a5 835 if( NextTx == true )
mluis 0:45496a70a8a5 836 {
mluis 0:45496a70a8a5 837 SerialDisplayUpdateUplinkAcked( false );
mluis 0:45496a70a8a5 838 SerialDisplayUpdateDonwlinkRxData( false );
mluis 0:45496a70a8a5 839 PrepareTxFrame( AppPort );
mluis 0:45496a70a8a5 840
mluis 0:45496a70a8a5 841 NextTx = SendFrame( );
mluis 0:45496a70a8a5 842
mluis 0:45496a70a8a5 843 // Switch LED 1 ON
mluis 0:45496a70a8a5 844 Led1State = true;
mluis 0:45496a70a8a5 845 Led1StateChanged = true;
mluis 0:45496a70a8a5 846 TimerStart( &Led1Timer );
mluis 0:45496a70a8a5 847 }
mluis 0:45496a70a8a5 848 if( ComplianceTest.Running == true )
mluis 0:45496a70a8a5 849 {
mluis 0:45496a70a8a5 850 // Schedule next packet transmission as soon as possible
mluis 0:45496a70a8a5 851 TxDutyCycleTime = 1000; // 1 ms
mluis 0:45496a70a8a5 852 }
mluis 0:45496a70a8a5 853 else
mluis 0:45496a70a8a5 854 {
mluis 0:45496a70a8a5 855 // Schedule next packet transmission
mluis 0:45496a70a8a5 856 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
mluis 0:45496a70a8a5 857 }
mluis 0:45496a70a8a5 858 DeviceState = DEVICE_STATE_CYCLE;
mluis 0:45496a70a8a5 859 break;
mluis 0:45496a70a8a5 860 }
mluis 0:45496a70a8a5 861 case DEVICE_STATE_CYCLE:
mluis 0:45496a70a8a5 862 {
mluis 0:45496a70a8a5 863 // Schedule next packet transmission
mluis 0:45496a70a8a5 864 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
mluis 0:45496a70a8a5 865 TimerStart( &TxNextPacketTimer );
mluis 0:45496a70a8a5 866
mluis 0:45496a70a8a5 867 DeviceState = DEVICE_STATE_SLEEP;
mluis 0:45496a70a8a5 868 break;
mluis 0:45496a70a8a5 869 }
mluis 0:45496a70a8a5 870 case DEVICE_STATE_SLEEP:
mluis 0:45496a70a8a5 871 {
mluis 0:45496a70a8a5 872 // Wake up through events
mluis 0:45496a70a8a5 873 break;
mluis 0:45496a70a8a5 874 }
mluis 0:45496a70a8a5 875 default:
mluis 0:45496a70a8a5 876 {
mluis 0:45496a70a8a5 877 DeviceState = DEVICE_STATE_INIT;
mluis 0:45496a70a8a5 878 break;
mluis 0:45496a70a8a5 879 }
mluis 0:45496a70a8a5 880 }
mluis 0:45496a70a8a5 881 }
mluis 0:45496a70a8a5 882 }