Send text with LoRaWAN.

Dependencies:   LMiC SX1276Lib mbed

Fork of LoRaWAN-lmic-app by Semtech

Committer:
tamberg
Date:
Sun Sep 13 10:26:09 2015 +0000
Revision:
4:f83ad3eee79d
Parent:
3:ce28e3313a88
Child:
5:1f8829bd11ed
Set LORAWAN_NET_ID, LORAWAN_DEV_ADDR, DevEui, NwkSKey, ArtSKey

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 3:ce28e3313a88 1 /*
mluis 0:a2929fa6e4f0 2 / _____) _ | |
mluis 0:a2929fa6e4f0 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:a2929fa6e4f0 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:a2929fa6e4f0 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:a2929fa6e4f0 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 1:60184eda0066 7 (C)2015 Semtech
mluis 0:a2929fa6e4f0 8
mluis 1:60184eda0066 9 Description: MBED LoRaWAN example application
mluis 0:a2929fa6e4f0 10
mluis 0:a2929fa6e4f0 11 License: Revised BSD License, see LICENSE.TXT file include in the project
mluis 0:a2929fa6e4f0 12
mluis 0:a2929fa6e4f0 13 Maintainer: Miguel Luis and Gregory Cristian
mluis 0:a2929fa6e4f0 14 */
mluis 1:60184eda0066 15 #include "mbed.h"
mluis 1:60184eda0066 16
mluis 0:a2929fa6e4f0 17 #include "lmic.h"
mluis 1:60184eda0066 18 #include "debug.h"
mluis 0:a2929fa6e4f0 19
mluis 0:a2929fa6e4f0 20 /*!
mluis 0:a2929fa6e4f0 21 * When set to 1 the application uses the Over-the-Air activation procedure
mluis 0:a2929fa6e4f0 22 * When set to 0 the application uses the Personalization activation procedure
mluis 0:a2929fa6e4f0 23 */
mluis 0:a2929fa6e4f0 24 #define OVER_THE_AIR_ACTIVATION 0
mluis 0:a2929fa6e4f0 25
mluis 1:60184eda0066 26 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 1:60184eda0066 27
mluis 1:60184eda0066 28 /*!
mluis 1:60184eda0066 29 * Defines the network ID when using personalization activation procedure
mluis 1:60184eda0066 30 */
mluis 1:60184eda0066 31 #define LORAWAN_NET_ID ( uint32_t )0x00000000
mluis 1:60184eda0066 32
mluis 1:60184eda0066 33 /*!
mluis 1:60184eda0066 34 * Defines the device address when using personalization activation procedure
mluis 1:60184eda0066 35 */
tamberg 4:f83ad3eee79d 36 #define LORAWAN_DEV_ADDR ( uint32_t )0x00001056//0x12345678
mluis 1:60184eda0066 37
mluis 1:60184eda0066 38 #endif
mluis 1:60184eda0066 39
mluis 1:60184eda0066 40 /*!
mluis 1:60184eda0066 41 * Defines the application data transmission duty cycle
mluis 1:60184eda0066 42 */
mluis 1:60184eda0066 43 #define APP_TX_DUTYCYCLE 5000 // 5 [s] value in ms
mluis 1:60184eda0066 44 #define APP_TX_DUTYCYCLE_RND 1000 // 1 [s] value in ms
mluis 1:60184eda0066 45
mluis 1:60184eda0066 46 /*!
mluis 1:60184eda0066 47 * LoRaWAN Adaptative Data Rate
mluis 1:60184eda0066 48 */
mluis 1:60184eda0066 49 #define LORAWAN_ADR_ON 1
mluis 1:60184eda0066 50
mluis 1:60184eda0066 51 /*!
mluis 1:60184eda0066 52 * LoRaWAN confirmed messages
mluis 1:60184eda0066 53 */
mluis 1:60184eda0066 54 #define LORAWAN_CONFIRMED_MSG_ON 1
mluis 1:60184eda0066 55
mluis 1:60184eda0066 56 /*!
mluis 1:60184eda0066 57 * LoRaWAN application port
mluis 1:60184eda0066 58 */
mluis 1:60184eda0066 59 #define LORAWAN_APP_PORT 15
mluis 1:60184eda0066 60
mluis 1:60184eda0066 61 /*!
mluis 1:60184eda0066 62 * User application data buffer size
mluis 1:60184eda0066 63 */
mluis 1:60184eda0066 64 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 1:60184eda0066 65 #define LORAWAN_APP_DATA_SIZE 6
mluis 1:60184eda0066 66
mluis 1:60184eda0066 67 #else
mluis 1:60184eda0066 68 #define LORAWAN_APP_DATA_SIZE 1
mluis 1:60184eda0066 69
mluis 1:60184eda0066 70 #endif
mluis 0:a2929fa6e4f0 71
mluis 0:a2929fa6e4f0 72 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 73 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
mluis 0:a2929fa6e4f0 74 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 75
mluis 0:a2929fa6e4f0 76 // application router ID (LSBF)
mluis 1:60184eda0066 77 static const uint8_t AppEui[8] =
mluis 0:a2929fa6e4f0 78 {
mluis 1:60184eda0066 79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:a2929fa6e4f0 80 };
mluis 0:a2929fa6e4f0 81
mluis 0:a2929fa6e4f0 82 // unique device ID (LSBF)
mluis 0:a2929fa6e4f0 83 static const u1_t DevEui[8] =
mluis 0:a2929fa6e4f0 84 {
tamberg 4:f83ad3eee79d 85 // 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
tamberg 4:f83ad3eee79d 86 0xF0, 0x3D, 0x29, 0x10, 0x00, 0x00, 0x10, 0x56
mluis 0:a2929fa6e4f0 87 };
mluis 0:a2929fa6e4f0 88
mluis 0:a2929fa6e4f0 89 // device-specific AES key (derived from device EUI)
mluis 1:60184eda0066 90 static const uint8_t DevKey[16] =
mluis 0:a2929fa6e4f0 91 {
mluis 1:60184eda0066 92 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
mluis 1:60184eda0066 93 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
mluis 0:a2929fa6e4f0 94 };
mluis 0:a2929fa6e4f0 95
mluis 1:60184eda0066 96 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 1:60184eda0066 97 // network session key
mluis 0:a2929fa6e4f0 98 static uint8_t NwkSKey[] =
mluis 0:a2929fa6e4f0 99 {
tamberg 4:f83ad3eee79d 100 // 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
tamberg 4:f83ad3eee79d 101 // 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
tamberg 4:f83ad3eee79d 102 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
tamberg 4:f83ad3eee79d 103 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
mluis 0:a2929fa6e4f0 104 };
mluis 0:a2929fa6e4f0 105
mluis 1:60184eda0066 106 // application session key
mluis 0:a2929fa6e4f0 107 static uint8_t ArtSKey[] =
mluis 0:a2929fa6e4f0 108 {
tamberg 4:f83ad3eee79d 109 // 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
tamberg 4:f83ad3eee79d 110 // 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
tamberg 4:f83ad3eee79d 111 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
tamberg 4:f83ad3eee79d 112 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
mluis 0:a2929fa6e4f0 113 };
mluis 0:a2929fa6e4f0 114
mluis 1:60184eda0066 115 #endif
mluis 1:60184eda0066 116
mluis 0:a2929fa6e4f0 117 // LEDs and Frame jobs
mluis 0:a2929fa6e4f0 118 osjob_t rxLedJob;
mluis 0:a2929fa6e4f0 119 osjob_t txLedJob;
mluis 0:a2929fa6e4f0 120 osjob_t sendFrameJob;
mluis 0:a2929fa6e4f0 121
mluis 1:60184eda0066 122 // LED state
mluis 0:a2929fa6e4f0 123 static bool AppLedStateOn = false;
mluis 0:a2929fa6e4f0 124
mluis 0:a2929fa6e4f0 125 //////////////////////////////////////////////////
mluis 1:60184eda0066 126 // Utility functions
mluis 1:60184eda0066 127 //////////////////////////////////////////////////
mluis 1:60184eda0066 128 /*!
mluis 1:60184eda0066 129 * \brief Computes a random number between min and max
mluis 1:60184eda0066 130 *
mluis 1:60184eda0066 131 * \param [IN] min range minimum value
mluis 1:60184eda0066 132 * \param [IN] max range maximum value
mluis 1:60184eda0066 133 * \retval random random value in range min..max
mluis 1:60184eda0066 134 */
mluis 1:60184eda0066 135 int32_t randr( int32_t min, int32_t max )
mluis 1:60184eda0066 136 {
mluis 1:60184eda0066 137 return ( int32_t )rand( ) % ( max - min + 1 ) + min;
mluis 1:60184eda0066 138 }
mluis 1:60184eda0066 139
mluis 1:60184eda0066 140 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 141 // APPLICATION CALLBACKS
mluis 0:a2929fa6e4f0 142 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 143
mluis 0:a2929fa6e4f0 144 // provide application router ID (8 bytes, LSBF)
mluis 1:60184eda0066 145 void os_getArtEui( uint8_t *buf )
mluis 0:a2929fa6e4f0 146 {
tamberg 4:f83ad3eee79d 147 debug_str("os_getArtEui\r\n");
mluis 0:a2929fa6e4f0 148 memcpy( buf, AppEui, 8 );
mluis 0:a2929fa6e4f0 149 }
mluis 0:a2929fa6e4f0 150
mluis 0:a2929fa6e4f0 151 // provide device ID (8 bytes, LSBF)
mluis 1:60184eda0066 152 void os_getDevEui( uint8_t *buf )
mluis 0:a2929fa6e4f0 153 {
tamberg 4:f83ad3eee79d 154 debug_str("os_getDevEui\r\n");
mluis 0:a2929fa6e4f0 155 memcpy( buf, DevEui, 8 );
mluis 0:a2929fa6e4f0 156 }
mluis 0:a2929fa6e4f0 157
mluis 0:a2929fa6e4f0 158 // provide device key (16 bytes)
mluis 1:60184eda0066 159 void os_getDevKey( uint8_t *buf )
mluis 0:a2929fa6e4f0 160 {
tamberg 4:f83ad3eee79d 161 debug_str("os_getDevKey\r\n");
mluis 0:a2929fa6e4f0 162 memcpy( buf, DevKey, 16 );
mluis 0:a2929fa6e4f0 163 }
mluis 0:a2929fa6e4f0 164
mluis 0:a2929fa6e4f0 165 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 166 // MAIN - INITIALIZATION AND STARTUP
mluis 0:a2929fa6e4f0 167 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 168
mluis 0:a2929fa6e4f0 169 static void onRxLed( osjob_t* j )
mluis 0:a2929fa6e4f0 170 {
mluis 1:60184eda0066 171 debug_val("LED2 = ", 0 );
mluis 0:a2929fa6e4f0 172 }
mluis 0:a2929fa6e4f0 173
mluis 0:a2929fa6e4f0 174 static void onTxLed( osjob_t* j )
mluis 0:a2929fa6e4f0 175 {
mluis 1:60184eda0066 176 debug_val("LED1 = ", 0 );
mluis 0:a2929fa6e4f0 177 }
mluis 0:a2929fa6e4f0 178
mluis 0:a2929fa6e4f0 179 static void prepareTxFrame( void )
mluis 0:a2929fa6e4f0 180 {
tamberg 4:f83ad3eee79d 181 debug_str("prepareTxFrame\r\n");
mluis 0:a2929fa6e4f0 182 LMIC.frame[0] = AppLedStateOn;
mluis 1:60184eda0066 183 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 1:60184eda0066 184 LMIC.frame[1] = LMIC.seqnoDn >> 8;
mluis 1:60184eda0066 185 LMIC.frame[2] = LMIC.seqnoDn;
mluis 1:60184eda0066 186 LMIC.frame[3] = LMIC.rssi >> 8;
mluis 1:60184eda0066 187 LMIC.frame[4] = LMIC.rssi;
mluis 1:60184eda0066 188 LMIC.frame[5] = LMIC.snr;
mluis 1:60184eda0066 189 #endif
mluis 0:a2929fa6e4f0 190 }
mluis 0:a2929fa6e4f0 191
mluis 0:a2929fa6e4f0 192 void processRxFrame( void )
mluis 0:a2929fa6e4f0 193 {
tamberg 4:f83ad3eee79d 194 debug_str("processRxFrame\r\n");
mluis 0:a2929fa6e4f0 195 switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number
mluis 0:a2929fa6e4f0 196 {
mluis 0:a2929fa6e4f0 197 case 1: // The application LED can be controlled on port 1 or 2
mluis 0:a2929fa6e4f0 198 case 2:
mluis 0:a2929fa6e4f0 199 if( LMIC.dataLen == 1 )
mluis 0:a2929fa6e4f0 200 {
mluis 0:a2929fa6e4f0 201 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
mluis 1:60184eda0066 202 debug_val( "LED3 = ", AppLedStateOn );
mluis 0:a2929fa6e4f0 203 }
mluis 0:a2929fa6e4f0 204 break;
mluis 0:a2929fa6e4f0 205 default:
mluis 0:a2929fa6e4f0 206 break;
mluis 0:a2929fa6e4f0 207 }
mluis 0:a2929fa6e4f0 208 }
mluis 0:a2929fa6e4f0 209
mluis 0:a2929fa6e4f0 210 static void onSendFrame( osjob_t* j )
mluis 0:a2929fa6e4f0 211 {
tamberg 4:f83ad3eee79d 212 debug_str("onSendFrame\r\n");
mluis 0:a2929fa6e4f0 213 prepareTxFrame( );
mluis 1:60184eda0066 214 LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON );
mluis 1:60184eda0066 215
mluis 1:60184eda0066 216 // Blink Tx LED
mluis 1:60184eda0066 217 debug_val( "LED1 = ", 1 );
mluis 1:60184eda0066 218 os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed );
mluis 0:a2929fa6e4f0 219 }
mluis 0:a2929fa6e4f0 220
mluis 1:60184eda0066 221 // Initialization job
mluis 1:60184eda0066 222 static void onInit( osjob_t* j )
mluis 1:60184eda0066 223 {
tamberg 4:f83ad3eee79d 224 debug_str("onInit\r\n");
mluis 1:60184eda0066 225 // reset MAC state
mluis 1:60184eda0066 226 LMIC_reset( );
mluis 1:60184eda0066 227 LMIC_setAdrMode( LORAWAN_ADR_ON );
mluis 1:60184eda0066 228 LMIC_setDrTxpow( DR_SF12, 14 );
mluis 1:60184eda0066 229
mluis 1:60184eda0066 230 // start joining
mluis 1:60184eda0066 231 #if( OVER_THE_AIR_ACTIVATION != 0 )
mluis 1:60184eda0066 232 LMIC_startJoining( );
mluis 1:60184eda0066 233 #else
mluis 1:60184eda0066 234 LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey );
mluis 1:60184eda0066 235 onSendFrame( NULL );
mluis 1:60184eda0066 236 #endif
mluis 1:60184eda0066 237 // init done - onEvent( ) callback will be invoked...
mluis 1:60184eda0066 238 }
mluis 1:60184eda0066 239
mluis 1:60184eda0066 240 int main( void )
mluis 0:a2929fa6e4f0 241 {
tamberg 4:f83ad3eee79d 242 debug_str("main\r\n");
mluis 0:a2929fa6e4f0 243 osjob_t initjob;
mluis 0:a2929fa6e4f0 244
mluis 0:a2929fa6e4f0 245 // initialize runtime env
mluis 0:a2929fa6e4f0 246 os_init( );
mluis 0:a2929fa6e4f0 247 // setup initial job
mluis 0:a2929fa6e4f0 248 os_setCallback( &initjob, onInit );
mluis 0:a2929fa6e4f0 249 // execute scheduled jobs and events
mluis 0:a2929fa6e4f0 250 os_runloop( );
mluis 0:a2929fa6e4f0 251 // (not reached)
mluis 0:a2929fa6e4f0 252 }
mluis 0:a2929fa6e4f0 253
mluis 0:a2929fa6e4f0 254 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 255 // LMIC EVENT CALLBACK
mluis 0:a2929fa6e4f0 256 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 257 void onEvent( ev_t ev )
mluis 0:a2929fa6e4f0 258 {
tamberg 4:f83ad3eee79d 259 debug_str("onEvent\r\n");
mluis 0:a2929fa6e4f0 260 bool txOn = false;
mluis 1:60184eda0066 261 debug_event( ev );
mluis 0:a2929fa6e4f0 262
mluis 0:a2929fa6e4f0 263 switch( ev )
mluis 0:a2929fa6e4f0 264 {
mluis 0:a2929fa6e4f0 265 // network joined, session established
mluis 0:a2929fa6e4f0 266 case EV_JOINED:
mluis 1:60184eda0066 267 debug_val( "Net ID = ", LMIC.netid );
mluis 0:a2929fa6e4f0 268 txOn = true;
mluis 0:a2929fa6e4f0 269 break;
mluis 0:a2929fa6e4f0 270 // scheduled data sent (optionally data received)
mluis 0:a2929fa6e4f0 271 case EV_TXCOMPLETE:
mluis 1:60184eda0066 272 debug_val( "Datarate = ", LMIC.datarate );
mluis 0:a2929fa6e4f0 273 // Check if we have a downlink on either Rx1 or Rx2 windows
mluis 1:60184eda0066 274 if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 )
mluis 0:a2929fa6e4f0 275 {
mluis 1:60184eda0066 276 debug_val( "LED2 = ", 1 );
mluis 1:60184eda0066 277 os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed );
mluis 0:a2929fa6e4f0 278
mluis 1:60184eda0066 279 if( LMIC.dataLen != 0 )
mluis 0:a2929fa6e4f0 280 { // data received in rx slot after tx
mluis 1:60184eda0066 281 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
mluis 0:a2929fa6e4f0 282 processRxFrame( );
mluis 0:a2929fa6e4f0 283 }
mluis 0:a2929fa6e4f0 284 }
mluis 0:a2929fa6e4f0 285 txOn = true;
mluis 0:a2929fa6e4f0 286 break;
mluis 0:a2929fa6e4f0 287 default:
mluis 0:a2929fa6e4f0 288 break;
mluis 0:a2929fa6e4f0 289 }
mluis 0:a2929fa6e4f0 290 if( txOn == true )
mluis 0:a2929fa6e4f0 291 {
mluis 1:60184eda0066 292 //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited)
mluis 1:60184eda0066 293 os_setTimedCallback( &sendFrameJob,
mluis 1:60184eda0066 294 os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ),
mluis 1:60184eda0066 295 onSendFrame );
mluis 0:a2929fa6e4f0 296
mluis 1:60184eda0066 297 ////Sends frame as soon as possible (duty cylce limitations)
mluis 1:60184eda0066 298 //onSendFrame( NULL );
mluis 0:a2929fa6e4f0 299 }
mluis 0:a2929fa6e4f0 300 }