Adapted to LoRa Semtech + Nucleo

Dependencies:   LMiC SX1276Lib cantcoap lwip mbed-rtos mbed

Fork of LoRaWAN-lmic-app by Pascal Nysten

Committer:
pnysten
Date:
Fri Nov 20 12:33:37 2015 +0000
Revision:
4:5e274bf85bf0
Parent:
3:ce28e3313a88
Child:
6:540c5d907c90
Adapted to LoRa Semtech + Nucleo

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 */
pnysten 4:5e274bf85bf0 15 #include <cstdio>
pnysten 4:5e274bf85bf0 16 #include <string>
pnysten 4:5e274bf85bf0 17 #include <cassert>
pnysten 4:5e274bf85bf0 18
mluis 1:60184eda0066 19 #include "mbed.h"
pnysten 4:5e274bf85bf0 20 #include "cantcoap.h"
mluis 1:60184eda0066 21
mluis 0:a2929fa6e4f0 22 #include "lmic.h"
mluis 1:60184eda0066 23 #include "debug.h"
mluis 0:a2929fa6e4f0 24
pnysten 4:5e274bf85bf0 25 const std::string REGISTRATION_SEGMENT ="/rd";
pnysten 4:5e274bf85bf0 26 const std::string ENDPOINT_SEGMENT = "?ep=";
pnysten 4:5e274bf85bf0 27 const std::string LIFETIME ="&lt=";
pnysten 4:5e274bf85bf0 28 const std::string BINDING ="&b=";
pnysten 4:5e274bf85bf0 29
pnysten 4:5e274bf85bf0 30 const std::string REGISTRATION_OPEN = "<";
pnysten 4:5e274bf85bf0 31 const std::string REGISTRATION_CLOSE = ">";
pnysten 4:5e274bf85bf0 32 const std::string REGISTRATION_SEPARATOR ="/";
pnysten 4:5e274bf85bf0 33
pnysten 4:5e274bf85bf0 34 int _node_Id=0;
pnysten 4:5e274bf85bf0 35
pnysten 4:5e274bf85bf0 36 const std::string endPoint_Name = "loraDevice";
pnysten 4:5e274bf85bf0 37 const int lifeTime = 300;
pnysten 4:5e274bf85bf0 38 const std::string binding = "U";
pnysten 4:5e274bf85bf0 39
pnysten 4:5e274bf85bf0 40 unsigned char * _payload;
pnysten 4:5e274bf85bf0 41 long _payload_size;
pnysten 4:5e274bf85bf0 42
mluis 0:a2929fa6e4f0 43 /*!
mluis 0:a2929fa6e4f0 44 * When set to 1 the application uses the Over-the-Air activation procedure
mluis 0:a2929fa6e4f0 45 * When set to 0 the application uses the Personalization activation procedure
mluis 0:a2929fa6e4f0 46 */
mluis 0:a2929fa6e4f0 47 #define OVER_THE_AIR_ACTIVATION 0
mluis 0:a2929fa6e4f0 48
mluis 1:60184eda0066 49 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 1:60184eda0066 50
mluis 1:60184eda0066 51 /*!
mluis 1:60184eda0066 52 * Defines the network ID when using personalization activation procedure
mluis 1:60184eda0066 53 */
mluis 1:60184eda0066 54 #define LORAWAN_NET_ID ( uint32_t )0x00000000
mluis 1:60184eda0066 55
mluis 1:60184eda0066 56 /*!
mluis 1:60184eda0066 57 * Defines the device address when using personalization activation procedure
mluis 1:60184eda0066 58 */
mluis 1:60184eda0066 59 #define LORAWAN_DEV_ADDR ( uint32_t )0x12345678
mluis 1:60184eda0066 60
mluis 1:60184eda0066 61 #endif
mluis 1:60184eda0066 62
mluis 1:60184eda0066 63 /*!
mluis 1:60184eda0066 64 * Defines the application data transmission duty cycle
mluis 1:60184eda0066 65 */
mluis 1:60184eda0066 66 #define APP_TX_DUTYCYCLE 5000 // 5 [s] value in ms
mluis 1:60184eda0066 67 #define APP_TX_DUTYCYCLE_RND 1000 // 1 [s] value in ms
mluis 1:60184eda0066 68
mluis 1:60184eda0066 69 /*!
mluis 1:60184eda0066 70 * LoRaWAN Adaptative Data Rate
mluis 1:60184eda0066 71 */
mluis 1:60184eda0066 72 #define LORAWAN_ADR_ON 1
mluis 1:60184eda0066 73
mluis 1:60184eda0066 74 /*!
mluis 1:60184eda0066 75 * LoRaWAN confirmed messages
mluis 1:60184eda0066 76 */
mluis 1:60184eda0066 77 #define LORAWAN_CONFIRMED_MSG_ON 1
mluis 1:60184eda0066 78
mluis 1:60184eda0066 79 /*!
mluis 1:60184eda0066 80 * LoRaWAN application port
mluis 1:60184eda0066 81 */
mluis 1:60184eda0066 82 #define LORAWAN_APP_PORT 15
mluis 1:60184eda0066 83
mluis 1:60184eda0066 84 /*!
mluis 1:60184eda0066 85 * User application data buffer size
mluis 1:60184eda0066 86 */
mluis 1:60184eda0066 87 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 1:60184eda0066 88 #define LORAWAN_APP_DATA_SIZE 6
mluis 1:60184eda0066 89
mluis 1:60184eda0066 90 #else
mluis 1:60184eda0066 91 #define LORAWAN_APP_DATA_SIZE 1
mluis 1:60184eda0066 92
mluis 1:60184eda0066 93 #endif
mluis 0:a2929fa6e4f0 94
pnysten 4:5e274bf85bf0 95 #define UINT16_MAX (65535U)
pnysten 4:5e274bf85bf0 96 #define UINT64_MAX (18446744073709551615ULL)
pnysten 4:5e274bf85bf0 97
pnysten 4:5e274bf85bf0 98
pnysten 4:5e274bf85bf0 99 std::string to_string( int x ) {
pnysten 4:5e274bf85bf0 100 int length = snprintf( NULL, 0, "%d", x );
pnysten 4:5e274bf85bf0 101 assert( length >= 0 );
pnysten 4:5e274bf85bf0 102 char* buf = new char[length + 1];
pnysten 4:5e274bf85bf0 103 snprintf( buf, length + 1, "%d", x );
pnysten 4:5e274bf85bf0 104 std::string str( buf );
pnysten 4:5e274bf85bf0 105 delete[] buf;
pnysten 4:5e274bf85bf0 106 return str;
pnysten 4:5e274bf85bf0 107 }
pnysten 4:5e274bf85bf0 108 unsigned char * get_Registration_Payload(long *payload_size){
pnysten 4:5e274bf85bf0 109
pnysten 4:5e274bf85bf0 110 string registration_Payload ="";
pnysten 4:5e274bf85bf0 111
pnysten 4:5e274bf85bf0 112 string s="";
pnysten 4:5e274bf85bf0 113
pnysten 4:5e274bf85bf0 114 s.append(REGISTRATION_OPEN);
pnysten 4:5e274bf85bf0 115 s.append(REGISTRATION_SEPARATOR);
pnysten 4:5e274bf85bf0 116 s.append("3/0/0");
pnysten 4:5e274bf85bf0 117 s.append(REGISTRATION_CLOSE);
pnysten 4:5e274bf85bf0 118 s.append(",");
pnysten 4:5e274bf85bf0 119 s.append(REGISTRATION_OPEN);
pnysten 4:5e274bf85bf0 120 s.append(REGISTRATION_SEPARATOR);
pnysten 4:5e274bf85bf0 121 s.append("3/0/1");
pnysten 4:5e274bf85bf0 122 s.append(REGISTRATION_CLOSE);
pnysten 4:5e274bf85bf0 123 s.append(",");
pnysten 4:5e274bf85bf0 124 s.append(REGISTRATION_OPEN);
pnysten 4:5e274bf85bf0 125 s.append(REGISTRATION_SEPARATOR);
pnysten 4:5e274bf85bf0 126 s.append("3/0/2");
pnysten 4:5e274bf85bf0 127 s.append(REGISTRATION_CLOSE);
pnysten 4:5e274bf85bf0 128
pnysten 4:5e274bf85bf0 129 registration_Payload.append(s);
pnysten 4:5e274bf85bf0 130
pnysten 4:5e274bf85bf0 131 unsigned char *c = new unsigned char[registration_Payload.size()+1];
pnysten 4:5e274bf85bf0 132 copy(registration_Payload.begin(),registration_Payload.end(),c);
pnysten 4:5e274bf85bf0 133 c[registration_Payload.size()]='\0';
pnysten 4:5e274bf85bf0 134 *payload_size=registration_Payload.size();
pnysten 4:5e274bf85bf0 135
pnysten 4:5e274bf85bf0 136 return c;
pnysten 4:5e274bf85bf0 137
pnysten 4:5e274bf85bf0 138 }
pnysten 4:5e274bf85bf0 139 uint8_t * get_Token(int * size){
pnysten 4:5e274bf85bf0 140 srand(time(0)+_node_Id);
pnysten 4:5e274bf85bf0 141 long test=0;
pnysten 4:5e274bf85bf0 142 bool exist=false;
pnysten 4:5e274bf85bf0 143
pnysten 4:5e274bf85bf0 144 do{
pnysten 4:5e274bf85bf0 145 test=(rand() % UINT64_MAX);
pnysten 4:5e274bf85bf0 146
pnysten 4:5e274bf85bf0 147 }while (exist==true);
pnysten 4:5e274bf85bf0 148 uint8_t ones = 0xFF;
pnysten 4:5e274bf85bf0 149 *size=1;
pnysten 4:5e274bf85bf0 150 for (int i=0; i<8; ++i) {
pnysten 4:5e274bf85bf0 151 if ( (test>>8*i & ones) =='\0' || i==8) {
pnysten 4:5e274bf85bf0 152 *size=i;
pnysten 4:5e274bf85bf0 153 break;
pnysten 4:5e274bf85bf0 154 }
pnysten 4:5e274bf85bf0 155 }
pnysten 4:5e274bf85bf0 156 uint8_t * token =new uint8_t[*size];
pnysten 4:5e274bf85bf0 157 for (int i=0; i<*size; ++i){
pnysten 4:5e274bf85bf0 158 token[*size-1-i]=test>>8*i & ones;
pnysten 4:5e274bf85bf0 159 }
pnysten 4:5e274bf85bf0 160 return token;
pnysten 4:5e274bf85bf0 161 }
pnysten 4:5e274bf85bf0 162
pnysten 4:5e274bf85bf0 163 uint16_t get_Message_ID(){
pnysten 4:5e274bf85bf0 164 srand(time(0)+_node_Id);
pnysten 4:5e274bf85bf0 165 int test=0;
pnysten 4:5e274bf85bf0 166 bool exist=false;
pnysten 4:5e274bf85bf0 167 do{
pnysten 4:5e274bf85bf0 168
pnysten 4:5e274bf85bf0 169 exist=false;
pnysten 4:5e274bf85bf0 170 test=(rand() % UINT16_MAX);
pnysten 4:5e274bf85bf0 171
pnysten 4:5e274bf85bf0 172 }while (exist==true);
pnysten 4:5e274bf85bf0 173
pnysten 4:5e274bf85bf0 174
pnysten 4:5e274bf85bf0 175 return (uint16_t) test;
pnysten 4:5e274bf85bf0 176
pnysten 4:5e274bf85bf0 177 }
pnysten 4:5e274bf85bf0 178
pnysten 4:5e274bf85bf0 179 char * get_Registration_Query(){
pnysten 4:5e274bf85bf0 180
pnysten 4:5e274bf85bf0 181 string buffer;
pnysten 4:5e274bf85bf0 182 buffer.append(REGISTRATION_SEGMENT);
pnysten 4:5e274bf85bf0 183 buffer.append(ENDPOINT_SEGMENT);
pnysten 4:5e274bf85bf0 184 buffer.append(endPoint_Name);
pnysten 4:5e274bf85bf0 185 buffer.append(LIFETIME);
pnysten 4:5e274bf85bf0 186 buffer.append(to_string(lifeTime));
pnysten 4:5e274bf85bf0 187 buffer.append(BINDING);
pnysten 4:5e274bf85bf0 188 buffer.append(binding);
pnysten 4:5e274bf85bf0 189
pnysten 4:5e274bf85bf0 190 char *c = new char[buffer.size()+1];
pnysten 4:5e274bf85bf0 191 copy(buffer.begin(),buffer.end(),c);
pnysten 4:5e274bf85bf0 192 c[buffer.size()]='\0';
pnysten 4:5e274bf85bf0 193 return c;
pnysten 4:5e274bf85bf0 194
pnysten 4:5e274bf85bf0 195
pnysten 4:5e274bf85bf0 196 }
pnysten 4:5e274bf85bf0 197
mluis 0:a2929fa6e4f0 198 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 199 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
mluis 0:a2929fa6e4f0 200 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 201
mluis 0:a2929fa6e4f0 202 // application router ID (LSBF)
mluis 1:60184eda0066 203 static const uint8_t AppEui[8] =
mluis 0:a2929fa6e4f0 204 {
mluis 1:60184eda0066 205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:a2929fa6e4f0 206 };
mluis 0:a2929fa6e4f0 207
mluis 0:a2929fa6e4f0 208 // unique device ID (LSBF)
mluis 0:a2929fa6e4f0 209 static const u1_t DevEui[8] =
mluis 0:a2929fa6e4f0 210 {
pnysten 4:5e274bf85bf0 211 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x02, 0x48
pnysten 4:5e274bf85bf0 212 // 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
pnysten 4:5e274bf85bf0 213 // 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x099, 0xF7
mluis 0:a2929fa6e4f0 214 };
mluis 0:a2929fa6e4f0 215
mluis 0:a2929fa6e4f0 216 // device-specific AES key (derived from device EUI)
mluis 1:60184eda0066 217 static const uint8_t DevKey[16] =
mluis 0:a2929fa6e4f0 218 {
mluis 1:60184eda0066 219 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
mluis 1:60184eda0066 220 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
mluis 0:a2929fa6e4f0 221 };
mluis 0:a2929fa6e4f0 222
mluis 1:60184eda0066 223 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 1:60184eda0066 224 // network session key
mluis 0:a2929fa6e4f0 225 static uint8_t NwkSKey[] =
mluis 0:a2929fa6e4f0 226 {
mluis 0:a2929fa6e4f0 227 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
mluis 0:a2929fa6e4f0 228 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
mluis 0:a2929fa6e4f0 229 };
mluis 0:a2929fa6e4f0 230
mluis 1:60184eda0066 231 // application session key
mluis 0:a2929fa6e4f0 232 static uint8_t ArtSKey[] =
mluis 0:a2929fa6e4f0 233 {
mluis 0:a2929fa6e4f0 234 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
mluis 0:a2929fa6e4f0 235 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
mluis 0:a2929fa6e4f0 236 };
mluis 0:a2929fa6e4f0 237
mluis 1:60184eda0066 238 #endif
mluis 1:60184eda0066 239
mluis 0:a2929fa6e4f0 240 // LEDs and Frame jobs
mluis 0:a2929fa6e4f0 241 osjob_t rxLedJob;
mluis 0:a2929fa6e4f0 242 osjob_t txLedJob;
mluis 0:a2929fa6e4f0 243 osjob_t sendFrameJob;
mluis 0:a2929fa6e4f0 244
mluis 1:60184eda0066 245 // LED state
mluis 0:a2929fa6e4f0 246 static bool AppLedStateOn = false;
mluis 0:a2929fa6e4f0 247
mluis 0:a2929fa6e4f0 248 //////////////////////////////////////////////////
mluis 1:60184eda0066 249 // Utility functions
mluis 1:60184eda0066 250 //////////////////////////////////////////////////
mluis 1:60184eda0066 251 /*!
mluis 1:60184eda0066 252 * \brief Computes a random number between min and max
mluis 1:60184eda0066 253 *
mluis 1:60184eda0066 254 * \param [IN] min range minimum value
mluis 1:60184eda0066 255 * \param [IN] max range maximum value
mluis 1:60184eda0066 256 * \retval random random value in range min..max
mluis 1:60184eda0066 257 */
mluis 1:60184eda0066 258 int32_t randr( int32_t min, int32_t max )
mluis 1:60184eda0066 259 {
mluis 1:60184eda0066 260 return ( int32_t )rand( ) % ( max - min + 1 ) + min;
mluis 1:60184eda0066 261 }
mluis 1:60184eda0066 262
mluis 1:60184eda0066 263 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 264 // APPLICATION CALLBACKS
mluis 0:a2929fa6e4f0 265 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 266
mluis 0:a2929fa6e4f0 267 // provide application router ID (8 bytes, LSBF)
mluis 1:60184eda0066 268 void os_getArtEui( uint8_t *buf )
mluis 0:a2929fa6e4f0 269 {
mluis 0:a2929fa6e4f0 270 memcpy( buf, AppEui, 8 );
mluis 0:a2929fa6e4f0 271 }
mluis 0:a2929fa6e4f0 272
mluis 0:a2929fa6e4f0 273 // provide device ID (8 bytes, LSBF)
mluis 1:60184eda0066 274 void os_getDevEui( uint8_t *buf )
mluis 0:a2929fa6e4f0 275 {
mluis 0:a2929fa6e4f0 276 memcpy( buf, DevEui, 8 );
mluis 0:a2929fa6e4f0 277 }
mluis 0:a2929fa6e4f0 278
mluis 0:a2929fa6e4f0 279 // provide device key (16 bytes)
mluis 1:60184eda0066 280 void os_getDevKey( uint8_t *buf )
mluis 0:a2929fa6e4f0 281 {
mluis 0:a2929fa6e4f0 282 memcpy( buf, DevKey, 16 );
mluis 0:a2929fa6e4f0 283 }
mluis 0:a2929fa6e4f0 284
mluis 0:a2929fa6e4f0 285 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 286 // MAIN - INITIALIZATION AND STARTUP
mluis 0:a2929fa6e4f0 287 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 288
mluis 0:a2929fa6e4f0 289 static void onRxLed( osjob_t* j )
mluis 0:a2929fa6e4f0 290 {
mluis 1:60184eda0066 291 debug_val("LED2 = ", 0 );
mluis 0:a2929fa6e4f0 292 }
mluis 0:a2929fa6e4f0 293
mluis 0:a2929fa6e4f0 294 static void onTxLed( osjob_t* j )
mluis 0:a2929fa6e4f0 295 {
mluis 1:60184eda0066 296 debug_val("LED1 = ", 0 );
mluis 0:a2929fa6e4f0 297 }
mluis 0:a2929fa6e4f0 298
mluis 0:a2929fa6e4f0 299 static void prepareTxFrame( void )
mluis 0:a2929fa6e4f0 300 {
mluis 0:a2929fa6e4f0 301 LMIC.frame[0] = AppLedStateOn;
mluis 1:60184eda0066 302 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 1:60184eda0066 303 LMIC.frame[1] = LMIC.seqnoDn >> 8;
mluis 1:60184eda0066 304 LMIC.frame[2] = LMIC.seqnoDn;
mluis 1:60184eda0066 305 LMIC.frame[3] = LMIC.rssi >> 8;
mluis 1:60184eda0066 306 LMIC.frame[4] = LMIC.rssi;
mluis 1:60184eda0066 307 LMIC.frame[5] = LMIC.snr;
mluis 1:60184eda0066 308 #endif
pnysten 4:5e274bf85bf0 309 /* debug_str("Frame to be sent: ");
pnysten 4:5e274bf85bf0 310 debug_val("1: ", LMIC.frame[0]);
pnysten 4:5e274bf85bf0 311 debug_val("2: ", LMIC.frame[1]);
pnysten 4:5e274bf85bf0 312 debug_val("3: ", LMIC.frame[2]);
pnysten 4:5e274bf85bf0 313 debug_val("4: ", LMIC.frame[3]);
pnysten 4:5e274bf85bf0 314 debug_val("5: ", LMIC.frame[4]);
pnysten 4:5e274bf85bf0 315 debug_val("6: ", LMIC.frame[5]);
pnysten 4:5e274bf85bf0 316 debug_str("\r\n");*/
mluis 0:a2929fa6e4f0 317 }
mluis 0:a2929fa6e4f0 318
mluis 0:a2929fa6e4f0 319 void processRxFrame( void )
mluis 0:a2929fa6e4f0 320 {
pnysten 4:5e274bf85bf0 321 debug_str("Data: ");
pnysten 4:5e274bf85bf0 322 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
pnysten 4:5e274bf85bf0 323 /* debug_str("Data - command: ");
pnysten 4:5e274bf85bf0 324 debug_hex(LMIC.frame[0]);
pnysten 4:5e274bf85bf0 325 debug_str("\r\n");*/
pnysten 4:5e274bf85bf0 326
mluis 0:a2929fa6e4f0 327 switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number
mluis 0:a2929fa6e4f0 328 {
pnysten 4:5e274bf85bf0 329 case 0:
pnysten 4:5e274bf85bf0 330 // debug_str("Port 0!!!\r\n");
pnysten 4:5e274bf85bf0 331 // debug_val("Data Len: ", LMIC.dataLen);
pnysten 4:5e274bf85bf0 332
mluis 0:a2929fa6e4f0 333 case 1: // The application LED can be controlled on port 1 or 2
mluis 0:a2929fa6e4f0 334 case 2:
mluis 0:a2929fa6e4f0 335 if( LMIC.dataLen == 1 )
mluis 0:a2929fa6e4f0 336 {
pnysten 4:5e274bf85bf0 337 debug_str("Data received on port 2: ");
pnysten 4:5e274bf85bf0 338 debug_hex(LMIC.frame[LMIC.dataBeg]);
pnysten 4:5e274bf85bf0 339 debug_str("\r\n");
mluis 0:a2929fa6e4f0 340 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
mluis 1:60184eda0066 341 debug_val( "LED3 = ", AppLedStateOn );
mluis 0:a2929fa6e4f0 342 }
mluis 0:a2929fa6e4f0 343 break;
mluis 0:a2929fa6e4f0 344 default:
mluis 0:a2929fa6e4f0 345 break;
mluis 0:a2929fa6e4f0 346 }
mluis 0:a2929fa6e4f0 347 }
mluis 0:a2929fa6e4f0 348
mluis 0:a2929fa6e4f0 349 static void onSendFrame( osjob_t* j )
mluis 0:a2929fa6e4f0 350 {
mluis 0:a2929fa6e4f0 351 prepareTxFrame( );
pnysten 4:5e274bf85bf0 352
pnysten 4:5e274bf85bf0 353 // Create Registration PDU :
pnysten 4:5e274bf85bf0 354
pnysten 4:5e274bf85bf0 355 CoapPDU *pdu = new CoapPDU();
pnysten 4:5e274bf85bf0 356
pnysten 4:5e274bf85bf0 357 pdu->setCode(CoapPDU::COAP_POST);
pnysten 4:5e274bf85bf0 358 pdu->setType(CoapPDU::COAP_CONFIRMABLE);
pnysten 4:5e274bf85bf0 359 int size;
pnysten 4:5e274bf85bf0 360 uint8_t * token = get_Token(&size);
pnysten 4:5e274bf85bf0 361 pdu->setToken(token,size);
pnysten 4:5e274bf85bf0 362 pdu->setMessageID(get_Message_ID());
pnysten 4:5e274bf85bf0 363 pdu->setURI(get_Registration_Query());
pnysten 4:5e274bf85bf0 364
pnysten 4:5e274bf85bf0 365 _payload=get_Registration_Payload(&_payload_size);
pnysten 4:5e274bf85bf0 366 pdu->setPayload(_payload, (int) _payload_size);
pnysten 4:5e274bf85bf0 367
pnysten 4:5e274bf85bf0 368 int PDUlength = pdu->getPDULength();
pnysten 4:5e274bf85bf0 369 u1_t frame[PDUlength+6];
pnysten 4:5e274bf85bf0 370
pnysten 4:5e274bf85bf0 371 memcpy(frame, pdu->getPDUPointer(), PDUlength * sizeof(uint8_t));
pnysten 4:5e274bf85bf0 372
pnysten 4:5e274bf85bf0 373 frame[PDUlength] = LMIC.seqnoDn >> 8;
pnysten 4:5e274bf85bf0 374 frame[PDUlength+1] = LMIC.seqnoDn;
pnysten 4:5e274bf85bf0 375 frame[PDUlength+2] = LMIC.rssi >> 8;
pnysten 4:5e274bf85bf0 376 frame[PDUlength+3] = LMIC.rssi;
pnysten 4:5e274bf85bf0 377 frame[PDUlength+4] = LMIC.snr;
pnysten 4:5e274bf85bf0 378 frame[PDUlength+5] = '\0';
pnysten 4:5e274bf85bf0 379 /* debug_str("Frame: ");
pnysten 4:5e274bf85bf0 380 debug_str(pdu->getPDUPointer());
pnysten 4:5e274bf85bf0 381 debug_str(" <STOP>\r\n");
pnysten 4:5e274bf85bf0 382
pnysten 4:5e274bf85bf0 383 debug_str("Frame: ");
pnysten 4:5e274bf85bf0 384 debug_str(frame);
pnysten 4:5e274bf85bf0 385 debug_str(" <STOP>\r\n");
pnysten 4:5e274bf85bf0 386 debug_val("Frame Length: ", PDUlength+5);*/
pnysten 4:5e274bf85bf0 387
pnysten 4:5e274bf85bf0 388 //LMIC_setTxData2( LORAWAN_APP_PORT, frame, PDUlength+6, LORAWAN_CONFIRMED_MSG_ON );
mluis 1:60184eda0066 389 LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON );
mluis 1:60184eda0066 390
mluis 1:60184eda0066 391 // Blink Tx LED
mluis 1:60184eda0066 392 debug_val( "LED1 = ", 1 );
mluis 1:60184eda0066 393 os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed );
mluis 0:a2929fa6e4f0 394 }
mluis 0:a2929fa6e4f0 395
mluis 1:60184eda0066 396 // Initialization job
mluis 1:60184eda0066 397 static void onInit( osjob_t* j )
mluis 1:60184eda0066 398 {
mluis 1:60184eda0066 399 // reset MAC state
mluis 1:60184eda0066 400 LMIC_reset( );
mluis 1:60184eda0066 401 LMIC_setAdrMode( LORAWAN_ADR_ON );
mluis 1:60184eda0066 402 LMIC_setDrTxpow( DR_SF12, 14 );
mluis 1:60184eda0066 403
mluis 1:60184eda0066 404 // start joining
mluis 1:60184eda0066 405 #if( OVER_THE_AIR_ACTIVATION != 0 )
mluis 1:60184eda0066 406 LMIC_startJoining( );
mluis 1:60184eda0066 407 #else
mluis 1:60184eda0066 408 LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey );
mluis 1:60184eda0066 409 onSendFrame( NULL );
mluis 1:60184eda0066 410 #endif
mluis 1:60184eda0066 411 // init done - onEvent( ) callback will be invoked...
mluis 1:60184eda0066 412 }
mluis 1:60184eda0066 413
mluis 1:60184eda0066 414 int main( void )
mluis 0:a2929fa6e4f0 415 {
pnysten 4:5e274bf85bf0 416 debug_init();
mluis 0:a2929fa6e4f0 417 osjob_t initjob;
mluis 0:a2929fa6e4f0 418
mluis 0:a2929fa6e4f0 419 // initialize runtime env
mluis 0:a2929fa6e4f0 420 os_init( );
mluis 0:a2929fa6e4f0 421 // setup initial job
mluis 0:a2929fa6e4f0 422 os_setCallback( &initjob, onInit );
mluis 0:a2929fa6e4f0 423 // execute scheduled jobs and events
mluis 0:a2929fa6e4f0 424 os_runloop( );
mluis 0:a2929fa6e4f0 425 // (not reached)
mluis 0:a2929fa6e4f0 426 }
mluis 0:a2929fa6e4f0 427
mluis 0:a2929fa6e4f0 428 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 429 // LMIC EVENT CALLBACK
mluis 0:a2929fa6e4f0 430 //////////////////////////////////////////////////
mluis 0:a2929fa6e4f0 431 void onEvent( ev_t ev )
mluis 0:a2929fa6e4f0 432 {
mluis 0:a2929fa6e4f0 433 bool txOn = false;
mluis 1:60184eda0066 434 debug_event( ev );
mluis 0:a2929fa6e4f0 435
mluis 0:a2929fa6e4f0 436 switch( ev )
mluis 0:a2929fa6e4f0 437 {
mluis 0:a2929fa6e4f0 438 // network joined, session established
mluis 0:a2929fa6e4f0 439 case EV_JOINED:
mluis 1:60184eda0066 440 debug_val( "Net ID = ", LMIC.netid );
mluis 0:a2929fa6e4f0 441 txOn = true;
mluis 0:a2929fa6e4f0 442 break;
mluis 0:a2929fa6e4f0 443 // scheduled data sent (optionally data received)
mluis 0:a2929fa6e4f0 444 case EV_TXCOMPLETE:
mluis 1:60184eda0066 445 debug_val( "Datarate = ", LMIC.datarate );
mluis 0:a2929fa6e4f0 446 // Check if we have a downlink on either Rx1 or Rx2 windows
mluis 1:60184eda0066 447 if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 )
mluis 0:a2929fa6e4f0 448 {
mluis 1:60184eda0066 449 debug_val( "LED2 = ", 1 );
mluis 1:60184eda0066 450 os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed );
mluis 0:a2929fa6e4f0 451
mluis 1:60184eda0066 452 if( LMIC.dataLen != 0 )
mluis 0:a2929fa6e4f0 453 { // data received in rx slot after tx
pnysten 4:5e274bf85bf0 454 //debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
mluis 0:a2929fa6e4f0 455 processRxFrame( );
mluis 0:a2929fa6e4f0 456 }
mluis 0:a2929fa6e4f0 457 }
mluis 0:a2929fa6e4f0 458 txOn = true;
mluis 0:a2929fa6e4f0 459 break;
mluis 0:a2929fa6e4f0 460 default:
mluis 0:a2929fa6e4f0 461 break;
mluis 0:a2929fa6e4f0 462 }
mluis 0:a2929fa6e4f0 463 if( txOn == true )
mluis 0:a2929fa6e4f0 464 {
mluis 1:60184eda0066 465 //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited)
mluis 1:60184eda0066 466 os_setTimedCallback( &sendFrameJob,
mluis 1:60184eda0066 467 os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ),
mluis 1:60184eda0066 468 onSendFrame );
mluis 0:a2929fa6e4f0 469
mluis 1:60184eda0066 470 ////Sends frame as soon as possible (duty cylce limitations)
mluis 1:60184eda0066 471 //onSendFrame( NULL );
mluis 0:a2929fa6e4f0 472 }
mluis 0:a2929fa6e4f0 473 }