Adapted to LoRa Semtech + Nucleo

Dependencies:   LMiC SX1276Lib cantcoap lwip mbed-rtos mbed

Fork of LoRaWAN-lmic-app by Pascal Nysten

Files at this revision

API Documentation at this revision

Comitter:
pnysten
Date:
Fri Nov 20 12:33:37 2015 +0000
Parent:
3:ce28e3313a88
Child:
5:97b629581096
Commit message:
Adapted to LoRa Semtech + Nucleo

Changed in this revision

LMiC.lib Show annotated file Show diff for this revision Revisions of this file
cantcoap.lib Show annotated file Show diff for this revision Revisions of this file
core/IOStream.h Show annotated file Show diff for this revision Revisions of this file
core/MtxCircBuffer.h Show annotated file Show diff for this revision Revisions of this file
core/config.h Show annotated file Show diff for this revision Revisions of this file
core/errors.h Show annotated file Show diff for this revision Revisions of this file
core/fwk.h Show annotated file Show diff for this revision Revisions of this file
debug.cpp Show annotated file Show diff for this revision Revisions of this file
debug.h Show annotated file Show diff for this revision Revisions of this file
lwip.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
--- a/LMiC.lib	Thu Apr 16 20:00:01 2015 +0000
+++ b/LMiC.lib	Fri Nov 20 12:33:37 2015 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/teams/Semtech/code/LMiC/#d3b7bde3995c
+https://developer.mbed.org/users/pnysten/code/LMiC/#bebd6b2e3d18
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cantcoap.lib	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/pnysten/code/cantcoap/#d0d57af6c9df
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/IOStream.h	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,65 @@
+/* IOStream.h */
+/*
+Copyright (C) 2011 ARM Limited.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef IOSTREAM_H_
+#define IOSTREAM_H_
+
+#include "fwk.h"
+
+#include "rtos.h"
+
+class IStream
+{
+public:
+  //IStream();
+  //virtual ~IStream();
+
+	//0 for non-blocking (returns immediately), osWaitForever for infinite blocking
+	virtual int read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout=osWaitForever) = 0;
+	virtual size_t available() = 0;
+	virtual int waitAvailable(uint32_t timeout=osWaitForever) = 0; //Wait for data to be available
+	virtual int abortRead() = 0; //Abort current reading (or waiting) operation
+};
+
+class OStream
+{
+public:
+  //OStream();
+  //virtual ~OStream();
+
+	//0 for non-blocking (returns immediately), osWaitForever for infinite blocking
+	virtual int write(uint8_t* buf, size_t length, uint32_t timeout=osWaitForever) = 0;
+	virtual size_t space() = 0;
+	virtual int waitSpace(uint32_t timeout=osWaitForever) = 0; //Wait for space to be available
+	virtual int abortWrite() = 0; //Abort current writing (or waiting) operation
+};
+
+class IOStream : public IStream, public OStream
+{
+public:
+  //IOStream();
+  //virtual ~IOStream();
+};
+
+
+#endif /* IOSTREAM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/MtxCircBuffer.h	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,107 @@
+/* MtxCircBuf.h */
+/*
+ Copyright (C) 2012 ARM Limited.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal in
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ */
+
+#ifndef MTXCIRCBUFFER_H
+#define MTXCIRCBUFFER_H
+
+#include "fwk.h"
+
+#include "rtos.h"
+
+//Mutex protected circualr buffer
+template<typename T, int size>
+class MtxCircBuffer
+{
+public:
+  MtxCircBuffer() //:
+      //mtx()
+  {
+    write = 0;
+    read = 0;
+  }
+
+  bool isFull()
+  {
+    mtx.lock();
+    bool r = (((write + 1) % size) == read);
+    mtx.unlock();
+    return r;
+  }
+
+  bool isEmpty()
+  {
+    mtx.lock();
+    bool r = (read == write);
+    mtx.unlock();
+    return r;
+  }
+
+  void queue(T k)
+  {
+    mtx.lock();
+    while (((write + 1) % size) == read) //if (isFull())
+    {
+      /*while((((write + 1) % size) == read))
+      {*/
+        mtx.unlock();
+        Thread::wait(10);
+        mtx.lock();
+      /*}*/
+      //read++;
+      //read %= size;
+    }
+    buf[write++] = k;
+    write %= size;
+    mtx.unlock();
+  }
+
+  uint16_t available()
+  {
+    mtx.lock();
+    uint16_t a = (write >= read) ? (write - read) : (size - read + write);
+    mtx.unlock();
+    return a;
+  }
+
+  bool dequeue(T * c)
+  {
+    mtx.lock();
+    bool empty = (read == write);
+    if (!empty)
+    {
+      *c = buf[read++];
+      read %= size;
+    }
+    mtx.unlock();
+    return (!empty);
+  }
+
+private:
+  volatile uint16_t write;
+  volatile uint16_t read;
+  volatile T buf[size];
+  Mutex mtx;
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/config.h	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,32 @@
+/* config.H */
+/*
+Copyright (C) 2012 ARM Limited.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+
+//Configuration
+#define AT_THREAD_PRIORITY 0
+
+
+#endif /* CONFIG_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/errors.h	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,51 @@
+/* errors.h */
+/*
+Copyright (C) 2012 ARM Limited.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef ERRORS_H_
+#define ERRORS_H_
+
+/** \page Network-related errors */
+
+#define OK 0 //No error
+
+#define NET_FULL 1 //>All available resources are already used
+#define NET_EMPTY 2 //>No resource
+#define NET_NOTFOUND 3 //>Element cannot be found
+#define NET_INVALID 4 //>Invalid
+#define NET_CONTEXT 5 //>Called in a wrong context (eg during an interrupt)
+#define NET_TIMEOUT 6 //>Timeout
+#define NET_UNKNOWN 7 //>Unknown error
+#define NET_OVERFLOW 8 //>Overflow
+#define NET_PROCESSING 9 //>Command is processing
+#define NET_INTERRUPTED 10 //>Current operation has been interrupted
+#define NET_MOREINFO 11 //>More info on this error can be retrieved elsewhere (eg in a parameter passed as ptr)
+#define NET_ABORT 12 //>Current operation must be aborted
+#define NET_DIFF 13 //>Items that should match are different
+#define NET_AUTH 14 //>Authentication failed
+#define NET_PROTOCOL 15 //>Protocol error
+#define NET_OOM 16 //>Out of memory
+#define NET_CONN 17 //>Connection error
+#define NET_CLOSED 18 //>Connection was closed by remote end
+#define NET_TOOSMALL 19 //>Buffer is too small
+
+#endif /* ERRORS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/fwk.h	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,49 @@
+/*
+ * fwk.h
+ *
+ *  Created on: 15 d�c. 2011
+ *      Author: Donatien
+ */
+
+#ifndef FWK_H_
+#define FWK_H_
+
+#include "config.h"
+
+#include "string.h"
+//using namespace std;
+
+#include "stdint.h"
+typedef unsigned int size_t;
+
+#ifndef __cplusplus
+//boolean type compatibility
+typedef byte bool;
+#define true 1
+#define false 0
+#endif
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+#define CR '\x0D'
+#define LF '\x0A'
+#define GD '\x3E'
+#define BRK '\x1A'
+
+//Custom utility classes
+//#include "IOStream.h"
+//#include "String.h"
+
+//Error codes
+#include "errors.h"
+
+//Debug
+#include "dbg.h"
+
+//Utility macros
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MAX(x,y) (((x)>(y))?(x):(y))
+
+#endif /* FWK_H_ */
--- a/debug.cpp	Thu Apr 16 20:00:01 2015 +0000
+++ b/debug.cpp	Fri Nov 20 12:33:37 2015 +0000
@@ -13,23 +13,27 @@
 #include "lmic.h"
 #include "debug.h"
 
+#include "mbed.h"
+Serial pc(USBTX, USBRX);
+ 
 void debug_init () {
+    pc.baud(9600);
     // print banner
     debug_str("\r\n============== DEBUG STARTED ==============\r\n");
 }
-
+ 
 void debug_led (u1_t val) {
     debug_val( "LED = ", val );
 }
-
+ 
 void debug_char (u1_t c) {
-    fprintf(stderr, "%c", c );
+    pc.printf("%c", c );
 }
-
+ 
 void debug_hex (u1_t b) {
-    fprintf(stderr, "%02X", b );
+    pc.printf("%02X", b );
 }
-
+ 
 void debug_buf (const u1_t* buf, u2_t len) {
     while( len-- ) {
         debug_hex( *buf++ );
@@ -38,18 +42,32 @@
     debug_char( '\r' );
     debug_char( '\n' );
 }
-
+ 
 void debug_uint (u4_t v) {
     for( s1_t n = 24; n >= 0; n -= 8 ) {
         debug_hex( v >> n );
     }
 }
+ 
+void debug_str (const char* str) {
+    /*while( *str ) {
+        debug_char( *str++ );
+    }*/
+    pc.printf(str);
+}
 
 void debug_str (const u1_t* str) {
     while( *str ) {
         debug_char( *str++ );
     }
 }
+ 
+void debug_val (const char* label, u4_t val) {
+    debug_str( label );
+    debug_uint( val );
+    debug_char( '\r' );
+    debug_char( '\n' );
+}
 
 void debug_val (const u1_t* label, u4_t val) {
     debug_str( label );
@@ -57,9 +75,9 @@
     debug_char( '\r' );
     debug_char( '\n' );
 }
-
+ 
 void debug_event (int ev) {
-    static const u1_t* evnames[] = {
+    static const char* evnames[] = {
         [EV_SCAN_TIMEOUT]   = "SCAN_TIMEOUT",
         [EV_BEACON_FOUND]   = "BEACON_FOUND",
         [EV_BEACON_MISSED]  = "BEACON_MISSED",
@@ -79,4 +97,4 @@
     debug_str(evnames[ev]);
     debug_char('\r');
     debug_char('\n');
-}
+}
\ No newline at end of file
--- a/debug.h	Thu Apr 16 20:00:01 2015 +0000
+++ b/debug.h	Fri Nov 20 12:33:37 2015 +0000
@@ -7,10 +7,7 @@
  *
  * Contributors:
  *    IBM Zurich Research Lab - initial API, implementation and documentation
- *    Semtech Apps Team       - Adapted for MBED
  *******************************************************************************/
-#ifndef _debug_hpp_
-#define _debug_hpp_
 
 // intialize debug library
 void debug_init (void);
@@ -31,12 +28,12 @@
 void debug_uint (u4_t v);
 
 // write nul-terminated string to USART
+void debug_str (const char* str);
 void debug_str (const u1_t* str);
 
 // write LMiC event name to USART
 void debug_event (int ev);
 
 // write label and 32-bit value as hex to USART
+void debug_val (const char* label, u4_t val);
 void debug_val (const u1_t* label, u4_t val);
-
-#endif // _debug_hpp_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwip.lib	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/pnysten/code/lwip/#a9e6ba815945
--- 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( );
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Fri Nov 20 12:33:37 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/ST/code/mbed-rtos/#83895f30f8f2