Send text with LoRaWAN.
Dependencies: LMiC SX1276Lib mbed
Fork of LoRaWAN-lmic-app by
Diff: main.cpp
- Revision:
- 5:1f8829bd11ed
- Parent:
- 4:f83ad3eee79d
- Child:
- 6:fbfc95b5c979
--- a/main.cpp Sun Sep 13 10:26:09 2015 +0000 +++ b/main.cpp Sun Sep 13 13:51:32 2015 +0000 @@ -1,205 +1,93 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2015 Semtech +/* License: Revised BSD License, see LICENSE.TXT, (c)2015 Semtech */ -Description: MBED LoRaWAN example application - -License: Revised BSD License, see LICENSE.TXT file include in the project - -Maintainer: Miguel Luis and Gregory Cristian -*/ #include "mbed.h" - #include "lmic.h" #include "debug.h" -/*! - * 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 0 - -#if( OVER_THE_AIR_ACTIVATION == 0 ) - -/*! - * Defines the network ID when using personalization activation procedure - */ #define LORAWAN_NET_ID ( uint32_t )0x00000000 - -/*! - * Defines the device address when using personalization activation procedure - */ #define LORAWAN_DEV_ADDR ( uint32_t )0x00001056//0x12345678 - -#endif - -/*! - * Defines the application data transmission duty cycle - */ #define APP_TX_DUTYCYCLE 5000 // 5 [s] value in ms #define APP_TX_DUTYCYCLE_RND 1000 // 1 [s] value in ms - -/*! - * LoRaWAN Adaptative Data Rate - */ #define LORAWAN_ADR_ON 1 - -/*! - * LoRaWAN confirmed messages - */ #define LORAWAN_CONFIRMED_MSG_ON 1 - -/*! - * LoRaWAN application port - */ #define LORAWAN_APP_PORT 15 - -/*! - * User application data buffer size - */ -#if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) #define LORAWAN_APP_DATA_SIZE 6 -#else -#define LORAWAN_APP_DATA_SIZE 1 - -#endif - -////////////////////////////////////////////////// -// CONFIGURATION (FOR APPLICATION CALLBACKS BELOW) -////////////////////////////////////////////////// - -// application router ID (LSBF) -static const uint8_t AppEui[8] = -{ +static const uint8_t AppEui[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -// unique device ID (LSBF) -static const u1_t DevEui[8] = -{ -// 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF +static const u1_t DevEui[8] = { 0xF0, 0x3D, 0x29, 0x10, 0x00, 0x00, 0x10, 0x56 }; -// device-specific AES key (derived from device EUI) -static const uint8_t DevKey[16] = -{ +static const uint8_t DevKey[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; -#if( OVER_THE_AIR_ACTIVATION == 0 ) -// network session key -static uint8_t NwkSKey[] = -{ -// 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, -// 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C +static uint8_t NwkSKey[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; -// application session key -static uint8_t ArtSKey[] = -{ -// 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, -// 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C +static uint8_t ArtSKey[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; -#endif - -// LEDs and Frame jobs osjob_t rxLedJob; osjob_t txLedJob; osjob_t sendFrameJob; -// LED state static bool AppLedStateOn = false; -////////////////////////////////////////////////// -// Utility functions -////////////////////////////////////////////////// -/*! - * \brief Computes a random number between min and max - * - * \param [IN] min range minimum value - * \param [IN] max range maximum value - * \retval random random value in range min..max - */ -int32_t randr( int32_t min, int32_t max ) -{ - return ( int32_t )rand( ) % ( max - min + 1 ) + min; +int32_t randr (int32_t min, int32_t max) { + return (int32_t) rand() % (max - min + 1) + min; +} + +void os_getArtEui (uint8_t *buf) { + debug_str("os_getArtEui\r\n"); + memcpy(buf, AppEui, 8); } -////////////////////////////////////////////////// -// APPLICATION CALLBACKS -////////////////////////////////////////////////// - -// provide application router ID (8 bytes, LSBF) -void os_getArtEui( uint8_t *buf ) -{ - debug_str("os_getArtEui\r\n"); - memcpy( buf, AppEui, 8 ); +void os_getDevEui (uint8_t *buf) { + debug_str("os_getDevEui\r\n"); + memcpy(buf, DevEui, 8); } -// provide device ID (8 bytes, LSBF) -void os_getDevEui( uint8_t *buf ) -{ - debug_str("os_getDevEui\r\n"); - memcpy( buf, DevEui, 8 ); +void os_getDevKey (uint8_t *buf) { + debug_str("os_getDevKey\r\n"); + memcpy(buf, DevKey, 16); } -// provide device key (16 bytes) -void os_getDevKey( uint8_t *buf ) -{ - debug_str("os_getDevKey\r\n"); - memcpy( buf, DevKey, 16 ); -} - -////////////////////////////////////////////////// -// MAIN - INITIALIZATION AND STARTUP -////////////////////////////////////////////////// - -static void onRxLed( osjob_t* j ) -{ +static void onRxLed (osjob_t* j) { debug_val("LED2 = ", 0 ); } -static void onTxLed( osjob_t* j ) -{ +static void onTxLed (osjob_t* j) { debug_val("LED1 = ", 0 ); } -static void prepareTxFrame( void ) -{ +static void prepareTxFrame (void) { debug_str("prepareTxFrame\r\n"); LMIC.frame[0] = AppLedStateOn; -#if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) LMIC.frame[1] = LMIC.seqnoDn >> 8; LMIC.frame[2] = LMIC.seqnoDn; LMIC.frame[3] = LMIC.rssi >> 8; LMIC.frame[4] = LMIC.rssi; LMIC.frame[5] = LMIC.snr; -#endif } -void processRxFrame( void ) -{ +void processRxFrame (void) { debug_str("processRxFrame\r\n"); - switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number - { + switch(LMIC.frame[LMIC.dataBeg - 1]) { // Check Rx port number case 1: // The application LED can be controlled on port 1 or 2 case 2: - if( LMIC.dataLen == 1 ) - { + if(LMIC.dataLen == 1) { AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01; - debug_val( "LED3 = ", AppLedStateOn ); + debug_val("LED3 = ", AppLedStateOn); } break; default: @@ -207,79 +95,60 @@ } } -static void onSendFrame( osjob_t* j ) -{ +static void onSendFrame (osjob_t* j) { debug_str("onSendFrame\r\n"); - prepareTxFrame( ); - LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON ); + prepareTxFrame(); + LMIC_setTxData2( + LORAWAN_APP_PORT, + LMIC.frame, + LORAWAN_APP_DATA_SIZE, + LORAWAN_CONFIRMED_MSG_ON); - // Blink Tx LED - debug_val( "LED1 = ", 1 ); - os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed ); +// debug_val("LED1 = ", 1); +// os_setTimedCallback(&txLedJob, os_getTime() + ms2osticks(25), onTxLed); } -// Initialization job -static void onInit( osjob_t* j ) -{ +static void onInit (osjob_t* j) { debug_str("onInit\r\n"); - // reset MAC state - LMIC_reset( ); - LMIC_setAdrMode( LORAWAN_ADR_ON ); - LMIC_setDrTxpow( DR_SF12, 14 ); - - // start joining -#if( OVER_THE_AIR_ACTIVATION != 0 ) - LMIC_startJoining( ); -#else - LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey ); - onSendFrame( NULL ); -#endif - // init done - onEvent( ) callback will be invoked... + LMIC_reset(); // reset MAC state + LMIC_setAdrMode(LORAWAN_ADR_ON); + LMIC_setDrTxpow(DR_SF12, 14); + LMIC_setSession( + LORAWAN_NET_ID, + LORAWAN_DEV_ADDR, + NwkSKey, + ArtSKey); + onSendFrame(NULL); + // onEvent() callback will be invoked... } -int main( void ) -{ +int main(void) { debug_str("main\r\n"); osjob_t initjob; - - // initialize runtime env - os_init( ); - // setup initial job - os_setCallback( &initjob, onInit ); - // execute scheduled jobs and events - os_runloop( ); - // (not reached) + os_init(); + os_setCallback(&initjob, onInit); + os_runloop(); // blocking } -////////////////////////////////////////////////// -// LMIC EVENT CALLBACK -////////////////////////////////////////////////// -void onEvent( ev_t ev ) -{ +void onEvent (ev_t ev) { debug_str("onEvent\r\n"); bool txOn = false; - debug_event( ev ); + debug_event(ev); - switch( ev ) - { - // network joined, session established - case EV_JOINED: - debug_val( "Net ID = ", LMIC.netid ); + switch(ev) { + case EV_JOINED: // network joined, session established + debug_val("Net ID = ", LMIC.netid); txOn = true; break; - // scheduled data sent (optionally data received) - case EV_TXCOMPLETE: - debug_val( "Datarate = ", LMIC.datarate ); + case EV_TXCOMPLETE: // scheduled data sent (optionally data received) + debug_val("Datarate = ", LMIC.datarate); // Check if we have a downlink on either Rx1 or Rx2 windows - if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 ) - { - debug_val( "LED2 = ", 1 ); - os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed ); - - if( LMIC.dataLen != 0 ) - { // data received in rx slot after tx - debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen ); - processRxFrame( ); + if ((LMIC.txrxFlags & (TXRX_DNW1 | TXRX_DNW2)) != 0) { + debug_val("LED2 = ", 1); + os_setTimedCallback(&rxLedJob, os_getTime() + ms2osticks(25), onRxLed); + if (LMIC.dataLen != 0) { // data received in rx slot after tx + debug_buf(LMIC.frame + LMIC.dataBeg, LMIC.dataLen); + processRxFrame(); } } txOn = true; @@ -287,14 +156,10 @@ default: break; } - if( txOn == true ) - { - //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited) - os_setTimedCallback( &sendFrameJob, - os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ), - onSendFrame ); - - ////Sends frame as soon as possible (duty cylce limitations) - //onSendFrame( NULL ); + if (txOn == true) { + os_setTimedCallback( + &sendFrameJob, + os_getTime() + ms2osticks(APP_TX_DUTYCYCLE + randr(-APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND)), + onSendFrame); } }