Adapted to LoRa Semtech + Nucleo
Dependencies: LMiC SX1276Lib cantcoap lwip mbed-rtos mbed
Fork of LoRaWAN-lmic-app by
Revision 4:5e274bf85bf0, committed 2015-11-20
- 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
--- 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 ="<="; +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