Lora OTA device for Everynet

Dependencies:   LMiCLibOTADeviceEverynet SX1276Lib X_NUCLEO_IKS01A1 cantcoap lwip mbed-rtos mbed

Fork of LoRaWAN-test-10secs by Alcatel-Lucent IoT Development

Revision:
4:5e274bf85bf0
Parent:
3:ce28e3313a88
Child:
6:540c5d907c90
--- a/main.cpp	Thu Apr 16 20:00:01 2015 +0000
+++ b/main.cpp	Fri Nov 20 12:33:37 2015 +0000
@@ -12,11 +12,34 @@
 
 Maintainer: Miguel Luis and Gregory Cristian
 */
+#include <cstdio>
+#include <string>
+#include <cassert>
+
 #include "mbed.h"
+#include "cantcoap.h"
 
 #include "lmic.h"
 #include "debug.h"
 
+const std::string REGISTRATION_SEGMENT ="/rd";
+const std::string ENDPOINT_SEGMENT     = "?ep=";
+const std::string LIFETIME             ="&lt=";
+const std::string BINDING              ="&b=";
+
+const std::string REGISTRATION_OPEN  =    "<";
+const std::string REGISTRATION_CLOSE =    ">";
+const std::string REGISTRATION_SEPARATOR ="/";
+
+int _node_Id=0;
+
+const std::string endPoint_Name = "loraDevice"; 
+const int lifeTime = 300;
+const std::string binding = "U";
+
+unsigned char * _payload;
+long _payload_size;
+
 /*!
  * When set to 1 the application uses the Over-the-Air activation procedure
  * When set to 0 the application uses the Personalization activation procedure
@@ -69,6 +92,109 @@
 
 #endif
 
+#define UINT16_MAX (65535U)
+#define UINT64_MAX (18446744073709551615ULL)
+
+
+std::string to_string( int x ) {
+  int length = snprintf( NULL, 0, "%d", x );
+  assert( length >= 0 );
+  char* buf = new char[length + 1];
+  snprintf( buf, length + 1, "%d", x );
+  std::string str( buf );
+  delete[] buf;
+  return str;
+}
+unsigned char * get_Registration_Payload(long *payload_size){
+
+    string registration_Payload ="";
+
+    string s="";
+
+    s.append(REGISTRATION_OPEN);
+    s.append(REGISTRATION_SEPARATOR);
+    s.append("3/0/0");
+    s.append(REGISTRATION_CLOSE);
+    s.append(",");
+    s.append(REGISTRATION_OPEN);
+    s.append(REGISTRATION_SEPARATOR);
+    s.append("3/0/1");
+    s.append(REGISTRATION_CLOSE);
+    s.append(",");
+    s.append(REGISTRATION_OPEN);
+    s.append(REGISTRATION_SEPARATOR);
+    s.append("3/0/2");
+    s.append(REGISTRATION_CLOSE);
+
+    registration_Payload.append(s);
+    
+    unsigned char *c = new unsigned char[registration_Payload.size()+1];
+    copy(registration_Payload.begin(),registration_Payload.end(),c);
+    c[registration_Payload.size()]='\0';
+    *payload_size=registration_Payload.size();
+    
+    return c;
+
+}
+uint8_t * get_Token(int * size){
+    srand(time(0)+_node_Id);
+    long test=0;
+    bool exist=false;
+    
+    do{
+        test=(rand() % UINT64_MAX);
+        
+    }while (exist==true);
+    uint8_t ones = 0xFF;
+    *size=1;
+    for (int i=0; i<8; ++i) {
+        if ( (test>>8*i & ones) =='\0' || i==8) {
+            *size=i;
+            break;
+        }
+    }
+    uint8_t * token =new uint8_t[*size];
+    for (int i=0; i<*size; ++i){
+        token[*size-1-i]=test>>8*i & ones;
+    }
+    return token;
+}
+
+uint16_t get_Message_ID(){
+    srand(time(0)+_node_Id);
+    int test=0;
+    bool exist=false;
+    do{
+        
+        exist=false;
+        test=(rand() % UINT16_MAX);
+        
+    }while (exist==true);
+    
+    
+    return (uint16_t) test;
+    
+}
+
+char * get_Registration_Query(){
+    
+    string buffer;
+    buffer.append(REGISTRATION_SEGMENT);
+    buffer.append(ENDPOINT_SEGMENT);
+    buffer.append(endPoint_Name);
+    buffer.append(LIFETIME);
+    buffer.append(to_string(lifeTime));
+    buffer.append(BINDING);
+    buffer.append(binding);
+    
+    char *c = new char[buffer.size()+1];
+    copy(buffer.begin(),buffer.end(),c);
+    c[buffer.size()]='\0';
+    return c;
+    
+
+}
+
 //////////////////////////////////////////////////
 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
 //////////////////////////////////////////////////
@@ -82,7 +208,9 @@
 // unique device ID (LSBF)
 static const u1_t DevEui[8] =
 {
-    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x02, 0x48
+//    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
+//    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x099, 0xF7
 };
 
 // device-specific AES key (derived from device EUI)
@@ -178,16 +306,37 @@
     LMIC.frame[4] = LMIC.rssi;
     LMIC.frame[5] = LMIC.snr;
 #endif    
+/*    debug_str("Frame to be sent: ");
+    debug_val("1: ", LMIC.frame[0]);
+    debug_val("2: ", LMIC.frame[1]);
+    debug_val("3: ", LMIC.frame[2]);
+    debug_val("4: ", LMIC.frame[3]);
+    debug_val("5: ", LMIC.frame[4]);
+    debug_val("6: ", LMIC.frame[5]);
+    debug_str("\r\n");*/
 }
 
 void processRxFrame( void )
 {
+    debug_str("Data: ");
+    debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
+/*    debug_str("Data - command: ");
+    debug_hex(LMIC.frame[0]);
+    debug_str("\r\n");*/
+
     switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number
     {
+        case 0:
+//            debug_str("Port 0!!!\r\n");
+//            debug_val("Data Len: ", LMIC.dataLen);
+            
         case 1: // The application LED can be controlled on port 1 or 2
         case 2:
             if( LMIC.dataLen == 1 )
             {
+                debug_str("Data received on port 2: ");
+                debug_hex(LMIC.frame[LMIC.dataBeg]);
+                debug_str("\r\n");
                 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
                 debug_val( "LED3 = ", AppLedStateOn );
             }
@@ -200,6 +349,43 @@
 static void onSendFrame( osjob_t* j )
 {
     prepareTxFrame( );
+
+    // Create Registration PDU :
+    
+    CoapPDU *pdu = new CoapPDU();
+    
+    pdu->setCode(CoapPDU::COAP_POST);
+    pdu->setType(CoapPDU::COAP_CONFIRMABLE);
+    int size;
+    uint8_t * token = get_Token(&size);
+    pdu->setToken(token,size);
+    pdu->setMessageID(get_Message_ID());
+    pdu->setURI(get_Registration_Query());
+    
+    _payload=get_Registration_Payload(&_payload_size);
+    pdu->setPayload(_payload, (int) _payload_size);
+    
+    int PDUlength = pdu->getPDULength();
+    u1_t frame[PDUlength+6];
+    
+    memcpy(frame, pdu->getPDUPointer(), PDUlength * sizeof(uint8_t));
+
+    frame[PDUlength] = LMIC.seqnoDn >> 8;
+    frame[PDUlength+1] = LMIC.seqnoDn;
+    frame[PDUlength+2] = LMIC.rssi >> 8;
+    frame[PDUlength+3] = LMIC.rssi;
+    frame[PDUlength+4] = LMIC.snr;
+    frame[PDUlength+5] = '\0';
+    /* debug_str("Frame: ");
+    debug_str(pdu->getPDUPointer());
+    debug_str("  <STOP>\r\n");
+
+    debug_str("Frame: ");
+    debug_str(frame);
+    debug_str("  <STOP>\r\n");
+    debug_val("Frame Length: ", PDUlength+5);*/
+    
+    //LMIC_setTxData2( LORAWAN_APP_PORT, frame, PDUlength+6, LORAWAN_CONFIRMED_MSG_ON );
     LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON );
 
     // Blink Tx LED
@@ -227,6 +413,7 @@
 
 int main( void )
 {
+    debug_init();
     osjob_t initjob;
 
     // initialize runtime env
@@ -264,7 +451,7 @@
 
             if( LMIC.dataLen != 0 )
             { // data received in rx slot after tx
-                debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
+                //debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
                 processRxFrame( );
             }
         }