Adapted to LoRa Semtech + Nucleo

Dependents:   LoRaWAN-lmic-app LoRaWAN-lmic-app LoRaWAN-test-10secs LoRaPersonalizedDeviceForEverynet ... more

Fork of cantcoap by Ashley Mills

Files at this revision

API Documentation at this revision

Comitter:
pnysten
Date:
Fri Nov 20 12:30:26 2015 +0000
Parent:
1:5eec2844ad47
Commit message:
?

Changed in this revision

cantcoap.cpp Show annotated file Show diff for this revision Revisions of this file
cantcoap.h Show annotated file Show diff for this revision Revisions of this file
dbg.h Show annotated file Show diff for this revision Revisions of this file
diff -r 5eec2844ad47 -r d0d57af6c9df cantcoap.cpp
--- a/cantcoap.cpp	Thu Jan 30 14:07:56 2014 +0000
+++ b/cantcoap.cpp	Fri Nov 20 12:30:26 2015 +0000
@@ -35,29 +35,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+//#include <unistd.h>
 #include <string.h>
-#include <inet.h>
 #include "cantcoap.h"
-
-// for debugging output you need https://mbed.org/users/donatien/code/DebugLib/
-#define __DEBUG__ 3 // INFO
-#ifndef __MODULE__
-   #define __MODULE__ "cantcoap.cpp"
-#endif
-#include "dbg.h"
-// some extra debug stuff
-#if __DEBUG__ > 0
-   #define INFOX(...)  do { fprintf(stderr,__VA_ARGS__); } while(0)
-   #define INFOLX(...) do { fprintf(stderr,"[INFO] %s:%d ",__MODULE__,__LINE__); fprintf(stderr,__VA_ARGS__); } while(0) 
-   #define DBGLX(...)  do { fprintf(stderr,"[DBG] %s:%d ",__MODULE__,__LINE__); fprintf(stderr,__VA_ARGS__); } while(0)
-   #define DBG_PDU()   do { printBin(); } while(0)
-#else
-   #define INFOX(...)  do{} while(0)
-   #define INFOLX(...) do{} while(0)
-   #define DBGLX(...)  do{} while(0)
-   #define DBG_PDU()   do{} while(0)
-#endif
-
+#include "lwip/inet.h"
+#include "mbed.h"
+//#include <iostream>
 
 /// Memory-managed constructor. Buffer for PDU is dynamically sized and allocated by the object.
 /**
@@ -122,34 +105,8 @@
  * \sa CoapPDU::CoapPDU(), CoapPDU::CoapPDU(uint8_t *buffer, int bufferLength, int pduLength)
  */
 CoapPDU::CoapPDU(uint8_t *pdu, int pduLength) {
-    int bufferLength = pduLength;
-    // sanity
-	if(pduLength<4&&pduLength!=0) {
-		DBG("PDU cannot have a length less than 4");
-	}
-
-	// pdu
-	_pdu = pdu;
-	_bufferLength = bufferLength;
-	if(pduLength==0) {
-		// this is actually a fresh pdu, header always exists
-		_pduLength = 4;
-		// make sure header is zeroed
-		_pdu[0] = 0x00; _pdu[1] = 0x00; _pdu[2] = 0x00; _pdu[3] = 0x00;
-		setVersion(1);
-	} else {
-		_pduLength = pduLength;
-	}
-
-	_constructedFromBuffer = 1;
-
-	// options
-	_numOptions = 0;
-	_maxAddedOptionNumber = 0;
-
-	// payload
-	_payloadPointer = NULL;
-	_payloadLength = 0;
+	CoapPDU(pdu,pduLength,pduLength);
+	// delegated to CoapPDU::CoapPDU(uint8_t *buffer, int bufferLength, int pduLength)
 }
 
 /// Construct object from external buffer that may be larger than actual PDU.
@@ -298,7 +255,7 @@
 		(code>COAP_UNSUPPORTED_CONTENT_FORMAT&&code<COAP_INTERNAL_SERVER_ERROR) ||
 		(code>COAP_PROXYING_NOT_SUPPORTED) ) {
 		DBG("Invalid CoAP code: %d",code);
-		return 0;
+		//return 0;
 	}
 	DBG("CoAP code: %d",code);
 
@@ -452,28 +409,35 @@
  * Calls CoapPDU::setURI(uri,strlen(uri).
  */
 int CoapPDU::setURI(char *uri) {
-	return setURI(uri,strlen(uri));
+	return setURI(uri,(int)strlen(uri));
 }
 
 /// Shorthand function for setting a resource URI.
 /**
- * This will parse the supplied \b uri and construct enough URI_PATH CoAP options to encode it.
+ * This will parse the supplied \b uri and construct enough URI_PATH and URI_QUERY options to encode it.
  * The options are added to the PDU.
  * 
- * At present queries are not handled. TODO Implement queries.
+ * At present only simple URI formatting is handled, only '/','?', and '&' separators, and no port or protocol specificaiton.
+ *
+ * The function will split on '/' and create URI_PATH elements until it either reaches the end of the string
+ * in which case it will stop or if it reaches '?' it will start splitting on '&' and create URI_QUERY elements
+ * until it reaches the end of the string.
  *
- * \note This uses an internal buffer of 16 bytes to manipulate strings. The internal buffer will be
- * expanded dynamically if necessary (path component longer than 16 bytes). The internal buffer will
- * be freed before the function returns.
- * 
+ * Here is an example:
+ *
+ * /a/b/c/d?x=1&y=2&z=3
+ *
+ * Will be broken into four URI_PATH elements "a", "b", "c", "d", and three URI_QUERY elements "x=1", "y=2", "z=3"
+ *
+ * TODO: Add protocol extraction, port extraction, and some malformity checking.
+ *
  * \param uri The uri to parse.
  * \param urilen The length of the uri to parse.
  *
  * \return 1 on success, 0 on failure.
  */
 int CoapPDU::setURI(char *uri, int urilen) {
-	// only '/' and alphabetic chars allowed
-	// very simple splitting done
+	// only '/', '?', '&' and ascii chars allowed
 
 	// sanitation
 	if(urilen<=0||uri==NULL) {
@@ -487,67 +451,73 @@
 		return 0;
 	}
 
+	// TODO, queries
+	// extract ? to mark where to stop processing path components
+	// and then process the query params
+
 	// local vars
 	char *startP=uri,*endP=NULL;
-	int oLen = 0;
-	int bufSpace = 16;
-	char *uriBuf = (char*)malloc(bufSpace*sizeof(char));
-	if(uriBuf==NULL) {
-		DBG("Error allocating temporary memory.");
-		return 1;
-	}
-
+	long oLen = 0;
+	char splitChar = '/';
+	int queryStageTriggered = 0;
+	uint16_t optionType = COAP_OPTION_URI_PATH;
 	while(1) {
-		// stop at end of string
+		// stop at end of string or query
 		if(*startP==0x00||*(startP+1)==0x00) {
 			break;
 		}
 
 		// ignore leading slash
-		if(*startP=='/') {
+		if(*startP==splitChar) {
 			DBG("Skipping leading slash");
 			startP++;
 		}
 
 		// find next split point
-		endP = strchr(startP,'/');
+		endP = strchr(startP,splitChar);
 
 		// might not be another slash
 		if(endP==NULL) {
 			DBG("Ending out of slash");
-			endP = uri+urilen;
+			// check if there is a ?
+			endP = strchr(startP,'?');
+			// done if no queries
+			if(endP==NULL) {
+				endP = uri+urilen;
+			} else {
+				queryStageTriggered = 1;
+			}
 		}
 
 		// get length of segment
 		oLen = endP-startP;
 
-		// copy sequence, make space if necessary
-		if((oLen+1)>bufSpace) {
-			char *newBuf = (char*)realloc(uriBuf,oLen+1);
-			if(newBuf==NULL) {
-				DBG("Error making space for temporary buffer");
-				free(uriBuf);
-				return 1;
-			}
-			uriBuf = newBuf;
-		}
+		#ifdef DEBUG
+		char *b = (char*)malloc(oLen+1);
+		memcpy(b,startP,oLen);
+		b[oLen] = 0x00;
+		DBG("Adding URI_PATH %s",b);
+		free(b);
+		#endif
 
-		// copy into temporary buffer
-		memcpy(uriBuf,startP,oLen);
-		uriBuf[oLen] = 0x00;
-		DBG("Adding URI_PATH %s",uriBuf);
 		// add option
-		if(addOption(COAP_OPTION_URI_PATH,oLen,(uint8_t*)uriBuf)!=0) {
+		if(addOption(optionType,oLen,(uint8_t*)startP)!=0) {
 			DBG("Error adding option");
 			return 1;
 		}
 		startP = endP;
+
+		if(queryStageTriggered) {
+			splitChar = '&';
+			optionType = COAP_OPTION_URI_QUERY;
+			startP++;
+			queryStageTriggered = false;
+		}
 	}
 
-	// clean up
-	free(uriBuf);
 	return 0;
 }
+
 /// Shorthand for adding a URI QUERY to the option list.
 /**
  * Adds a new option to the CoAP PDU that encodes a URI_QUERY.
@@ -559,10 +529,12 @@
 	return addOption(COAP_OPTION_URI_QUERY,strlen(query),(uint8_t*)query);
 }
 
-/// Concatenates any URI_PATH elements into a single string.
+/// Concatenates any URI_PATH elements and URI_QUERY elements into a single string.
 /**
- * Parses the PDU options and extracts all URI_PATH elements, concatenating them into a single string with slash separators.
- * The produced string will be null terminated.
+ * Parses the PDU options and extracts all URI_PATH and URI_QUERY elements, 
+ * concatenating them into a single string with slash and amphersand separators accordingly.
+ * 
+ * The produced string will be NULL terminated.
  * 
  * \param dst Buffer into which to copy the concatenated path elements.
  * \param dstlen Length of buffer.
@@ -615,10 +587,24 @@
 		DBG("No space for initial slash needed 1, got %d",bytesLeft);
 		return 1;
 	}
+
+	char separator = '/';
+	int firstQuery = 1;
+
 	for(int i=0; i<_numOptions; i++) {
 		o = &options[i];
 		oLen = o->optionValueLength;
-		if(o->optionNumber==COAP_OPTION_URI_PATH) {
+		if(o->optionNumber==COAP_OPTION_URI_PATH||o->optionNumber==COAP_OPTION_URI_QUERY) {
+			// if the option is a query, change the separator to &
+			if(o->optionNumber==COAP_OPTION_URI_QUERY) {
+				if(firstQuery) {
+					// change previous '/' to a '?'
+					*(dst-1) = '?';
+					firstQuery = 0;
+				}
+				separator = '&';
+			}
+
 			// check space
 			if(oLen>bytesLeft) {
 				DBG("Destination buffer too small, needed %d, got %d",oLen,bytesLeft);
@@ -632,16 +618,16 @@
 				return 0;
 			}
 
-			// copy URI path component
+			// copy URI path or query component
 			memcpy(dst,o->optionValuePointer,oLen);
 
 			// adjust counters
 			dst += oLen;
 			bytesLeft -= oLen;
 
-			// add slash following (don't know at this point if another option is coming)
+			// add separator following (don't know at this point if another option is coming)
 			if(bytesLeft>=1) {
-				*dst = '/';
+				*dst = separator;
 				dst++;
 				bytesLeft--;
 			} else {
@@ -651,7 +637,7 @@
 		}
 	}
 
-	// remove terminating slash
+	// remove terminating separator
 	dst--;
 	bytesLeft++;
 	// add null terminating byte (always space since reserved)
@@ -821,6 +807,16 @@
 	return 0;
 }
 
+long CoapPDU::getLongToken(){
+
+    long token=0;
+    
+    for (int i=0; i<getTokenLength(); ++i) {
+        token+= getTokenPointer()[i]<<8*i;
+    }
+    return ntohl(token);
+}
+
 /// Sets the CoAP response code
 void CoapPDU::setCode(CoapPDU::Code code) {
 	_pdu[1] = code;
@@ -1211,6 +1207,7 @@
  * \param len Length of payload byte sequence.
  * \return 0 on success, 1 on failure.
  */
+
 int CoapPDU::setPayload(uint8_t *payload, int len) {
 	if(payload==NULL) {
 		DBG("NULL payload pointer.");
@@ -1229,6 +1226,8 @@
 	return 0;
 }
 
+
+
 /// Returns a pointer to the payload buffer.
 uint8_t* CoapPDU::getPayloadPointer() {
 	return _payloadPointer;
@@ -1563,205 +1562,203 @@
 
 /// Prints the PDU in human-readable format.
 void CoapPDU::printHuman() {
-	INFOX("__________________\r\n");
+	INFO("__________________");
 	if(_constructedFromBuffer) {
-		INFOX("PDU was constructed from buffer of %d bytes\r\n",_bufferLength);
+		INFO("PDU was constructed from buffer of %d bytes",_bufferLength);
 	}
-	INFOX("PDU is %d bytes long\r\n",_pduLength);
-	INFOX("CoAP Version: %d\r\n",getVersion());
+	INFO("PDU is %d bytes long",_pduLength);
+	INFO("CoAP Version: %d",getVersion());
 	INFOX("Message Type: ");
 	switch(getType()) {
 		case COAP_CONFIRMABLE:
-			INFOX("Confirmable\r\n");
+			INFO("Confirmable");
 		break;
 
 		case COAP_NON_CONFIRMABLE:
-			INFOX("Non-Confirmable\r\n");
+			INFO("Non-Confirmable");
 		break;
 
 		case COAP_ACKNOWLEDGEMENT:
-			INFOX("Acknowledgement\r\n");
+			INFO("Acknowledgement");
 		break;
 
 		case COAP_RESET:
-			INFOX("Reset\r\n");
+			INFO("Reset");
 		break;
 	}
-	INFOX("Token length: %d\r\n",getTokenLength());
+	INFO("Token length: %d",getTokenLength());
 	INFOX("Code: ");
 	switch(getCode()) {
 		case COAP_EMPTY:
-			INFOX("0.00 Empty");
+			INFO("0.00 Empty");
 		break;
 		case COAP_GET:
-			INFOX("0.01 GET");
+			INFO("0.01 GET");
 		break;
 		case COAP_POST:
-			INFOX("0.02 POST");
+			INFO("0.02 POST");
 		break;
 		case COAP_PUT:
-			INFOX("0.03 PUT");
+			INFO("0.03 PUT");
 		break;
 		case COAP_DELETE:
-			INFOX("0.04 DELETE");
+			INFO("0.04 DELETE");
 		break;
 		case COAP_CREATED:
-			INFOX("2.01 Created");
+			INFO("2.01 Created");
 		break;
 		case COAP_DELETED:
-			INFOX("2.02 Deleted");
+			INFO("2.02 Deleted");
 		break;
 		case COAP_VALID:
-			INFOX("2.03 Valid");
+			INFO("2.03 Valid");
 		break;
 		case COAP_CHANGED:
-			INFOX("2.04 Changed");
+			INFO("2.04 Changed");
 		break;
 		case COAP_CONTENT:
-			INFOX("2.05 Content");
+			INFO("2.05 Content");
 		break;
 		case COAP_BAD_REQUEST:
-			INFOX("4.00 Bad Request");
+			INFO("4.00 Bad Request");
 		break;
 		case COAP_UNAUTHORIZED:
-			INFOX("4.01 Unauthorized");
+			INFO("4.01 Unauthorized");
 		break;
 		case COAP_BAD_OPTION:
-			INFOX("4.02 Bad Option");
+			INFO("4.02 Bad Option");
 		break;
 		case COAP_FORBIDDEN:
-			INFOX("4.03 Forbidden");
+			INFO("4.03 Forbidden");
 		break;
 		case COAP_NOT_FOUND:
-			INFOX("4.04 Not Found");
+			INFO("4.04 Not Found");
 		break;
 		case COAP_METHOD_NOT_ALLOWED:
-			INFOX("4.05 Method Not Allowed");
+			INFO("4.05 Method Not Allowed");
 		break;
 		case COAP_NOT_ACCEPTABLE:
-			INFOX("4.06 Not Acceptable");
+			INFO("4.06 Not Acceptable");
 		break;
 		case COAP_PRECONDITION_FAILED:
-			INFOX("4.12 Precondition Failed");
+			INFO("4.12 Precondition Failed");
 		break;
 		case COAP_REQUEST_ENTITY_TOO_LARGE:
-			INFOX("4.13 Request Entity Too Large");
+			INFO("4.13 Request Entity Too Large");
 		break;
 		case COAP_UNSUPPORTED_CONTENT_FORMAT:
-			INFOX("4.15 Unsupported Content-Format");
+			INFO("4.15 Unsupported Content-Format");
 		break;
 		case COAP_INTERNAL_SERVER_ERROR:
-			INFOX("5.00 Internal Server Error");
+			INFO("5.00 Internal Server Error");
 		break;
 		case COAP_NOT_IMPLEMENTED:
-			INFOX("5.01 Not Implemented");
+			INFO("5.01 Not Implemented");
 		break;
 		case COAP_BAD_GATEWAY:
-			INFOX("5.02 Bad Gateway");
+			INFO("5.02 Bad Gateway");
 		break;
 		case COAP_SERVICE_UNAVAILABLE:
-			INFOX("5.03 Service Unavailable");
+			INFO("5.03 Service Unavailable");
 		break;
 		case COAP_GATEWAY_TIMEOUT:
-			INFOX("5.04 Gateway Timeout");
+			INFO("5.04 Gateway Timeout");
 		break;
 		case COAP_PROXYING_NOT_SUPPORTED:
-			INFOX("5.05 Proxying Not Supported");
+			INFO("5.05 Proxying Not Supported");
 		break;
 		case COAP_UNDEFINED_CODE:
-			INFOX("Undefined Code");
+			INFO("Undefined Code");
 		break;
 	}
-	INFOX("\r\n");
 
 	// print message ID
-	INFOX("Message ID: %u\r\n",getMessageID());
+	INFO("Message ID: %u",getMessageID());
 
 	// print token value
 	int tokenLength = getTokenLength();
 	uint8_t *tokenPointer = getPDUPointer()+COAP_HDR_SIZE;
 	if(tokenLength==0) {
-		INFOX("No token.\r\n");
+		INFO("No token.");
 	} else {
-		INFOX("Token of %d bytes.\r\n",tokenLength);
+		INFO("Token of %d bytes.",tokenLength);
 		INFOX("   Value: 0x");
 		for(int j=0; j<tokenLength; j++) {
 			INFOX("%.2x",tokenPointer[j]);
 		}
-		INFOX("\r\n");
+		INFO(" ");
 	}
 
 	// print options
 	CoapPDU::CoapOption* options = getOptions();
-	INFOX("%d options:\r\n",_numOptions);
+	INFO("%d options:",_numOptions);
 	for(int i=0; i<_numOptions; i++) {
-		INFOX("OPTION (%d/%d)\r\n",i,_numOptions);
-		INFOX("   Option number (delta): %hu (%hu)\r\n",options[i].optionNumber,options[i].optionDelta);
+		INFO("OPTION (%d/%d)",i + 1,_numOptions);
+		INFO("   Option number (delta): %hu (%hu)",options[i].optionNumber,options[i].optionDelta);
 		INFOX("   Name: ");
 		switch(options[i].optionNumber) {
 			case COAP_OPTION_IF_MATCH:
-				INFOX("IF_MATCH");
+				INFO("IF_MATCH");
 			break;
 			case COAP_OPTION_URI_HOST:
-				INFOX("URI_HOST");
+				INFO("URI_HOST");
 			break;
 			case COAP_OPTION_ETAG:
-				INFOX("ETAG");
+				INFO("ETAG");
 			break;
 			case COAP_OPTION_IF_NONE_MATCH:
-				INFOX("IF_NONE_MATCH");
+				INFO("IF_NONE_MATCH");
 			break;
 			case COAP_OPTION_OBSERVE:
-				INFOX("OBSERVE");
+				INFO("OBSERVE");
 			break;
 			case COAP_OPTION_URI_PORT:
-				INFOX("URI_PORT");
+				INFO("URI_PORT");
 			break;
 			case COAP_OPTION_LOCATION_PATH:
-				INFOX("LOCATION_PATH");
+				INFO("LOCATION_PATH");
 			break;
 			case COAP_OPTION_URI_PATH:
-				INFOX("URI_PATH");
+				INFO("URI_PATH");
 			break;
 			case COAP_OPTION_CONTENT_FORMAT:
-				INFOX("CONTENT_FORMAT");
+				INFO("CONTENT_FORMAT");
 			break;
 			case COAP_OPTION_MAX_AGE:
-				INFOX("MAX_AGE");
+				INFO("MAX_AGE");
 			break;
 			case COAP_OPTION_URI_QUERY:
-				INFOX("URI_QUERY");
+				INFO("URI_QUERY");
 			break;
 			case COAP_OPTION_ACCEPT:
-				INFOX("ACCEPT");
+				INFO("ACCEPT");
 			break;
 			case COAP_OPTION_LOCATION_QUERY:
-				INFOX("LOCATION_QUERY");
+				INFO("LOCATION_QUERY");
 			break;
 			case COAP_OPTION_PROXY_URI:
-				INFOX("PROXY_URI");
+				INFO("PROXY_URI");
 			break;
 			case COAP_OPTION_PROXY_SCHEME:
-				INFOX("PROXY_SCHEME");
+				INFO("PROXY_SCHEME");
 			break;
 			case COAP_OPTION_BLOCK1:
-				INFOX("BLOCK1");
+				INFO("BLOCK1");
 			break;
 			case COAP_OPTION_BLOCK2:
-				INFOX("BLOCK2");
+				INFO("BLOCK2");
 			break;
 			case COAP_OPTION_SIZE1:
-				INFOX("SIZE1");
+				INFO("SIZE1");
 			break;
 			case COAP_OPTION_SIZE2:
-				INFOX("SIZE2");
+				INFO("SIZE2");
 			break;
 			default:
-				INFOX("Unknown option");
+				INFO("Unknown option");
 			break;
 		}
-		INFOX("\r\n");
-		INFOX("   Value length: %u\r\n",options[i].optionValueLength);
+		INFO("   Value length: %u",options[i].optionValueLength);
 		INFOX("   Value: \"");
 		for(int j=0; j<options[i].optionValueLength; j++) {
 			char c = options[i].optionValuePointer[j];
@@ -1771,14 +1768,14 @@
 				INFOX("\\%.2d",c);
 			}
 		}
-		INFOX("\"\r\n");
+		INFO("\"");
 	}
 	
 	// print payload
 	if(_payloadLength==0) {
-		INFOX("No payload.\r\n");
+		INFO("No payload.");
 	} else {
-		INFOX("Payload of %d bytes\r\n",_payloadLength);
+		INFO("Payload of %d bytes",_payloadLength);
 		INFOX("   Value: \"");
 		for(int j=0; j<_payloadLength; j++) {
 			char c = _payloadPointer[j];
@@ -1788,9 +1785,9 @@
 				INFOX("\\%.2x",c);
 			}
 		}
-		INFO("\"\r\n");
+		INFO("\"");
 	}
-	INFOX("__________________\r\n");
+	INFO("__________________");
 }
 
 /// Prints the PDU as a c array (useful for debugging or hardcoding PDUs)
@@ -1812,7 +1809,7 @@
 	uint16_t optionValueLength = getOptionValueLength(option);
 	int extraDeltaBytes = computeExtraBytes(optionDelta);
 	int extraValueLengthBytes = computeExtraBytes(optionValueLength);
-	int totalLength = 1+extraDeltaBytes+extraValueLengthBytes+optionValueLength;
+	long totalLength = 1+extraDeltaBytes+extraValueLengthBytes+optionValueLength;
 
 	if(totalLength>_pduLength) {
 		totalLength = &_pdu[_pduLength-1]-option;
@@ -1911,4 +1908,4 @@
 /// Dumps the PDU as a byte sequence to stdout.
 void CoapPDU::print() {
 	fwrite(_pdu,1,_pduLength,stdout);
-}
\ No newline at end of file
+}
diff -r 5eec2844ad47 -r d0d57af6c9df cantcoap.h
--- a/cantcoap.h	Thu Jan 30 14:07:56 2014 +0000
+++ b/cantcoap.h	Fri Nov 20 12:30:26 2015 +0000
@@ -1,31 +1,12 @@
-/**
-Copyright (c) 2013, Ashley Mills.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met: 
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer. 
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution. 
+#pragma once
+#pragma clang diagnostic ignored "-Wdeprecated-writable-strings"
+#pragma clang diagnostic ignored "-Wconstant-logical-operand"
+#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#pragma once
-
+/// Copyright (c) 2013, Ashley Mills.
+//#include <unistd.h>
 #include <stdint.h>
+#include "dbg.h"
 
 #define COAP_HDR_SIZE 4
 #define COAP_OPTION_HDR_BYTE 1
@@ -150,6 +131,7 @@
 		int setTokenLength(uint8_t tokenLength);
 		int getTokenLength();
 		uint8_t* getTokenPointer();
+        long getLongToken();
 		int setToken(uint8_t *token, uint8_t tokenLength);
 
 		// message code
@@ -261,4 +243,4 @@
 #define COAP_CODE_SERVICE_UNAVAILABLE        0xA3
 #define COAP_CODE_GATEWAY_TIMEOUT            0xA4
 #define COAP_CODE_PROXYING_NOT_SUPPORTED     0xA5
-*/
\ No newline at end of file
+*/
diff -r 5eec2844ad47 -r d0d57af6c9df dbg.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbg.h	Fri Nov 20 12:30:26 2015 +0000
@@ -0,0 +1,23 @@
+#pragma once
+#include <stdio.h>
+
+#define DEBUG 1
+#undef DEBUG
+
+#define DBG_NEWLINE "\n"
+
+#define INFO(...) printf(__VA_ARGS__); printf(DBG_NEWLINE);
+#define INFOX(...); printf(__VA_ARGS__);
+#define ERR(...) printf(__VA_ARGS__); printf(DBG_NEWLINE);
+
+#ifdef DEBUG
+    #define DBG(...) fprintf(stderr,"%s:%d ",__FILE__,__LINE__); fprintf(stderr,__VA_ARGS__); fprintf(stderr,"\r\n");
+    #define DBGX(...) fprintf(stderr,__VA_ARGS__);
+    #define DBGLX(...) fprintf(stderr,"%s:%d ",__FILE__,__LINE__); fprintf(stderr,__VA_ARGS__);
+    #define DBG_PDU() printBin();
+#else
+    #define DBG(...) {};
+    #define DBGX(...) {};
+    #define DBGLX(...) {};
+    #define DBG_PDU() {};
+#endif