Send text with LoRaWAN.

Dependencies:   LMiC SX1276Lib mbed

Fork of LoRaWAN-lmic-app by Semtech

Committer:
mluis
Date:
Thu Jan 22 13:02:55 2015 +0000
Revision:
0:a2929fa6e4f0
Child:
1:60184eda0066
Basic Class A node example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:a2929fa6e4f0 1 /*
mluis 0:a2929fa6e4f0 2 / _____) _ | |
mluis 0:a2929fa6e4f0 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:a2929fa6e4f0 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:a2929fa6e4f0 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:a2929fa6e4f0 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 0:a2929fa6e4f0 7 (C)2013 Semtech
mluis 0:a2929fa6e4f0 8
mluis 0:a2929fa6e4f0 9 Description: MBED 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 0:a2929fa6e4f0 15 #include "lmic.h"
mluis 0:a2929fa6e4f0 16
mluis 0:a2929fa6e4f0 17 /*!
mluis 0:a2929fa6e4f0 18 * When set to 1 the application uses the Over-the-Air activation procedure
mluis 0:a2929fa6e4f0 19 * When set to 0 the application uses the Personalization activation procedure
mluis 0:a2929fa6e4f0 20 */
mluis 0:a2929fa6e4f0 21 #define OVER_THE_AIR_ACTIVATION 0
mluis 0:a2929fa6e4f0 22
mluis 0:a2929fa6e4f0 23 #define APP_DATA_SIZE 1
mluis 0:a2929fa6e4f0 24
mluis 0:a2929fa6e4f0 25 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 26 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
mluis 0:a2929fa6e4f0 27 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 28
mluis 0:a2929fa6e4f0 29 // application router ID (LSBF)
mluis 0:a2929fa6e4f0 30 static const u1_t AppEui[8] =
mluis 0:a2929fa6e4f0 31 {
mluis 0:a2929fa6e4f0 32 0xAA, 0xCC, 0x11, 0x00, 0xCC, 0xEE, 0x77, 0xEE
mluis 0:a2929fa6e4f0 33 };
mluis 0:a2929fa6e4f0 34
mluis 0:a2929fa6e4f0 35 // unique device ID (LSBF)
mluis 0:a2929fa6e4f0 36 static const u1_t DevEui[8] =
mluis 0:a2929fa6e4f0 37 {
mluis 0:a2929fa6e4f0 38 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
mluis 0:a2929fa6e4f0 39 };
mluis 0:a2929fa6e4f0 40
mluis 0:a2929fa6e4f0 41 // device-specific AES key (derived from device EUI)
mluis 0:a2929fa6e4f0 42 static const u1_t DevKey[16] =
mluis 0:a2929fa6e4f0 43 {
mluis 0:a2929fa6e4f0 44 0xAB, 0x89, 0xEF, 0xCD, 0x23, 0x01, 0x67, 0x45,
mluis 0:a2929fa6e4f0 45 0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA
mluis 0:a2929fa6e4f0 46 };
mluis 0:a2929fa6e4f0 47
mluis 0:a2929fa6e4f0 48 static uint8_t NwkSKey[] =
mluis 0:a2929fa6e4f0 49 {
mluis 0:a2929fa6e4f0 50 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
mluis 0:a2929fa6e4f0 51 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
mluis 0:a2929fa6e4f0 52 };
mluis 0:a2929fa6e4f0 53
mluis 0:a2929fa6e4f0 54 static uint8_t ArtSKey[] =
mluis 0:a2929fa6e4f0 55 {
mluis 0:a2929fa6e4f0 56 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
mluis 0:a2929fa6e4f0 57 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
mluis 0:a2929fa6e4f0 58 };
mluis 0:a2929fa6e4f0 59
mluis 0:a2929fa6e4f0 60 // LEDs and Frame jobs
mluis 0:a2929fa6e4f0 61 osjob_t rxLedJob;
mluis 0:a2929fa6e4f0 62 osjob_t txLedJob;
mluis 0:a2929fa6e4f0 63 osjob_t sendFrameJob;
mluis 0:a2929fa6e4f0 64
mluis 0:a2929fa6e4f0 65 static bool AppLedStateOn = false;
mluis 0:a2929fa6e4f0 66
mluis 0:a2929fa6e4f0 67 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 68 // APPLICATION CALLBACKS
mluis 0:a2929fa6e4f0 69 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 70
mluis 0:a2929fa6e4f0 71 // provide application router ID (8 bytes, LSBF)
mluis 0:a2929fa6e4f0 72 void os_getArtEui( u1_t* buf )
mluis 0:a2929fa6e4f0 73 {
mluis 0:a2929fa6e4f0 74 memcpy( buf, AppEui, 8 );
mluis 0:a2929fa6e4f0 75 }
mluis 0:a2929fa6e4f0 76
mluis 0:a2929fa6e4f0 77 // provide device ID (8 bytes, LSBF)
mluis 0:a2929fa6e4f0 78 void os_getDevEui( u1_t* buf )
mluis 0:a2929fa6e4f0 79 {
mluis 0:a2929fa6e4f0 80 memcpy( buf, DevEui, 8 );
mluis 0:a2929fa6e4f0 81 }
mluis 0:a2929fa6e4f0 82
mluis 0:a2929fa6e4f0 83 // provide device key (16 bytes)
mluis 0:a2929fa6e4f0 84 void os_getDevKey( u1_t* buf )
mluis 0:a2929fa6e4f0 85 {
mluis 0:a2929fa6e4f0 86 memcpy( buf, DevKey, 16 );
mluis 0:a2929fa6e4f0 87 }
mluis 0:a2929fa6e4f0 88
mluis 0:a2929fa6e4f0 89 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 90 // MAIN - INITIALIZATION AND STARTUP
mluis 0:a2929fa6e4f0 91 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 92
mluis 0:a2929fa6e4f0 93 // Initialization job
mluis 0:a2929fa6e4f0 94 static void onInit( osjob_t* j )
mluis 0:a2929fa6e4f0 95 {
mluis 0:a2929fa6e4f0 96 // reset MAC state
mluis 0:a2929fa6e4f0 97 LMIC_reset( );
mluis 0:a2929fa6e4f0 98 LMIC_setAdrMode( 1 );
mluis 0:a2929fa6e4f0 99 LMIC_setDrTxpow( DR_FSK, 14 );
mluis 0:a2929fa6e4f0 100 // start joining
mluis 0:a2929fa6e4f0 101 #if( OVER_THE_AIR_ACTIVATION != 0 )
mluis 0:a2929fa6e4f0 102 LMIC_startJoining( );
mluis 0:a2929fa6e4f0 103 #else
mluis 0:a2929fa6e4f0 104 LMIC_startABP( 0, 0x44332211, NwkSKey, ArtSKey );
mluis 0:a2929fa6e4f0 105 #endif
mluis 0:a2929fa6e4f0 106 // init done - onEvent() callback will be invoked...
mluis 0:a2929fa6e4f0 107 }
mluis 0:a2929fa6e4f0 108
mluis 0:a2929fa6e4f0 109 static void onRxLed( osjob_t* j )
mluis 0:a2929fa6e4f0 110 {
mluis 0:a2929fa6e4f0 111 DEBUG_VAL("LED2 = ", 1 );
mluis 0:a2929fa6e4f0 112 }
mluis 0:a2929fa6e4f0 113
mluis 0:a2929fa6e4f0 114 static void onTxLed( osjob_t* j )
mluis 0:a2929fa6e4f0 115 {
mluis 0:a2929fa6e4f0 116 DEBUG_VAL("LED1 = ", 1 );
mluis 0:a2929fa6e4f0 117 }
mluis 0:a2929fa6e4f0 118
mluis 0:a2929fa6e4f0 119 static void prepareTxFrame( void )
mluis 0:a2929fa6e4f0 120 {
mluis 0:a2929fa6e4f0 121 LMIC.frame[0] = AppLedStateOn;
mluis 0:a2929fa6e4f0 122 }
mluis 0:a2929fa6e4f0 123
mluis 0:a2929fa6e4f0 124 void processRxFrame( void )
mluis 0:a2929fa6e4f0 125 {
mluis 0:a2929fa6e4f0 126 switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number
mluis 0:a2929fa6e4f0 127 {
mluis 0:a2929fa6e4f0 128 case 1: // The application LED can be controlled on port 1 or 2
mluis 0:a2929fa6e4f0 129 case 2:
mluis 0:a2929fa6e4f0 130 if( LMIC.dataLen == 1 )
mluis 0:a2929fa6e4f0 131 {
mluis 0:a2929fa6e4f0 132 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
mluis 0:a2929fa6e4f0 133 DEBUG_VAL( "LED3 = ", AppLedStateOn ? 0 : 1 );
mluis 0:a2929fa6e4f0 134 }
mluis 0:a2929fa6e4f0 135 break;
mluis 0:a2929fa6e4f0 136 default:
mluis 0:a2929fa6e4f0 137 break;
mluis 0:a2929fa6e4f0 138 }
mluis 0:a2929fa6e4f0 139 }
mluis 0:a2929fa6e4f0 140
mluis 0:a2929fa6e4f0 141 static void onSendFrame( osjob_t* j )
mluis 0:a2929fa6e4f0 142 {
mluis 0:a2929fa6e4f0 143 prepareTxFrame( );
mluis 0:a2929fa6e4f0 144 LMIC_setTxData2( 1, LMIC.frame, APP_DATA_SIZE, 1 );
mluis 0:a2929fa6e4f0 145 }
mluis 0:a2929fa6e4f0 146
mluis 0:a2929fa6e4f0 147 int main(void)
mluis 0:a2929fa6e4f0 148 {
mluis 0:a2929fa6e4f0 149 osjob_t initjob;
mluis 0:a2929fa6e4f0 150
mluis 0:a2929fa6e4f0 151 // initialize runtime env
mluis 0:a2929fa6e4f0 152 os_init( );
mluis 0:a2929fa6e4f0 153 // setup initial job
mluis 0:a2929fa6e4f0 154 os_setCallback( &initjob, onInit );
mluis 0:a2929fa6e4f0 155 // execute scheduled jobs and events
mluis 0:a2929fa6e4f0 156 os_runloop( );
mluis 0:a2929fa6e4f0 157 // (not reached)
mluis 0:a2929fa6e4f0 158 }
mluis 0:a2929fa6e4f0 159
mluis 0:a2929fa6e4f0 160 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 161 // LMIC EVENT CALLBACK
mluis 0:a2929fa6e4f0 162 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 163 void onEvent( ev_t ev )
mluis 0:a2929fa6e4f0 164 {
mluis 0:a2929fa6e4f0 165 bool txOn = false;
mluis 0:a2929fa6e4f0 166
mluis 0:a2929fa6e4f0 167 DEBUG_EVENT( ev );
mluis 0:a2929fa6e4f0 168
mluis 0:a2929fa6e4f0 169 switch( ev )
mluis 0:a2929fa6e4f0 170 {
mluis 0:a2929fa6e4f0 171 // network joined, session established
mluis 0:a2929fa6e4f0 172 case EV_JOINED:
mluis 0:a2929fa6e4f0 173 DEBUG_VAL( "Net ID = ", LMIC.netid );
mluis 0:a2929fa6e4f0 174 txOn = true;
mluis 0:a2929fa6e4f0 175 break;
mluis 0:a2929fa6e4f0 176 // scheduled data sent (optionally data received)
mluis 0:a2929fa6e4f0 177 case EV_TXCOMPLETE:
mluis 0:a2929fa6e4f0 178 // Check if we have a downlink on either Rx1 or Rx2 windows
mluis 0:a2929fa6e4f0 179 if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) )!= 0 )
mluis 0:a2929fa6e4f0 180 {
mluis 0:a2929fa6e4f0 181 DEBUG_VAL( "LED2 = ", 0 );
mluis 0:a2929fa6e4f0 182 os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 15 ), onRxLed );
mluis 0:a2929fa6e4f0 183
mluis 0:a2929fa6e4f0 184 if( LMIC.dataLen != 0 )
mluis 0:a2929fa6e4f0 185 { // data received in rx slot after tx
mluis 0:a2929fa6e4f0 186 DEBUG_BUF( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
mluis 0:a2929fa6e4f0 187 processRxFrame( );
mluis 0:a2929fa6e4f0 188 }
mluis 0:a2929fa6e4f0 189 }
mluis 0:a2929fa6e4f0 190 txOn = true;
mluis 0:a2929fa6e4f0 191 break;
mluis 0:a2929fa6e4f0 192 default:
mluis 0:a2929fa6e4f0 193 break;
mluis 0:a2929fa6e4f0 194 }
mluis 0:a2929fa6e4f0 195 if( txOn == true )
mluis 0:a2929fa6e4f0 196 {
mluis 0:a2929fa6e4f0 197 //os_setTimedCallback( &sendFrameJob, os_getTime( ) + sec2osticks( 5 ), onSendFrame );
mluis 0:a2929fa6e4f0 198 onSendFrame( NULL );
mluis 0:a2929fa6e4f0 199
mluis 0:a2929fa6e4f0 200 // Blink Tx LED
mluis 0:a2929fa6e4f0 201 DEBUG_VAL( "LED1 = ", 0 );
mluis 0:a2929fa6e4f0 202 os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed );
mluis 0:a2929fa6e4f0 203 }
mluis 0:a2929fa6e4f0 204 }