Duy tran / Mbed OS iot_water_monitor_v2

Dependencies:   easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code

Files at this revision

API Documentation at this revision

Comitter:
DuyLionTran
Date:
Tue Dec 12 15:58:44 2017 +0000
Parent:
14:0129ac8844ee
Child:
16:a4118bfd7b41
Commit message:
version 1.6

Changed in this revision

MQTT.lib Show annotated file Show diff for this revision Revisions of this file
MQTT/FP.lib Show diff for this revision Revisions of this file
MQTT/MQTTAsync.h Show diff for this revision Revisions of this file
MQTT/MQTTClient.h Show diff for this revision Revisions of this file
MQTT/MQTTEthernet.h Show diff for this revision Revisions of this file
MQTT/MQTTLogging.h Show diff for this revision Revisions of this file
MQTT/MQTTPacket.lib Show diff for this revision Revisions of this file
MQTT/MQTTSocket.h Show diff for this revision Revisions of this file
MQTT/MQTTmbed.h Show diff for this revision Revisions of this file
NDefLib.lib Show annotated file Show diff for this revision Revisions of this file
NDefLib/Message.cpp Show diff for this revision Revisions of this file
NDefLib/Message.h Show diff for this revision Revisions of this file
NDefLib/NDefNfcTag.h Show diff for this revision Revisions of this file
NDefLib/Record.h Show diff for this revision Revisions of this file
NDefLib/RecordHeader.h Show diff for this revision Revisions of this file
NDefLib/RecordType.lib Show diff for this revision Revisions of this file
Sensor/ReadSensor.cpp Show annotated file Show diff for this revision Revisions of this file
Sensor/ReadSensor.h Show annotated file Show diff for this revision Revisions of this file
SimpleMQTT.cpp Show annotated file Show diff for this revision Revisions of this file
SimpleMQTT.h Show annotated file Show diff for this revision Revisions of this file
easy-connect.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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTT.lib	Tue Dec 12 15:58:44 2017 +0000
@@ -0,0 +1,1 @@
+MQTT#818366b014c9
--- a/MQTT/FP.lib	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/sam_grove/code/FP/#3c62ba1807ac
--- a/MQTT/MQTTAsync.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,607 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014 IBM Corp.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Eclipse Distribution License v1.0 which accompany this distribution.
- *
- * The Eclipse Public License is available at
- *    http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- *   http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *    Ian Craggs - initial API and implementation and/or initial documentation
- *******************************************************************************/
-
-#if !defined(MQTTASYNC_H)
-#define MQTTASYNC_H
-
-#include "FP.h"
-#include "MQTTPacket.h"
-#include "stdio.h"
-
-namespace MQTT
-{
-
-
-enum QoS { QOS0, QOS1, QOS2 };
-
-
-struct Message
-{
-    enum QoS qos;
-    bool retained;
-    bool dup;
-    unsigned short id;
-    void *payload;
-    size_t payloadlen;
-};
-
-
-class PacketId
-{
-public:
-    PacketId();
-    
-    int getNext();
-   
-private:
-    static const int MAX_PACKET_ID = 65535;
-    int next;
-};
-
-typedef void (*messageHandler)(Message*);
-
-typedef struct limits
-{
-	int MAX_MQTT_PACKET_SIZE; // 
-	int MAX_MESSAGE_HANDLERS;  // each subscription requires a message handler
-	int MAX_CONCURRENT_OPERATIONS;  // each command which runs concurrently can have a result handler, when we are in multi-threaded mode
-	int command_timeout_ms;
-		
-	limits()
-	{
-		MAX_MQTT_PACKET_SIZE = 100;
-		MAX_MESSAGE_HANDLERS = 5;
-		MAX_CONCURRENT_OPERATIONS = 1; // 1 indicates single-threaded mode - set to >1 for multithreaded mode
-		command_timeout_ms = 30000;
-	}
-} Limits;
-  
-
-/**
- * @class Async
- * @brief non-blocking, threaded MQTT client API
- * @param Network a network class which supports send, receive
- * @param Timer a timer class with the methods: 
- */ 
-template<class Network, class Timer, class Thread, class Mutex> class Async
-{
-    
-public:    
-
-	struct Result
-	{
-    	/* success or failure result data */
-    	Async<Network, Timer, Thread, Mutex>* client;
-		int rc;
-	};
-
-	typedef void (*resultHandler)(Result*);	
-   
-    Async(Network* network, const Limits limits = Limits()); 
-        
-    typedef struct
-    {
-        Async* client;
-        Network* network;
-    } connectionLostInfo;
-    
-    typedef int (*connectionLostHandlers)(connectionLostInfo*);
-    
-    /** Set the connection lost callback - called whenever the connection is lost and we should be connected
-     *  @param clh - pointer to the callback function
-     */
-    void setConnectionLostHandler(connectionLostHandlers clh)
-    {
-        connectionLostHandler.attach(clh);
-    }
-    
-    /** Set the default message handling callback - used for any message which does not match a subscription message handler
-     *  @param mh - pointer to the callback function
-     */
-    void setDefaultMessageHandler(messageHandler mh)
-    {
-        defaultMessageHandler.attach(mh);
-    }
-           
-    int connect(resultHandler fn, MQTTPacket_connectData* options = 0);
-    
-     template<class T>
-    int connect(void(T::*method)(Result *), MQTTPacket_connectData* options = 0, T *item = 0);  // alternative to pass in pointer to member function
-        
-    int publish(resultHandler rh, const char* topic, Message* message);
-    
-    int subscribe(resultHandler rh, const char* topicFilter, enum QoS qos, messageHandler mh);
-    
-    int unsubscribe(resultHandler rh, const char* topicFilter);
-    
-    int disconnect(resultHandler rh);
-    
-private:
-
-    void run(void const *argument);
-    int cycle(int timeout);
-    int waitfor(int packet_type, Timer& atimer);
-	int keepalive();
-	int findFreeOperation();
-
-    int decodePacket(int* value, int timeout);
-    int readPacket(int timeout);
-    int sendPacket(int length, int timeout);
-	int deliverMessage(MQTTString* topic, Message* message);
-    
-    Thread* thread;
-    Network* ipstack;
-    
-    Limits limits;
-    
-    char* buf;  
-    char* readbuf;
-
-    Timer ping_timer, connect_timer;
-    unsigned int keepAliveInterval;
-	bool ping_outstanding;
-    
-    PacketId packetid;
-    
-    typedef FP<void, Result*> resultHandlerFP;    
-    resultHandlerFP connectHandler; 
-    
-    typedef FP<void, Message*> messageHandlerFP;
-    struct MessageHandlers
-    {
-    	const char* topic;
-    	messageHandlerFP fp;
-    } *messageHandlers;      // Message handlers are indexed by subscription topic
-    
-    // how many concurrent operations should we allow?  Each one will require a function pointer
-    struct Operations
-    {
-    	unsigned short id;
-    	resultHandlerFP fp;
-    	const char* topic;         // if this is a publish, store topic name in case republishing is required
-    	Message* message;    // for publish, 
-    	Timer timer;         // to check if the command has timed out
-    } *operations;           // result handlers are indexed by packet ids
-
-	static void threadfn(void* arg);
-	
-	messageHandlerFP defaultMessageHandler;
-    
-    typedef FP<int, connectionLostInfo*> connectionLostFP;
-    
-    connectionLostFP connectionLostHandler;
-    
-};
-
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> void MQTT::Async<Network, Timer, Thread, Mutex>::threadfn(void* arg)
-{
-    ((Async<Network, Timer, Thread, Mutex>*) arg)->run(NULL);
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> MQTT::Async<Network, Timer, Thread, Mutex>::Async(Network* network, Limits limits)  : limits(limits), packetid()
-{
-	this->thread = 0;
-	this->ipstack = network;
-	this->ping_timer = Timer();
-	this->ping_outstanding = 0;
-	   
-	// How to make these memory allocations portable?  I was hoping to avoid the heap
-	buf = new char[limits.MAX_MQTT_PACKET_SIZE];
-	readbuf = new char[limits.MAX_MQTT_PACKET_SIZE];
-	this->operations = new struct Operations[limits.MAX_CONCURRENT_OPERATIONS];
-	for (int i = 0; i < limits.MAX_CONCURRENT_OPERATIONS; ++i)
-		operations[i].id = 0;
-	this->messageHandlers = new struct MessageHandlers[limits.MAX_MESSAGE_HANDLERS];
-	for (int i = 0; i < limits.MAX_MESSAGE_HANDLERS; ++i)
-		messageHandlers[i].topic = 0;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::sendPacket(int length, int timeout)
-{
-    int sent = 0;
-    
-    while (sent < length)
-        sent += ipstack->write(&buf[sent], length, timeout);
-	if (sent == length)
-	    ping_timer.countdown(this->keepAliveInterval); // record the fact that we have successfully sent the packet    
-    return sent;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::decodePacket(int* value, int timeout)
-{
-    char c;
-    int multiplier = 1;
-    int len = 0;
-	const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
-
-    *value = 0;
-    do
-    {
-        int rc = MQTTPACKET_READ_ERROR;
-
-        if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
-        {
-            rc = MQTTPACKET_READ_ERROR; /* bad data */
-            goto exit;
-        }
-        rc = ipstack->read(&c, 1, timeout);
-        if (rc != 1)
-            goto exit;
-        *value += (c & 127) * multiplier;
-        multiplier *= 128;
-    } while ((c & 128) != 0);
-exit:
-    return len;
-}
-
-
-/**
- * If any read fails in this method, then we should disconnect from the network, as on reconnect
- * the packets can be retried. 
- * @param timeout the max time to wait for the packet read to complete, in milliseconds
- * @return the MQTT packet type, or -1 if none
- */
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::readPacket(int timeout) 
-{
-    int rc = -1;
-    MQTTHeader header = {0};
-    int len = 0;
-    int rem_len = 0;
-
-    /* 1. read the header byte.  This has the packet type in it */
-    if (ipstack->read(readbuf, 1, timeout) != 1)
-        goto exit;
-
-    len = 1;
-    /* 2. read the remaining length.  This is variable in itself */
-    decodePacket(&rem_len, timeout);
-    len += MQTTPacket_encode(readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
-
-    /* 3. read the rest of the buffer using a callback to supply the rest of the data */
-    if (ipstack->read(readbuf + len, rem_len, timeout) != rem_len)
-        goto exit;
-
-    header.byte = readbuf[0];
-    rc = header.bits.type;
-exit:
-    return rc;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::deliverMessage(MQTTString* topic, Message* message)
-{
-	int rc = -1;
-
-	// we have to find the right message handler - indexed by topic
-	for (int i = 0; i < limits.MAX_MESSAGE_HANDLERS; ++i)
-	{
-		if (messageHandlers[i].topic != 0 && MQTTPacket_equals(topic, (char*)messageHandlers[i].topic))
-		{
-			messageHandlers[i].fp(message);
-			rc = 0;
-			break;
-		}
-	}
-	
-	return rc;
-}
-
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::cycle(int timeout)
-{
-    /* get one piece of work off the wire and one pass through */
-
-    // read the socket, see what work is due
-    int packet_type = readPacket(timeout);
-    
-	int len, rc;
-    switch (packet_type)
-    {
-        case CONNACK:
-			if (this->thread)
-			{
-				Result res = {this, 0};
-            	if (MQTTDeserialize_connack(&res.rc, readbuf, limits.MAX_MQTT_PACKET_SIZE) == 1)
-                	;
-				connectHandler(&res);
-				connectHandler.detach(); // only invoke the callback once
-			}
-			break;
-        case PUBACK:
-        	if (this->thread)
-        		; //call resultHandler
-        case SUBACK:
-            break;
-        case PUBLISH:
-			MQTTString topicName;
-			Message msg;
-			rc = MQTTDeserialize_publish((int*)&msg.dup, (int*)&msg.qos, (int*)&msg.retained, (int*)&msg.id, &topicName,
-								 (char**)&msg.payload, (int*)&msg.payloadlen, readbuf, limits.MAX_MQTT_PACKET_SIZE);;
-			if (msg.qos == QOS0)
-				deliverMessage(&topicName, &msg);
-            break;
-        case PUBREC:
-   	        int type, dup, mypacketid;
-   	        if (MQTTDeserialize_ack(&type, &dup, &mypacketid, readbuf, limits.MAX_MQTT_PACKET_SIZE) == 1)
-   	            ; 
-   	        // must lock this access against the application thread, if we are multi-threaded
-			len = MQTTSerialize_ack(buf, limits.MAX_MQTT_PACKET_SIZE, PUBREL, 0, mypacketid);
-		    rc = sendPacket(len, timeout); // send the PUBREL packet
-			if (rc != len) 
-				goto exit; // there was a problem
-
-            break;
-        case PUBCOMP:
-            break;
-        case PINGRESP:
-			ping_outstanding = false;
-            break;
-    }
-	keepalive();
-exit:
-    return packet_type;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::keepalive()
-{
-	int rc = 0;
-
-	if (keepAliveInterval == 0)
-		goto exit;
-
-	if (ping_timer.expired())
-	{
-		if (ping_outstanding)
-			rc = -1;
-		else
-		{
-			int len = MQTTSerialize_pingreq(buf, limits.MAX_MQTT_PACKET_SIZE);
-			rc = sendPacket(len, 1000); // send the ping packet
-			if (rc != len) 
-				rc = -1; // indicate there's a problem
-			else
-				ping_outstanding = true;
-		}
-	}
-
-exit:
-	return rc;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> void MQTT::Async<Network, Timer, Thread, Mutex>::run(void const *argument)
-{
-	while (true)
-		cycle(ping_timer.left_ms());
-}
-
-
-// only used in single-threaded mode where one command at a time is in process
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::waitfor(int packet_type, Timer& atimer)
-{
-	int rc = -1;
-	
-	do
-    {
-		if (atimer.expired()) 
-			break; // we timed out
-	}
-	while ((rc = cycle(atimer.left_ms())) != packet_type);	
-	
-	return rc;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::connect(resultHandler resultHandler, MQTTPacket_connectData* options)
-{
-	connect_timer.countdown(limits.command_timeout_ms);
-
-    MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
-    if (options == 0)
-        options = &default_options; // set default options if none were supplied
-    
-    this->keepAliveInterval = options->keepAliveInterval;
-	ping_timer.countdown(this->keepAliveInterval);
-    int len = MQTTSerialize_connect(buf, limits.MAX_MQTT_PACKET_SIZE, options);
-    int rc = sendPacket(len, connect_timer.left_ms()); // send the connect packet
-	if (rc != len) 
-		goto exit; // there was a problem
-    
-    if (resultHandler == 0)     // wait until the connack is received 
-    {
-        // this will be a blocking call, wait for the connack
-		if (waitfor(CONNACK, connect_timer) == CONNACK)
-		{
-        	int connack_rc = -1;
-        	if (MQTTDeserialize_connack(&connack_rc, readbuf, limits.MAX_MQTT_PACKET_SIZE) == 1)
-	        	rc = connack_rc;
-	    }
-    }
-    else
-    {
-        // set connect response callback function
-        connectHandler.attach(resultHandler);
-        
-        // start background thread            
-        this->thread = new Thread((void (*)(void const *argument))&MQTT::Async<Network, Timer, Thread, Mutex>::threadfn, (void*)this);
-    }
-    
-exit:
-    return rc;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::findFreeOperation()
-{
-	int found = -1;
-	for (int i = 0; i < limits.MAX_CONCURRENT_OPERATIONS; ++i)
-	{
-		if (operations[i].id == 0)
-		{
-			found = i;
-			break;
-		}
-	}
-	return found;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::subscribe(resultHandler resultHandler, const char* topicFilter, enum QoS qos, messageHandler messageHandler)
-{
-	int index = 0;
-	if (this->thread)
-		index = findFreeOperation();	
-	Timer& atimer = operations[index].timer;
-	
-	atimer.countdown(limits.command_timeout_ms);
-    MQTTString topic = {(char*)topicFilter, 0, 0};
-    
-    int len = MQTTSerialize_subscribe(buf, limits.MAX_MQTT_PACKET_SIZE, 0, packetid.getNext(), 1, &topic, (int*)&qos);
-    int rc = sendPacket(len, atimer.left_ms()); // send the subscribe packet
-	if (rc != len) 
-		goto exit; // there was a problem
-    
-    /* wait for suback */
-    if (resultHandler == 0)
-    {
-        // this will block
-        if (waitfor(SUBACK, atimer) == SUBACK)
-        {
-            int count = 0, grantedQoS = -1, mypacketid;
-            if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, readbuf, limits.MAX_MQTT_PACKET_SIZE) == 1)
-                rc = grantedQoS; // 0, 1, 2 or 0x80 
-            if (rc != 0x80)
-            {
-            	for (int i = 0; i < limits.MAX_MESSAGE_HANDLERS; ++i)
-				{
-					if (messageHandlers[i].topic == 0)
-					{
-						messageHandlers[i].topic = topicFilter;
-						messageHandlers[i].fp.attach(messageHandler);
-						rc = 0;
-						break;
-					}
-				}
-            }
-        }
-    }
-    else
-    {
-        // set subscribe response callback function
-        
-    }
-    
-exit:
-    return rc;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::unsubscribe(resultHandler resultHandler, const char* topicFilter)
-{
-	int index = 0;
-	if (this->thread)
-		index = findFreeOperation();	
-	Timer& atimer = operations[index].timer;
-
-	atimer.countdown(limits.command_timeout_ms);
-    MQTTString topic = {(char*)topicFilter, 0, 0};
-    
-    int len = MQTTSerialize_unsubscribe(buf, limits.MAX_MQTT_PACKET_SIZE, 0, packetid.getNext(), 1, &topic);
-    int rc = sendPacket(len, atimer.left_ms()); // send the subscribe packet
-	if (rc != len) 
-		goto exit; // there was a problem
-    
-    // set unsubscribe response callback function
-        
-    
-exit:
-    return rc;
-}
-
-
-   
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::publish(resultHandler resultHandler, const char* topicName, Message* message)
-{
-	int index = 0;
-	if (this->thread)
-		index = findFreeOperation();	
-	Timer& atimer = operations[index].timer;
-
-	atimer.countdown(limits.command_timeout_ms);
-    MQTTString topic = {(char*)topicName, 0, 0};
-
-	if (message->qos == QOS1 || message->qos == QOS2)
-		message->id = packetid.getNext();
-    
-	int len = MQTTSerialize_publish(buf, limits.MAX_MQTT_PACKET_SIZE, 0, message->qos, message->retained, message->id, topic, (char*)message->payload, message->payloadlen);
-    int rc = sendPacket(len, atimer.left_ms()); // send the subscribe packet
-	if (rc != len) 
-		goto exit; // there was a problem
-    
-    /* wait for acks */
-    if (resultHandler == 0)
-    {
- 		if (message->qos == QOS1)
-		{
-	        if (waitfor(PUBACK, atimer) == PUBACK)
-    	    {
-    	        int type, dup, mypacketid;
-    	        if (MQTTDeserialize_ack(&type, &dup, &mypacketid, readbuf, limits.MAX_MQTT_PACKET_SIZE) == 1)
-    	            rc = 0; 
-    	    }
-		}
-		else if (message->qos == QOS2)
-		{
-	        if (waitfor(PUBCOMP, atimer) == PUBCOMP)
-	   	    {
-	   	    	int type, dup, mypacketid;
-            	if (MQTTDeserialize_ack(&type, &dup, &mypacketid, readbuf, limits.MAX_MQTT_PACKET_SIZE) == 1)
-    	           	rc = 0; 
-			}
-
-		}
-    }
-    else
-    {
-        // set publish response callback function
-        
-    }
-    
-exit:
-    return rc;
-}
-
-
-template<class Network, class Timer, class Thread, class Mutex> int MQTT::Async<Network, Timer, Thread, Mutex>::disconnect(resultHandler resultHandler)
-{  
-    Timer timer = Timer(limits.command_timeout_ms);     // we might wait for incomplete incoming publishes to complete
-    int len = MQTTSerialize_disconnect(buf, limits.MAX_MQTT_PACKET_SIZE);
-    int rc = sendPacket(len, timer.left_ms());   // send the disconnect packet
-    
-    return (rc == len) ? 0 : -1;
-}
-
-
-
-#endif
\ No newline at end of file
--- a/MQTT/MQTTClient.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1052 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014, 2017 IBM Corp.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Eclipse Distribution License v1.0 which accompany this distribution.
- *
- * The Eclipse Public License is available at
- *    http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- *   http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *    Ian Craggs - initial API and implementation and/or initial documentation
- *    Ian Craggs - fix for bug 458512 - QoS 2 messages
- *    Ian Craggs - fix for bug 460389 - send loop uses wrong length
- *    Ian Craggs - fix for bug 464169 - clearing subscriptions
- *    Ian Craggs - fix for bug 464551 - enums and ints can be different size
- *    Mark Sonnentag - fix for bug 475204 - inefficient instantiation of Timer
- *    Ian Craggs - fix for bug 475749 - packetid modified twice
- *    Ian Craggs - add ability to set message handler separately #6
- *******************************************************************************/
-
-#if !defined(MQTTCLIENT_H)
-#define MQTTCLIENT_H
-
-#include "FP.h"
-#include "MQTTPacket.h"
-#include <stdio.h>
-#include "MQTTLogging.h"
-
-#if !defined(MQTTCLIENT_QOS1)
-    #define MQTTCLIENT_QOS1 1
-#endif
-#if !defined(MQTTCLIENT_QOS2)
-    #define MQTTCLIENT_QOS2 0
-#endif
-
-namespace MQTT
-{
-
-
-enum QoS { QOS0, QOS1, QOS2 };
-
-// all failure return codes must be negative
-enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESS = 0 };
-
-
-struct Message
-{
-    enum QoS qos;
-    bool retained;
-    bool dup;
-    unsigned short id;
-    void *payload;
-    size_t payloadlen;
-};
-
-
-struct MessageData
-{
-    MessageData(MQTTString &aTopicName, struct Message &aMessage)  : message(aMessage), topicName(aTopicName)
-    { }
-
-    struct Message &message;
-    MQTTString &topicName;
-};
-
-
-struct connackData
-{
-    int rc;
-    bool sessionPresent;
-};
-
-
-struct subackData
-{
-    int grantedQoS;
-};
-
-
-class PacketId
-{
-public:
-    PacketId()
-    {
-        next = 0;
-    }
-
-    int getNext()
-    {
-        return next = (next == MAX_PACKET_ID) ? 1 : next + 1;
-    }
-
-private:
-    static const int MAX_PACKET_ID = 65535;
-    int next;
-};
-
-
-/**
- * @class Client
- * @brief blocking, non-threaded MQTT client API
- *
- * This version of the API blocks on all method calls, until they are complete.  This means that only one
- * MQTT request can be in process at any one time.
- * @param Network a network class which supports send, receive
- * @param Timer a timer class with the methods:
- */
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE = 100, int MAX_MESSAGE_HANDLERS = 5>
-class Client
-{
-
-public:
-
-    typedef void (*messageHandler)(MessageData&);
-
-    /** Construct the client
-     *  @param network - pointer to an instance of the Network class - must be connected to the endpoint
-     *      before calling MQTT connect
-     *  @param limits an instance of the Limit class - to alter limits as required
-     */
-    Client(Network& network, unsigned int command_timeout_ms = 30000);
-
-    /** Set the default message handling callback - used for any message which does not match a subscription message handler
-     *  @param mh - pointer to the callback function.  Set to 0 to remove.
-     */
-    void setDefaultMessageHandler(messageHandler mh)
-    {
-        if (mh != 0)
-            defaultMessageHandler.attach(mh);
-        else
-            defaultMessageHandler.detach();
-    }
-
-    /** Set a message handling callback.  This can be used outside of the the subscribe method.
-     *  @param topicFilter - a topic pattern which can include wildcards
-     *  @param mh - pointer to the callback function. If 0, removes the callback if any
-     */
-    int setMessageHandler(const char* topicFilter, messageHandler mh);
-
-    /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
-     *  The nework object must be connected to the network endpoint before calling this
-     *  Default connect options are used
-     *  @return success code -
-     */
-    int connect();
-
-    /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
-     *  The nework object must be connected to the network endpoint before calling this
-     *  @param options - connect options
-     *  @return success code -
-     */
-    int connect(MQTTPacket_connectData& options);
-
-    /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
-     *  The nework object must be connected to the network endpoint before calling this
-     *  @param options - connect options
-     *  @param connackData - connack data to be returned
-     *  @return success code -
-     */
-    int connect(MQTTPacket_connectData& options, connackData& data);
-
-    /** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs
-     *  @param topic - the topic to publish to
-     *  @param message - the message to send
-     *  @return success code -
-     */
-    int publish(const char* topicName, Message& message);
-
-    /** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs
-     *  @param topic - the topic to publish to
-     *  @param payload - the data to send
-     *  @param payloadlen - the length of the data
-     *  @param qos - the QoS to send the publish at
-     *  @param retained - whether the message should be retained
-     *  @return success code -
-     */
-    int publish(const char* topicName, void* payload, size_t payloadlen, enum QoS qos = QOS0, bool retained = false);
-
-    /** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs
-     *  @param topic - the topic to publish to
-     *  @param payload - the data to send
-     *  @param payloadlen - the length of the data
-     *  @param id - the packet id used - returned
-     *  @param qos - the QoS to send the publish at
-     *  @param retained - whether the message should be retained
-     *  @return success code -
-     */
-    int publish(const char* topicName, void* payload, size_t payloadlen, unsigned short& id, enum QoS qos = QOS1, bool retained = false);
-
-    /** MQTT Subscribe - send an MQTT subscribe packet and wait for the suback
-     *  @param topicFilter - a topic pattern which can include wildcards
-     *  @param qos - the MQTT QoS to subscribe at
-     *  @param mh - the callback function to be invoked when a message is received for this subscription
-     *  @return success code -
-     */
-    int subscribe(const char* topicFilter, enum QoS qos, messageHandler mh);
-
-    /** MQTT Subscribe - send an MQTT subscribe packet and wait for the suback
-     *  @param topicFilter - a topic pattern which can include wildcards
-     *  @param qos - the MQTT QoS to subscribe at©
-     *  @param mh - the callback function to be invoked when a message is received for this subscription
-     *  @param
-     *  @return success code -
-     */
-    int subscribe(const char* topicFilter, enum QoS qos, messageHandler mh, subackData &data);
-
-    /** MQTT Unsubscribe - send an MQTT unsubscribe packet and wait for the unsuback
-     *  @param topicFilter - a topic pattern which can include wildcards
-     *  @return success code -
-     */
-    int unsubscribe(const char* topicFilter);
-
-    /** MQTT Disconnect - send an MQTT disconnect packet, and clean up any state
-     *  @return success code -
-     */
-    int disconnect();
-
-    /** A call to this API must be made within the keepAlive interval to keep the MQTT connection alive
-     *  yield can be called if no other MQTT operation is needed.  This will also allow messages to be
-     *  received.
-     *  @param timeout_ms the time to wait, in milliseconds
-     *  @return success code - on failure, this means the client has disconnected
-     */
-    int yield(unsigned long timeout_ms = 1000L);
-
-    /** Is the client connected?
-     *  @return flag - is the client connected or not?
-     */
-    bool isConnected()
-    {
-        return isconnected;
-    }
-
-private:
-
-    void closeSession();
-    void cleanSession();
-    int cycle(Timer& timer);
-    int waitfor(int packet_type, Timer& timer);
-    int keepalive();
-    int publish(int len, Timer& timer, enum QoS qos);
-
-    int decodePacket(int* value, int timeout);
-    int readPacket(Timer& timer);
-    int sendPacket(int length, Timer& timer);
-    int deliverMessage(MQTTString& topicName, Message& message);
-    bool isTopicMatched(char* topicFilter, MQTTString& topicName);
-
-    Network& ipstack;
-    unsigned long command_timeout_ms;
-
-    unsigned char sendbuf[MAX_MQTT_PACKET_SIZE];
-    unsigned char readbuf[MAX_MQTT_PACKET_SIZE];
-
-    Timer last_sent, last_received;
-    unsigned int keepAliveInterval;
-    bool ping_outstanding;
-    bool cleansession;
-
-    PacketId packetid;
-
-    struct MessageHandlers
-    {
-        const char* topicFilter;
-        FP<void, MessageData&> fp;
-    } messageHandlers[MAX_MESSAGE_HANDLERS];      // Message handlers are indexed by subscription topic
-
-    FP<void, MessageData&> defaultMessageHandler;
-
-    bool isconnected;
-
-#if MQTTCLIENT_QOS1 || MQTTCLIENT_QOS2
-    unsigned char pubbuf[MAX_MQTT_PACKET_SIZE];  // store the last publish for sending on reconnect
-    int inflightLen;
-    unsigned short inflightMsgid;
-    enum QoS inflightQoS;
-#endif
-
-#if MQTTCLIENT_QOS2
-    bool pubrel;
-    #if !defined(MAX_INCOMING_QOS2_MESSAGES)
-        #define MAX_INCOMING_QOS2_MESSAGES 10
-    #endif
-    unsigned short incomingQoS2messages[MAX_INCOMING_QOS2_MESSAGES];
-    bool isQoS2msgidFree(unsigned short id);
-    bool useQoS2msgid(unsigned short id);
-    void freeQoS2msgid(unsigned short id);
-#endif
-
-};
-
-}
-
-
-template<class Network, class Timer, int a, int MAX_MESSAGE_HANDLERS>
-void MQTT::Client<Network, Timer, a, MAX_MESSAGE_HANDLERS>::cleanSession()
-{
-    for (int i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
-        messageHandlers[i].topicFilter = 0;
-
-#if MQTTCLIENT_QOS1 || MQTTCLIENT_QOS2
-    inflightMsgid = 0;
-    inflightQoS = QOS0;
-#endif
-
-#if MQTTCLIENT_QOS2
-    pubrel = false;
-    for (int i = 0; i < MAX_INCOMING_QOS2_MESSAGES; ++i)
-        incomingQoS2messages[i] = 0;
-#endif
-}
-
-
-template<class Network, class Timer, int a, int MAX_MESSAGE_HANDLERS>
-void MQTT::Client<Network, Timer, a, MAX_MESSAGE_HANDLERS>::closeSession()
-{
-    ping_outstanding = false;
-    isconnected = false;
-    if (cleansession)
-        cleanSession();
-}
-
-
-template<class Network, class Timer, int a, int MAX_MESSAGE_HANDLERS>
-MQTT::Client<Network, Timer, a, MAX_MESSAGE_HANDLERS>::Client(Network& network, unsigned int command_timeout_ms)  : ipstack(network), packetid()
-{
-    this->command_timeout_ms = command_timeout_ms;
-    cleansession = true;
-      closeSession();
-}
-
-
-#if MQTTCLIENT_QOS2
-template<class Network, class Timer, int a, int b>
-bool MQTT::Client<Network, Timer, a, b>::isQoS2msgidFree(unsigned short id)
-{
-    for (int i = 0; i < MAX_INCOMING_QOS2_MESSAGES; ++i)
-    {
-        if (incomingQoS2messages[i] == id)
-            return false;
-    }
-    return true;
-}
-
-
-template<class Network, class Timer, int a, int b>
-bool MQTT::Client<Network, Timer, a, b>::useQoS2msgid(unsigned short id)
-{
-    for (int i = 0; i < MAX_INCOMING_QOS2_MESSAGES; ++i)
-    {
-        if (incomingQoS2messages[i] == 0)
-        {
-            incomingQoS2messages[i] = id;
-            return true;
-        }
-    }
-    return false;
-}
-
-
-template<class Network, class Timer, int a, int b>
-void MQTT::Client<Network, Timer, a, b>::freeQoS2msgid(unsigned short id)
-{
-    for (int i = 0; i < MAX_INCOMING_QOS2_MESSAGES; ++i)
-    {
-        if (incomingQoS2messages[i] == id)
-        {
-            incomingQoS2messages[i] = 0;
-            return;
-        }
-    }
-}
-#endif
-
-
-template<class Network, class Timer, int a, int b>
-int MQTT::Client<Network, Timer, a, b>::sendPacket(int length, Timer& timer)
-{
-    int rc = FAILURE,
-        sent = 0;
-
-    while (sent < length)
-    {
-        rc = ipstack.write(&sendbuf[sent], length - sent, timer.left_ms());
-        if (rc < 0)  // there was an error writing the data
-            break;
-        sent += rc;
-        if (timer.expired()) // only check expiry after at least one attempt to write
-            break;
-    }
-    if (sent == length)
-    {
-        if (this->keepAliveInterval > 0)
-            last_sent.countdown(this->keepAliveInterval); // record the fact that we have successfully sent the packet
-        rc = SUCCESS;
-    }
-    else
-        rc = FAILURE;
-
-#if defined(MQTT_DEBUG)
-    char printbuf[150];
-    DEBUG("Rc %d from sending packet %s\r\n", rc, 
-        MQTTFormat_toServerString(printbuf, sizeof(printbuf), sendbuf, length));
-#endif
-    return rc;
-}
-
-
-template<class Network, class Timer, int a, int b>
-int MQTT::Client<Network, Timer, a, b>::decodePacket(int* value, int timeout)
-{
-    unsigned char c;
-    int multiplier = 1;
-    int len = 0;
-    const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
-
-    *value = 0;
-    do
-    {
-        int rc = MQTTPACKET_READ_ERROR;
-
-        if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
-        {
-            rc = MQTTPACKET_READ_ERROR; /* bad data */
-            goto exit;
-        }
-        rc = ipstack.read(&c, 1, timeout);
-        if (rc != 1)
-            goto exit;
-        *value += (c & 127) * multiplier;
-        multiplier *= 128;
-    } while ((c & 128) != 0);
-exit:
-    return len;
-}
-
-
-/**
- * If any read fails in this method, then we should disconnect from the network, as on reconnect
- * the packets can be retried.
- * @param timeout the max time to wait for the packet read to complete, in milliseconds
- * @return the MQTT packet type, 0 if none, -1 if error
- */
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::readPacket(Timer& timer)
-{
-    int rc = FAILURE;
-    MQTTHeader header = {0};
-    int len = 0;
-    int rem_len = 0;
-
-    /* 1. read the header byte.  This has the packet type in it */
-    rc = ipstack.read(readbuf, 1, timer.left_ms());
-    if (rc != 1)
-        goto exit;
-
-    len = 1;
-    /* 2. read the remaining length.  This is variable in itself */
-    decodePacket(&rem_len, timer.left_ms());
-    len += MQTTPacket_encode(readbuf + 1, rem_len); /* put the original remaining length into the buffer */
-
-    if (rem_len > (MAX_MQTT_PACKET_SIZE - len))
-    {
-        rc = BUFFER_OVERFLOW;
-        goto exit;
-    }
-
-    /* 3. read the rest of the buffer using a callback to supply the rest of the data */
-    if (rem_len > 0 && (ipstack.read(readbuf + len, rem_len, timer.left_ms()) != rem_len))
-        goto exit;
-
-    header.byte = readbuf[0];
-    rc = header.bits.type;
-    if (this->keepAliveInterval > 0)
-        last_received.countdown(this->keepAliveInterval); // record the fact that we have successfully received a packet
-exit:
-
-#if defined(MQTT_DEBUG)
-    if (rc >= 0)
-    {
-        char printbuf[50];
-        DEBUG("Rc %d receiving packet %s\r\n", rc, 
-            MQTTFormat_toClientString(printbuf, sizeof(printbuf), readbuf, len));
-    }
-#endif
-    return rc;
-}
-
-
-// assume topic filter and name is in correct format
-// # can only be at end
-// + and # can only be next to separator
-template<class Network, class Timer, int a, int b>
-bool MQTT::Client<Network, Timer, a, b>::isTopicMatched(char* topicFilter, MQTTString& topicName)
-{
-    char* curf = topicFilter;
-    char* curn = topicName.lenstring.data;
-    char* curn_end = curn + topicName.lenstring.len;
-
-    while (*curf && curn < curn_end)
-    {
-        if (*curn == '/' && *curf != '/')
-            break;
-        if (*curf != '+' && *curf != '#' && *curf != *curn)
-            break;
-        if (*curf == '+')
-        {   // skip until we meet the next separator, or end of string
-            char* nextpos = curn + 1;
-            while (nextpos < curn_end && *nextpos != '/')
-                nextpos = ++curn + 1;
-        }
-        else if (*curf == '#')
-            curn = curn_end - 1;    // skip until end of string
-        curf++;
-        curn++;
-    };
-
-    return (curn == curn_end) && (*curf == '\0');
-}
-
-
-
-template<class Network, class Timer, int a, int MAX_MESSAGE_HANDLERS>
-int MQTT::Client<Network, Timer, a, MAX_MESSAGE_HANDLERS>::deliverMessage(MQTTString& topicName, Message& message)
-{
-    int rc = FAILURE;
-
-    // we have to find the right message handler - indexed by topic
-    for (int i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
-    {
-        if (messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(&topicName, (char*)messageHandlers[i].topicFilter) ||
-                isTopicMatched((char*)messageHandlers[i].topicFilter, topicName)))
-        {
-            if (messageHandlers[i].fp.attached())
-            {
-                MessageData md(topicName, message);
-                messageHandlers[i].fp(md);
-                rc = SUCCESS;
-            }
-        }
-    }
-
-    if (rc == FAILURE && defaultMessageHandler.attached())
-    {
-        MessageData md(topicName, message);
-        defaultMessageHandler(md);
-        rc = SUCCESS;
-    }
-
-    return rc;
-}
-
-
-
-template<class Network, class Timer, int a, int b>
-int MQTT::Client<Network, Timer, a, b>::yield(unsigned long timeout_ms)
-{
-    int rc = SUCCESS;
-    Timer timer;
-
-    timer.countdown_ms(timeout_ms);
-    while (!timer.expired())
-    {
-        if (cycle(timer) < 0)
-        {
-            rc = FAILURE;
-            break;
-        }
-    }
-
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::cycle(Timer& timer)
-{
-    // get one piece of work off the wire and one pass through
-    int len = 0,
-        rc = SUCCESS;
-
-    int packet_type = readPacket(timer);    // read the socket, see what work is due
-
-    switch (packet_type)
-    {
-        default:
-            // no more data to read, unrecoverable. Or read packet fails due to unexpected network error
-            rc = packet_type;
-            goto exit;
-        case NSAPI_ERROR_WOULD_BLOCK:
-        case NSAPI_ERROR_OK: // timed out reading packet            
-            break;
-        case CONNACK:
-        case PUBACK:
-        case SUBACK:
-            break;
-        case PUBLISH:
-        {
-            MQTTString topicName = MQTTString_initializer;
-            Message msg;
-            int intQoS;
-            msg.payloadlen = 0; /* this is a size_t, but deserialize publish sets this as int */
-            if (MQTTDeserialize_publish((unsigned char*)&msg.dup, &intQoS, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName,
-                                 (unsigned char**)&msg.payload, (int*)&msg.payloadlen, readbuf, MAX_MQTT_PACKET_SIZE) != 1)
-                goto exit;
-            msg.qos = (enum QoS)intQoS;
-#if MQTTCLIENT_QOS2
-            if (msg.qos != QOS2)
-#endif
-                deliverMessage(topicName, msg);
-#if MQTTCLIENT_QOS2
-            else if (isQoS2msgidFree(msg.id))
-            {
-                if (useQoS2msgid(msg.id))
-                    deliverMessage(topicName, msg);
-                else
-                    WARN("Maximum number of incoming QoS2 messages exceeded");
-            }
-#endif
-#if MQTTCLIENT_QOS1 || MQTTCLIENT_QOS2
-            if (msg.qos != QOS0)
-            {
-                if (msg.qos == QOS1)
-                    len = MQTTSerialize_ack(sendbuf, MAX_MQTT_PACKET_SIZE, PUBACK, 0, msg.id);
-                else if (msg.qos == QOS2)
-                    len = MQTTSerialize_ack(sendbuf, MAX_MQTT_PACKET_SIZE, PUBREC, 0, msg.id);
-                if (len <= 0)
-                    rc = FAILURE;
-                else
-                    rc = sendPacket(len, timer);
-                if (rc == FAILURE)
-                    goto exit; // there was a problem
-            }
-            break;
-#endif
-        }
-#if MQTTCLIENT_QOS2
-        case PUBREC:
-        case PUBREL:
-            unsigned short mypacketid;
-            unsigned char dup, type;
-            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, readbuf, MAX_MQTT_PACKET_SIZE) != 1)
-                rc = FAILURE;
-            else if ((len = MQTTSerialize_ack(sendbuf, MAX_MQTT_PACKET_SIZE,
-                                 (packet_type == PUBREC) ? PUBREL : PUBCOMP, 0, mypacketid)) <= 0)
-                rc = FAILURE;
-            else if ((rc = sendPacket(len, timer)) != SUCCESS) // send the PUBREL packet
-                rc = FAILURE; // there was a problem
-            if (rc == FAILURE)
-                goto exit; // there was a problem
-            if (packet_type == PUBREL)
-                freeQoS2msgid(mypacketid);
-            break;
-
-        case PUBCOMP:
-            break;
-#endif
-        case PINGRESP:
-            ping_outstanding = false;
-            break;
-    }
-
-    if (keepalive() != SUCCESS)
-        //check only keepalive FAILURE status so that previous FAILURE status can be considered as FAULT
-        rc = FAILURE;
-
-exit:
-    if (rc == SUCCESS)
-        rc = packet_type;
-    else if (isconnected)
-        closeSession();
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::keepalive()
-{
-    int rc = SUCCESS;
-    static Timer ping_sent;
-
-    if (keepAliveInterval == 0)
-        goto exit;
-    
-    if (ping_outstanding)
-    {
-        if (ping_sent.expired())
-        {
-            rc = FAILURE; // session failure
-            #if defined(MQTT_DEBUG)
-                DEBUG("PINGRESP not received in keepalive interval\r\n");
-            #endif
-        }
-    }
-    else if (last_sent.expired() || last_received.expired())
-    {
-        Timer timer(1000);
-        int len = MQTTSerialize_pingreq(sendbuf, MAX_MQTT_PACKET_SIZE);
-        if (len > 0 && (rc = sendPacket(len, timer)) == SUCCESS) // send the ping packet
-        {
-            ping_outstanding = true;
-            ping_sent.countdown(this->keepAliveInterval);
-        }
-    }
-exit:
-    return rc;
-}
-
-
-// only used in single-threaded mode where one command at a time is in process
-template<class Network, class Timer, int a, int b>
-int MQTT::Client<Network, Timer, a, b>::waitfor(int packet_type, Timer& timer)
-{
-    int rc = FAILURE;
-
-    do
-    {
-        if (timer.expired())
-            break; // we timed out
-        rc = cycle(timer);
-    }
-    while (rc != packet_type && rc >= 0);
-
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::connect(MQTTPacket_connectData& options, connackData& data)
-{
-    Timer connect_timer(command_timeout_ms);
-    int rc = FAILURE;
-    int len = 0;
-
-    if (isconnected) // don't send connect packet again if we are already connected
-        goto exit;
-
-    this->keepAliveInterval = options.keepAliveInterval;
-    this->cleansession = options.cleansession;
-    if ((len = MQTTSerialize_connect(sendbuf, MAX_MQTT_PACKET_SIZE, &options)) <= 0)
-        goto exit;
-    if ((rc = sendPacket(len, connect_timer)) != SUCCESS)  // send the connect packet
-        goto exit; // there was a problem
-
-    if (this->keepAliveInterval > 0)
-        last_received.countdown(this->keepAliveInterval);
-    // this will be a blocking call, wait for the connack
-    if (waitfor(CONNACK, connect_timer) == CONNACK)
-    {
-        data.rc = 0;
-        data.sessionPresent = false;
-        if (MQTTDeserialize_connack((unsigned char*)&data.sessionPresent,
-                            (unsigned char*)&data.rc, readbuf, MAX_MQTT_PACKET_SIZE) == 1)
-            rc = data.rc;
-        else
-            rc = FAILURE;
-    }
-    else
-        rc = FAILURE;
-
-#if MQTTCLIENT_QOS2
-    // resend any inflight publish
-    if (inflightMsgid > 0 && inflightQoS == QOS2 && pubrel)
-    {
-        if ((len = MQTTSerialize_ack(sendbuf, MAX_MQTT_PACKET_SIZE, PUBREL, 0, inflightMsgid)) <= 0)
-            rc = FAILURE;
-        else
-            rc = publish(len, connect_timer, inflightQoS);
-    }
-    else
-#endif
-#if MQTTCLIENT_QOS1 || MQTTCLIENT_QOS2
-    if (inflightMsgid > 0)
-    {
-        memcpy(sendbuf, pubbuf, MAX_MQTT_PACKET_SIZE);
-        rc = publish(inflightLen, connect_timer, inflightQoS);
-    }
-#endif
-
-exit:
-    if (rc == SUCCESS)
-    {
-        isconnected = true;
-        ping_outstanding = false;
-    }
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::connect(MQTTPacket_connectData& options)
-{
-    connackData data;
-    return connect(options, data);
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::connect()
-{
-    MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
-    return connect(default_options);
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int MAX_MESSAGE_HANDLERS>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::setMessageHandler(const char* topicFilter, messageHandler messageHandler)
-{
-    int rc = FAILURE;
-    int i = -1;
-
-    // first check for an existing matching slot
-    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
-    {
-        if (messageHandlers[i].topicFilter != 0 && strcmp(messageHandlers[i].topicFilter, topicFilter) == 0)
-        {
-            if (messageHandler == 0) // remove existing
-            {
-                messageHandlers[i].topicFilter = 0;
-                messageHandlers[i].fp.detach();
-            }
-            rc = SUCCESS; // return i when adding new subscription
-            break;
-        }
-    }
-    // if no existing, look for empty slot (unless we are removing)
-    if (messageHandler != 0) {
-        if (rc == FAILURE)
-        {
-            for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
-            {
-                if (messageHandlers[i].topicFilter == 0)
-                {
-                    rc = SUCCESS;
-                    break;
-                }
-            }
-        }
-        if (i < MAX_MESSAGE_HANDLERS)
-        {
-            messageHandlers[i].topicFilter = topicFilter;
-            messageHandlers[i].fp.attach(messageHandler);
-        }
-    }
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int MAX_MESSAGE_HANDLERS>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::subscribe(const char* topicFilter,
-     enum QoS qos, messageHandler messageHandler, subackData& data)
-{
-    int rc = FAILURE;
-    Timer timer(command_timeout_ms);
-    int len = 0;
-    MQTTString topic = {(char*)topicFilter, {0, 0}};
-
-    if (!isconnected)
-        goto exit;
-
-    len = MQTTSerialize_subscribe(sendbuf, MAX_MQTT_PACKET_SIZE, 0, packetid.getNext(), 1, &topic, (int*)&qos);
-    if (len <= 0)
-        goto exit;
-    if ((rc = sendPacket(len, timer)) != SUCCESS) // send the subscribe packet
-        goto exit;             // there was a problem
-
-    if (waitfor(SUBACK, timer) == SUBACK)      // wait for suback
-    {
-        int count = 0;
-        unsigned short mypacketid;
-        data.grantedQoS = 0;
-        if (MQTTDeserialize_suback(&mypacketid, 1, &count, &data.grantedQoS, readbuf, MAX_MQTT_PACKET_SIZE) == 1)
-        {
-            if (data.grantedQoS != 0x80)
-                rc = setMessageHandler(topicFilter, messageHandler);
-        }
-    }
-    else
-        rc = FAILURE;
-
-exit:
-    if (rc == FAILURE)
-        closeSession();
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int MAX_MESSAGE_HANDLERS>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::subscribe(const char* topicFilter, enum QoS qos, messageHandler messageHandler)
-{
-    subackData data;
-    return subscribe(topicFilter, qos, messageHandler, data);
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int MAX_MESSAGE_HANDLERS>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::unsubscribe(const char* topicFilter)
-{
-    int rc = FAILURE;
-    Timer timer(command_timeout_ms);
-    MQTTString topic = {(char*)topicFilter, {0, 0}};
-    int len = 0;
-
-    if (!isconnected)
-        goto exit;
-
-    if ((len = MQTTSerialize_unsubscribe(sendbuf, MAX_MQTT_PACKET_SIZE, 0, packetid.getNext(), 1, &topic)) <= 0)
-        goto exit;
-    if ((rc = sendPacket(len, timer)) != SUCCESS) // send the unsubscribe packet
-        goto exit; // there was a problem
-
-    if (waitfor(UNSUBACK, timer) == UNSUBACK)
-    {
-        unsigned short mypacketid;  // should be the same as the packetid above
-        if (MQTTDeserialize_unsuback(&mypacketid, readbuf, MAX_MQTT_PACKET_SIZE) == 1)
-        {
-            // remove the subscription message handler associated with this topic, if there is one
-            setMessageHandler(topicFilter, 0);
-        }
-    }
-    else
-        rc = FAILURE;
-
-exit:
-    if (rc != SUCCESS)
-        closeSession();
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::publish(int len, Timer& timer, enum QoS qos)
-{
-    int rc;
-
-    if ((rc = sendPacket(len, timer)) != SUCCESS) // send the publish packet
-        goto exit; // there was a problem
-
-#if MQTTCLIENT_QOS1
-    if (qos == QOS1)
-    {
-        if (waitfor(PUBACK, timer) == PUBACK)
-        {
-            unsigned short mypacketid;
-            unsigned char dup, type;
-            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, readbuf, MAX_MQTT_PACKET_SIZE) != 1)
-                rc = FAILURE;
-            else if (inflightMsgid == mypacketid)
-                inflightMsgid = 0;
-        }
-        else
-            rc = FAILURE;
-    }
-#endif
-#if MQTTCLIENT_QOS2
-    else if (qos == QOS2)
-    {
-        if (waitfor(PUBCOMP, timer) == PUBCOMP)
-        {
-            unsigned short mypacketid;
-            unsigned char dup, type;
-            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, readbuf, MAX_MQTT_PACKET_SIZE) != 1)
-                rc = FAILURE;
-            else if (inflightMsgid == mypacketid)
-                inflightMsgid = 0;
-        }
-        else
-            rc = FAILURE;
-    }
-#endif
-
-exit:
-    if (rc != SUCCESS)
-        closeSession();
-    return rc;
-}
-
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::publish(const char* topicName, void* payload, size_t payloadlen, unsigned short& id, enum QoS qos, bool retained)
-{
-    int rc = FAILURE;
-    Timer timer(command_timeout_ms);
-    MQTTString topicString = MQTTString_initializer;
-    int len = 0;
-
-    if (!isconnected)
-        goto exit;
-
-    topicString.cstring = (char*)topicName;
-
-#if MQTTCLIENT_QOS1 || MQTTCLIENT_QOS2
-    if (qos == QOS1 || qos == QOS2)
-        id = packetid.getNext();
-#endif
-
-    len = MQTTSerialize_publish(sendbuf, MAX_MQTT_PACKET_SIZE, 0, qos, retained, id,
-              topicString, (unsigned char*)payload, payloadlen);
-    if (len <= 0)
-        goto exit;
-
-#if MQTTCLIENT_QOS1 || MQTTCLIENT_QOS2
-    if (!cleansession)
-    {
-        memcpy(pubbuf, sendbuf, len);
-        inflightMsgid = id;
-        inflightLen = len;
-        inflightQoS = qos;
-#if MQTTCLIENT_QOS2
-        pubrel = false;
-#endif
-    }
-#endif
-
-    rc = publish(len, timer, qos);
-exit:
-    return rc;
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::publish(const char* topicName, void* payload, size_t payloadlen, enum QoS qos, bool retained)
-{
-    unsigned short id = 0;  // dummy - not used for anything
-    return publish(topicName, payload, payloadlen, id, qos, retained);
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::publish(const char* topicName, Message& message)
-{
-    return publish(topicName, message.payload, message.payloadlen, message.qos, message.retained);
-}
-
-
-template<class Network, class Timer, int MAX_MQTT_PACKET_SIZE, int b>
-int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::disconnect()
-{
-    int rc = FAILURE;
-    Timer timer(command_timeout_ms);     // we might wait for incomplete incoming publishes to complete
-    int len = MQTTSerialize_disconnect(sendbuf, MAX_MQTT_PACKET_SIZE);
-    if (len > 0)
-        rc = sendPacket(len, timer);            // send the disconnect packet
-    closeSession();
-    return rc;
-}
-
-#endif
--- a/MQTT/MQTTEthernet.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-
-#if !defined(MQTTETHERNET_H)
-#define MQTTETHERNET_H
-
-#include "MQTTmbed.h"
-#include "EthernetInterface.h"
-#include "MQTTSocket.h"
-
-class MQTTEthernet : public MQTTSocket
-{
-public:    
-    MQTTEthernet() : MQTTSocket(&eth)
-    {
-        eth.connect();
-    }
-    
-    EthernetInterface& getEth()
-    {
-        return eth;
-    }
-    
-private:
-
-    EthernetInterface eth;
-    
-};
-
-
-#endif
--- a/MQTT/MQTTLogging.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#if !defined(MQTT_LOGGING_H)
-#define MQTT_LOGGING_H
-
-#define STREAM      stdout
-#if !defined(DEBUG)
-#define DEBUG(...)    \
-    {\
-    fprintf(STREAM, "DEBUG:   %s L#%d ", __PRETTY_FUNCTION__, __LINE__);  \
-    fprintf(STREAM, ##__VA_ARGS__); \
-    fflush(STREAM); \
-    }
-#endif
-#if !defined(LOG)
-#define LOG(...)    \
-    {\
-    fprintf(STREAM, "LOG:   %s L#%d ", __PRETTY_FUNCTION__, __LINE__);  \
-    fprintf(STREAM, ##__VA_ARGS__); \
-    fflush(STREAM); \
-    }
-#endif
-#if !defined(WARN)
-#define WARN(...)   \
-    { \
-    fprintf(STREAM, "WARN:  %s L#%d ", __PRETTY_FUNCTION__, __LINE__);  \
-    fprintf(STREAM, ##__VA_ARGS__); \
-    fflush(STREAM); \
-    }
-#endif 
-#if !defined(ERROR)
-#define ERROR(...)  \
-    { \
-    fprintf(STREAM, "ERROR: %s L#%d ", __PRETTY_FUNCTION__, __LINE__); \
-    fprintf(STREAM, ##__VA_ARGS__); \
-    fflush(STREAM); \
-    exit(1); \
-    }
-#endif
-
-#endif
\ No newline at end of file
--- a/MQTT/MQTTPacket.lib	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/teams/mqtt/code/MQTTPacket/#aedcaf7984d5
--- a/MQTT/MQTTSocket.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-#if !defined(MQTTSOCKET_H)
-#define MQTTSOCKET_H
-
-#include "MQTTmbed.h"
-#include <EthernetInterface.h>
-#include <Timer.h>
-
-class MQTTSocket
-{
-public:
-    MQTTSocket(EthernetInterface *anet)
-    {
-        net = anet;
-        open = false;
-    }
-    
-    int connect(char* hostname, int port, int timeout=1000)
-    {
-        if (open)
-            disconnect();
-        nsapi_error_t rc = mysock.open(net);
-        open = true;
-        mysock.set_blocking(true);
-        mysock.set_timeout((unsigned int)timeout);  
-        rc = mysock.connect(hostname, port);
-        mysock.set_blocking(false);  // blocking timeouts seem not to work
-        return rc;
-    }
-
-    // common read/write routine, avoiding blocking timeouts
-    int common(unsigned char* buffer, int len, int timeout, bool read)
-    {
-        timer.start();
-        mysock.set_blocking(false); // blocking timeouts seem not to work
-        int bytes = 0;
-        bool first = true;
-        do 
-        {
-            if (first)
-                first = false;
-            else
-                wait_ms(timeout < 100 ? timeout : 100);
-            int rc;
-            if (read)
-                rc = mysock.recv((char*)buffer, len);
-            else
-                rc = mysock.send((char*)buffer, len);
-            if (rc < 0)
-            {
-                if (rc != NSAPI_ERROR_WOULD_BLOCK)
-                {
-                    bytes = -1;
-                    break;
-                }
-            } 
-            else
-                bytes += rc;
-        }
-        while (bytes < len && timer.read_ms() < timeout);
-        timer.stop();
-        return bytes;
-    }
-
-    /* returns the number of bytes read, which could be 0.
-       -1 if there was an error on the socket
-    */
-    int read(unsigned char* buffer, int len, int timeout)
-    {
-        return common(buffer, len, timeout, true);
-    }
-
-    int write(unsigned char* buffer, int len, int timeout)
-    {
-        return common(buffer, len, timeout, false);
-    }
-
-    int disconnect()
-    {
-        open = false;
-        return mysock.close();
-    }
-
-    /*bool is_connected()
-    {
-        return mysock.is_connected();
-    }*/
-
-private:
-
-    bool open;
-    TCPSocket mysock;
-    EthernetInterface *net;
-    Timer timer;
-
-};
-
-#endif
--- a/MQTT/MQTTmbed.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#if !defined(MQTT_MBED_H)
-#define MQTT_MBED_H
-
-#include "mbed.h"
-
-class Countdown
-{
-public:
-    Countdown() : t()
-    {
-  
-    }
-    
-    Countdown(int ms) : t()
-    {
-        countdown_ms(ms);   
-    }
-    
-    
-    bool expired()
-    {
-        return t.read_ms() >= interval_end_ms;
-    }
-    
-    void countdown_ms(unsigned long ms)  
-    {
-        t.stop();
-        interval_end_ms = ms;
-        t.reset();
-        t.start();
-    }
-    
-    void countdown(int seconds)
-    {
-        countdown_ms((unsigned long)seconds * 1000L);
-    }
-    
-    int left_ms()
-    {
-        return interval_end_ms - t.read_ms();
-    }
-    
-private:
-    Timer t;
-    unsigned long interval_end_ms; 
-};
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NDefLib.lib	Tue Dec 12 15:58:44 2017 +0000
@@ -0,0 +1,1 @@
+NDefLib#6eb44b07d867
--- a/NDefLib/Message.cpp	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/**
- ******************************************************************************
- * @file    Message.cpp
- * @author  ST / Central Labs
- * @version V2.0.0
- * @date    28 Apr 2017
- * @brief   NDef Message class implementation
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * 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.
- *   3. Neither the name of STMicroelectronics nor the names of its contributors
- *      may be used to endorse or promote products derived from this software
- *      without specific prior written permission.
- *
- * 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-#include <cstdlib>
-#include "NDefLib/Message.h"
-#include "RecordType/EmptyRecord.h"
-#include "RecordType/RecordText.h"
-#include "RecordType/RecordAAR.h"
-#include "RecordType/RecordMimeType.h"
-#include "RecordType/RecordURI.h"
-
-namespace NDefLib {
-
-uint16_t Message::get_byte_length() const {
-	uint16_t lenght = 2; //length size
-
-	if (mRecords.size() == 0) {
-		return lenght + EmptyRecord().get_byte_length();
-	}
-
-	std::vector<Record*>::const_iterator it = mRecords.begin();
-	const std::vector<Record*>::const_iterator end = mRecords.end();
-
-	for (; it != end; ++it) {
-		lenght += (*it)->get_byte_length();
-	} //for
-
-	return lenght;
-} //getByteLenght
-
-uint16_t Message::write(uint8_t *buffer) const {
-
-	const uint16_t length = get_byte_length() - 2;
-	uint16_t offset = 0;
-	buffer[offset++] = (uint8_t) ((length & 0xFF00) >> 8);
-	buffer[offset++] = (uint8_t) ((length & 0x00FF));
-
-	const uint32_t nRecord = mRecords.size();
-
-	if (mRecords.size() == 0) {
-		offset += EmptyRecord().write(buffer + offset);
-		return offset;
-	} //else
-
-	for (uint32_t i = 0; i < nRecord; i++) {
-		Record *r = mRecords[i];
-
-		r->set_as_middle_record();
-		if (i == 0) {
-			r->set_as_first_record();
-		}
-		if (i == nRecord - 1) {
-			r->set_as_last_record();
-		}
-
-		offset += r->write(buffer + offset);
-	} //for
-
-	return offset;
-} //write
-
-void Message::parse_message(const uint8_t * const rawNdefFile, const uint16_t length, Message *msg) {
-	uint16_t offset = 0;
-	Record *r;
-
-	RecordHeader header;
-	do {
-		const uint8_t headerLenght = header.load_header(rawNdefFile + offset);
-		r = RecordText::parse(header, rawNdefFile + offset + headerLenght);
-		if (r == NULL) {
-			r = RecordAAR::parse(header, rawNdefFile + offset + headerLenght);
-		}
-		if (r == NULL) {
-			r = RecordMimeType::parse(header,
-			rawNdefFile + offset + headerLenght);
-		}
-		if (r == NULL) {
-			r = RecordURI::parse(header, rawNdefFile + offset + headerLenght);
-		}
-
-		offset += header.get_record_length();
-		msg->add_record(r);
-	} while (offset < length);
-}
-
-void Message::remove_and_delete_all_record(Message &msg){
-    const uint32_t nRecords =msg.get_N_records();
-	for (uint32_t i =0 ;i<nRecords ;i++) {
-        NDefLib::Record *r = msg[i];
-        delete r;
-    }//for
-    msg.mRecords.clear();
-}//removeAndDeleteAllRecord
-
-} /* namespace NDefLib */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
--- a/NDefLib/Message.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/**
- ******************************************************************************
- * @file    Message.h
- * @author  ST / Central Labs
- * @version V2.0.0
- * @date    28 Apr 2017
- * @brief   NDef Message class
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * 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.
- *   3. Neither the name of STMicroelectronics nor the names of its contributors
- *      may be used to endorse or promote products derived from this software
- *      without specific prior written permission.
- *
- * 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-#ifndef NDEFLIB_MESSAGE_H_
-#define NDEFLIB_MESSAGE_H_
-
-#include <algorithm>
-#include <vector>
-
-#include "Record.h"
-
-namespace NDefLib {
-
-/**
- * Class containing a list of {@link Record}
- */
-class Message {
-public:
-
-	/**
-	 * Add a ndef record to this message.
-	 * @param r Record to add
-	 */
-	void add_record(Record *r) {
-		mRecords.push_back(r);
-	}
-
-	/**
-	 * Remove a ndef record to this message
-	 * @param r record to remove 
-	 */
-	void remove_record(Record *r){
-		mRecords.erase( std::remove( mRecords.begin(), mRecords.end(), r ), mRecords.end() ); 
-	}
-	
-
-	/**
-	 * Add all the records in the list to this message.
-	 * @param addList List of records to add.
-	 */
-	void add_records(const std::vector<Record*> &addList) {
-		mRecords.insert(mRecords.end(), addList.begin(), addList.end());
-	}
-
-	/**
-	 * Get the specific record contained by this message, NULL if not a valid index.
-	 * @param index Record index.
-	 * @return a Record object if present, otherwise NULL
-	 */
-	Record* operator[](const uint32_t index)const{
-		if (index >= mRecords.size()) {
-			return NULL;
-		}
-
-		return mRecords[index];
-	}
-
-	/**
-	 * Get the number of records in this message.
-	 * @return number of records in this message
-	 */
-	uint32_t get_N_records() const {
-		return mRecords.size();
-	}
-
-	/**
-	 * Length in bytes needed to write this message.
-	 * @return number of bytes needed to write this message
-	 */
-	uint16_t get_byte_length() const;
-
-	/**
-	 * Write message in the provided buffer
-	 * @par The first 2 bytes contain the NDEF message length.
-	 * @param[out] buffer Buffer the message must be written into.
-	 * @return number of bytes written
-	 */
-	uint16_t write(uint8_t *buffer) const;
-
-	/**
-	 * Create a set of records from a raw buffer adding them to a message object.
-	 * @par Message buffer must NOT contain the buffer length in the first two bytes.
-	 * @param buffer Buffer containing the message record.
-	 * @param bufferLength Buffer length.
-	 * @param[in,out] Message message that will contain the new records.
-	 */
-	static void parse_message(const uint8_t * const buffer,
-		const uint16_t bufferLength, Message *message);
-
-	/**
-	 * Remove all the recrods from the mesasge and delete it 
-	 * @param msg Message with the records to delete
-	 */
-	static void remove_and_delete_all_record(Message &msg);
-
-	virtual ~Message() {
-	}
-
-private:
-	/**
-	 * List of records contained by this message.
-	 */
-	std::vector<Record*> mRecords;
-};
-
-} /* namespace NDefLib */
-
-#endif /* NDEFLIB_MESSAGE_H_ */
--- a/NDefLib/NDefNfcTag.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-/**
- ******************************************************************************
- * @file    NDefNfcTag.h
- * @author  ST / Central Labs
- * @version V2.0.0
- * @date    28 Apr 2017
- * @brief   Generic interface that a device must implement to use the NDefLib
- * with async communication
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * 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.
- *   3. Neither the name of STMicroelectronics nor the names of its contributors
- *      may be used to endorse or promote products derived from this software
- *      without specific prior written permission.
- *
- * 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-#ifndef NDEFLIB_NDEFNFCTAG_H_
-#define NDEFLIB_NDEFNFCTAG_H_
-
-#include "NDefLib/Message.h"
-
-namespace NDefLib {
-
-/**
- * Abstract class used to write/read NDef messages to/from a nfc tag.
- * This class is made to handle also asynchronous communication with the nfc component.
- * All the functions in this class will return immediately, when a command ends a proper callback function will
- * be called.
- */
-class NDefNfcTag {
-
-public:
-
-	/**
-	 * Class that contains all the function called when a command finished.
-	 * The default implementation is an empty function.
-	 */
-	class Callbacks {
-		public:
-
-			/**
-			 * Called when a session is open.
-			 * @param tag Tag where the session is open.
-			 * @param success True if the operation has success.
-			 */
-			virtual void on_session_open(NDefNfcTag *tag,bool success){
-				(void)tag;(void)success;
-			};
-
-			/**
-			 * Called when a message is written.
-			 * @param tag Tag where the message is written.
-			 * @param success True if the operation has success.
-			 */
-			virtual void on_message_write(NDefNfcTag *tag,bool success){
-				(void)tag;(void)success;
-
-			};
-
-			/**
-			 * Called when a message is read.
-			 * @param tag Tag where the message is read.
-			 * @param success True if the operation has success.
-			 */
-			virtual void on_message_read(NDefNfcTag *tag,bool success,
-					const Message *msg){
-				(void)tag;(void)success; (void)msg;
-			};
-
-
-			/**
-			 * Called when a session is closed.
-			 * @param tag Tag where the session is closed.
-			 * @param success True if the operation has success.
-			 */
-			virtual void on_session_close(NDefNfcTag *tag,bool success){
-				(void)tag;(void)success;
-			};
-
-			virtual ~Callbacks(){};
-	};
-
-private:
-
-	/**
-	 * Data used to store the callback status during a read/write operation.
-	 */
-	struct CallbackStatus{
-		
-		/** Object that triggers the callback */
-		NDefNfcTag *callOwner;
-		
-		/** Message that the callback is writing/reading */
-		Message *msg;
-	};
-
-public:
-
-	NDefNfcTag():mCallBack(&mDefaultCallBack){}
-
-	/**
-	 * Set the callback object.
-	 * @param c Object containing the callback.
-	 */
-	void set_callback(Callbacks *c){
-		if (c!=NULL) {
-			mCallBack=c;
-		} else {
-			mCallBack=&mDefaultCallBack;
-		}
-	}//setCallBack
-
-
-	/**
-	 * Open the communication session with the nfc tag.
-	 * @param force Force to open a communication.
-	 * @return true if success
-	 */
-	virtual bool open_session(bool force = false)=0;
-
-	/**
-	 * Close the communication with the nfc tag.
-	 * @return true if success
-	 */
-	virtual bool close_session()=0;
-
-	/**
-	 * Returns true if a communication with the nfc tag is open.
-	 * @return true if a communication with the nfc tag is open
-	 */
-	virtual bool is_session_open()=0;
-
-	/**
-	 * Write a message in the nfc tag.
-	 * @par This call will delete the previous message.
-	 * @param msg Message to write.
-	 * @return true if success
-	 */
-	virtual bool write(Message &msg) {
-		if (!is_session_open()) {
-			mCallBack->on_message_write(this,false);
-			return false;
-		}
-
-		const uint16_t length = msg.get_byte_length();
-		uint8_t *buffer = new uint8_t[length];
-		if (buffer==NULL){ //impossible to allocate the buffer
-			mCallBack->on_message_write(this,false);
-			return false;
-		}
-
-		msg.write(buffer);
-
-		mCallBackStatus.callOwner=this;
-		mCallBackStatus.msg=NULL;
-
-		return writeByte(buffer, length,0,NDefNfcTag::onWriteMessageCallback,&mCallBackStatus);
-	}
-
-	/**
-	 * Read a message from the tag.
-	 * @param[in,out] msg Message object the read records are added to.
-	 * @return true if success
-	 */
-	virtual bool read(Message *msg) {
-		if (!is_session_open()) {
-			mCallBack->on_message_read(this,false,msg);
-			return false;
-		}
-
-		uint8_t *buffer = new uint8_t[2];
-		if (buffer==NULL) {
-			mCallBack->on_message_read(this,false,msg);
-			return false;
-		}
-
-		mCallBackStatus.callOwner=this;
-		mCallBackStatus.msg=msg;
-		return readByte(0,2,buffer,NDefNfcTag::onReadMessageLength,&mCallBackStatus);
-	}
-
-	virtual ~NDefNfcTag() {}
-
-protected:
-
-	typedef struct CallbackStatus CallbackStatus_t;
-
-	/**
-	 * Function that the component will call when a read/write operation is completed
-	 * @param internalState Callback internal state data.
-	 * @param status True if the operation succeed.
-	 * @param buffer Buffer to read/write.
-	 * @param length Number of byte read/write.
-	 * @return true if the operation had success
-	 */
-	typedef bool(*byteOperationCallback_t)(CallbackStatus_t *internalState,
-		bool status,const uint8_t *buffer, uint16_t length);
-
-	/**
-	 * Write a sequence of bytes to the NDEF file.
-	 * @param buffer Buffer to write.
-	 * @param length Number of bytes to write.
-	 * @param offset Offset where start to write.
-	 * @param callback Function to call when the operation ended.
-	 * @param callbackStatus Parameter to pass to the callback function.
-	 * @return true if the operation has success
-	 */
-	virtual bool writeByte(const uint8_t *buffer, uint16_t length,uint16_t offset,
-		byteOperationCallback_t callback,CallbackStatus_t *callbackStatus)=0;
-
-	/**
-	 * Read a sequence of bytes from the NDEF file.
-	 * @param byteOffset Read offset in bytes.
-	 * @param byteLength Number of bytes to read.
-	 * @param[out] buffer Buffer to store the read data into.
-	 * @param callback Function to call when the operation ended.
-	 * @param callbackStatus Parameter to pass to the callback function.
-	 * @return true if the operation has success
-	 */
-	virtual bool readByte(const uint16_t byteOffset, const uint16_t byteLength,
-		uint8_t *buffer, byteOperationCallback_t callback,CallbackStatus_t *callbackStatus)=0;
-
-
-	/** object with the user callback */
-	Callbacks *mCallBack;
-private:
-
-	/** object with the current callback status */
-	CallbackStatus_t mCallBackStatus;
-	/** default callback object, all the functions are empty */
-	Callbacks mDefaultCallBack;
-
-	/**
-	 * Function called when a write operation completes, it will invoke on_message_write
-	 * @param internalState Object that invokes the write operation.
-	 * @param status True if the operation had success.
-	 * @param buffer Buffer written.
-	 * @param length Number of bytes written.
-	 * @return true if the write had success
-	 */
-	static bool onWriteMessageCallback(CallbackStatus_t *internalState,
-		bool status,const uint8_t *buffer, uint16_t ){
-		delete [] buffer;
-
-		internalState->callOwner->mCallBack->on_message_write(internalState->callOwner,status);
-
-		return status;
-	}
-
-	/**
-	 * Function called when a read operation completes.
-	 * In this case we read the message length, this function will read all the message
-	 * @param internalState Object that invokes the write operation.
-	 * @param status true If the operation had success.
-	 * @param buffer Buffer read.
-	 * @param length Number of bytes read.
-	 * @return true if the read had success
-	 */
-	static bool onReadMessageLength(CallbackStatus_t *internalState,
-		bool status,const uint8_t *buffer, uint16_t length){
-
-		if (!status || length!=2) {
-			internalState->callOwner->mCallBack->on_message_read(internalState->callOwner,false,internalState->msg);
-			return false;
-		}//if
-
-		length = (((uint16_t) buffer[0]) << 8 | buffer[1]);
-		delete [] buffer;
-
-		uint8_t *readBuffer = new uint8_t[length];
-		if (readBuffer==NULL) {
-			internalState->callOwner->mCallBack->on_message_read(internalState->callOwner,false,internalState->msg);
-			return false;
-		}//readBuffer
-
-		internalState->callOwner->readByte(2,length,readBuffer, &NDefNfcTag::onReadMessageCallback,internalState);
-		return status;
-	}
-
-	/**
-	 * Function called when all messages have been read
-	 * @param internalState Object that invokes the write operation.
-	 * @param status True if the operation had success.
-	 * @param buffer Buffer read.
-	 * @param length Number of bytes read.
-	 * @return true if the read had success
-	 */
-	static bool onReadMessageCallback(CallbackStatus_t *internalState,
-		bool status,const uint8_t *buffer, uint16_t length){
-		if(!status) {
-			internalState->callOwner->mCallBack->on_message_read(internalState->callOwner,false,internalState->msg);
-			return false;
-		}
-		Message::parse_message(buffer, length, internalState->msg);
-		delete [] buffer;
-		internalState->callOwner->mCallBack-> on_message_read(internalState->callOwner,true,internalState->msg);
-		return status ;
-	}
-
-}; //class NDefNfcTagASync
-
-}// namespace NDefLib
-
-#endif /* NDEFLIB_NDEFNFCTAG_H_ */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
--- a/NDefLib/Record.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/**
- ******************************************************************************
- * @file    Record.h
- * @author  ST / Central Labs
- * @version V2.0.0
- * @date    28 Apr 2017
- * @brief   Generic Record class 
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * 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.
- *   3. Neither the name of STMicroelectronics nor the names of its contributors
- *      may be used to endorse or promote products derived from this software
- *      without specific prior written permission.
- *
- * 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-#ifndef NDEFLIB_RECORD_H_
-#define NDEFLIB_RECORD_H_
-#include <stdint.h>
-
-#include "RecordHeader.h"
-
-namespace NDefLib {
-
-/**
- * Base class for a NDefRecord
- * @see NFC Data Exchange Format (NDEF) Technical Specification NDEF 1.0
- */
-class Record {
-public:
-
-	/**
-	 * Enum used to identify the record type.
-	 */
-	typedef enum {
-		TYPE_UNKNOWN,        //!< UNKNOWN record
-		TYPE_TEXT,           //!< TEXT
-		TYPE_AAR,            //!< Android Archive record
-		TYPE_MIME,           //!< generic MIME type
-		TYPE_URI,            //!< generic URI
-		TYPE_URI_MAIL,       //!< Email URI record
-		TYPE_URI_SMS,        //!< SMS URI record
-		TYPE_URI_GEOLOCATION,//!< position URI record
-		TYPE_MIME_VCARD,     //!< VCard record
-		TYPE_WIFI_CONF 		 //!< Wifi configuration
-	} RecordType_t;
-
-	Record() {
-	}
-
-	/**
-	 * Set the record as the first record in the message.
-	 */
-	void set_as_first_record() {
-		mRecordHeader.set_MB(true);
-	}
-
-	/**
-	 * Set the record as the last record in the message.
-	 */
-	void set_as_last_record() {
-		mRecordHeader.set_ME(true);
-	}
-
-	/**
-	 * Check if it is the last record in the message.
-	 * @return true if it is the last record in the message
-	 */
-	bool is_last_record() const {
-		return mRecordHeader.get_ME();
-	}
-
-	/**
-	 * Check if it is the first record in the message.
-	 * @return true if it is the fist record in the message
-	 */
-	bool is_first_record() const {
-		return mRecordHeader.get_MB();
-	}
-
-	/**
-	 * Set the record as generic (not the first one and not the last one)
-	 */
-	void set_as_middle_record() {
-		mRecordHeader.set_MB(false);
-		mRecordHeader.set_ME(false);
-	}
-
-	/**
-	 * Check if the record is in the middle of a chain.
-	 * @return true if is not the fist or the last one
-	 */
-	bool is_middle_record() const{
-		return ! (mRecordHeader.get_MB() || mRecordHeader.get_ME());
-	}
-
-	/**
-	 * Get tag type.
-	 * @par This method should be overridden to return a valid type.
-	 * @return tag type 
-	 */
-	virtual RecordType_t get_type() const {
-		return TYPE_UNKNOWN;
-	} //getType
-
-
-	/**
-	 * Get the record header.
-	 * @return record header 
-	 */
-	const RecordHeader& get_header() const{
-		return mRecordHeader;
-	}
-
-	/**
-	 * Number of bytes needed to store this record.
-	 * @return size of the header + size of the record content
-	 */
-	virtual uint16_t get_byte_length() {
-		return mRecordHeader.get_record_length();
-	}
-
-	/**
-	 * Write the record content into a buffer.
-	 * @param[out] buffer buffer to write the record content into, the buffer size
-	 *  must be almost {@link Record#getByteLength} bytes.
-	 * @return number of written bytes
-	 */
-	virtual uint16_t write(uint8_t *buffer)=0;
-
-	virtual ~Record() {
-	};
-
-protected:
-	RecordHeader mRecordHeader;
-};
-
-} /* namespace NDefLib */
-
-#endif /* NDEFLIB_RECORD_H_ */
--- a/NDefLib/RecordHeader.h	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-/**
- ******************************************************************************
- * @file    RecordHeader.h
- * @author  ST / Central Labs
- * @version V2.0.0
- * @date    28 Apr 2017
- * @brief   Record header class 
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * 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.
- *   3. Neither the name of STMicroelectronics nor the names of its contributors
- *      may be used to endorse or promote products derived from this software
- *      without specific prior written permission.
- *
- * 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-#ifndef NDEFLIB_RECORDHEADER_H_
-#define NDEFLIB_RECORDHEADER_H_
-
-#include <stdint.h>
-
-namespace NDefLib {
-
-/**
- * Record header class.
- * @see NFC Data Exchange Format (NDEF) Technical Specification NDEF 1.0
- */
-class RecordHeader {
-
-public:
-
-	/**
-	 * Record type format
-	 */
-	typedef enum TypeNameFormat {
-		Empty = 0x00,          //!< Empty
-		NFC_well_known = 0x01, //!< NFC_well_known
-		Mime_media_type = 0x02,//!< Mime_media_type
-		Absolute_URI = 0x03,   //!< Absolute_URI
-		NFC_external = 0x04,   //!< NFC_external
-		Unknown = 0x05,        //!< Unknown
-		Unchanged = 0x06,      //!< Unchanged
-		Reserved = 0x07        //!< Reserved
-	} TypeNameFormat_t;
-
-
-	RecordHeader() :
-			headerFlags(0), typeLength(0), payloadLength(0) {
-		set_SR(true);
-	}
-
-	/**
-	 * Set the 'message begin' flag.
-	 * @param value True if the record is the first within the message.
-	 */
-	void set_MB(bool value) {
-		if (value) {
-			headerFlags |= 0x80;
-		} else {
-			headerFlags &= ~0x80;
-		}
-	}//set_MB
-
-	/**
-	 * Check the 'message begin' flag.
-	 * @return true if it is the first record in the message
-	 */
-	bool get_MB() const {
-		return (headerFlags & 0x80) != 0;
-	}//get_MB
-
-	/**
-	 * Set the 'message end' flag.
-	 * @param value True if it is the last record in the message.
-	 */
-	void set_ME(bool value) {
-		if (value) {
-			headerFlags |= 0x40;
-		} else {
-			headerFlags &= ~0x40;
-		}
-	}//set_ME
-
-	/**
-	 * Check the 'message end' flag.
-	 * @return true if it is the last record in the message
-	 */
-	bool get_ME() const {
-		return (headerFlags & 0x40) != 0;
-	}//get_ME
-
-	/**
-	 * Set the 'Chunk' flag.
-	 * @param value True if the record is in the first record chunk or in a middle record
-	 * chunk of a chunked payload.
-	 */
-	void set_CF(bool value) {
-		if (value) {
-			headerFlags |= 0x20;
-		} else {
-			headerFlags &= ~0x20;
-		}
-	}//set_CF
-
-	/**
-	 * Check the 'Chunk' flag value.
-	 * @return true if the record is in the first record chunk or in a middle record
-	 * chunk of a chunked payload
-	 */
-	bool get_CF() const {
-		return (headerFlags & 0x20) != 0;
-	}//get_CF
-
-	/**
-	 * Set the 'Short record' flag value.
-	 * @param value True if the record size can be encoded with 8 bits.
-	 */
-	void set_SR(bool value) {
-		if (value) {
-			headerFlags |= 0x10;
-		} else {
-			headerFlags &= ~0x10;
-		}
-	}//setSR
-
-	/**
-	 * Check the 'Short record' flag.
-	 * @return true if the short range header format is set
-	 */
-	bool get_SR() const {
-		return (headerFlags & 0x10) != 0;
-	}//getSR
-
-	/**
-	 * Set the 'ID length' flag.
-	 * @param value True if the 'ID length' value is used.
-	 */
-	void set_IL(bool value) {
-		if (value) {
-			headerFlags |= 0x08;
-		} else {
-			headerFlags &= ~0x08;
-		}
-	}//setIL
-
-	/**
-	 * Check the 'ID length' flag.
-	 * @param value True if 'ID length' is set.
-	 */
-	bool get_IL() const {
-		return (headerFlags & 0x08) != 0;
-	}//getIL
-
-	/**
-	 * Set the type name format field.
-	 * @param value Record type name format.
-	 */
-	void set_FNT(const TypeNameFormat_t value) {
-		uint8_t temp = (uint8_t) value;
-		temp &= 0x07; //keep the first 3 bits
-		headerFlags &= 0xF8; //clean the fist 3 bits
-		headerFlags |= temp; //set the fist 3 bits
-	}//setFNT
-
-	/**
-	 * Get the record type name.
-	 * @return type name format of the record
-	 */
-	TypeNameFormat_t get_FNT() const {
-		return (TypeNameFormat_t) (headerFlags & 0x07);
-	}
-
-	/**
-	 * Set the record payload length.
-	 * @par This function will update the SR field as needed.
-	 * @param length payload length
-	 */
-	void set_payload_length(uint32_t length) {
-		payloadLength = length;
-		set_SR(payloadLength <= 255);
-	}
-
-	/**
-	 * Get the payload length.
-	 * @return payload length
-	 */
-	uint32_t get_payload_length() const {
-		return payloadLength;
-	}
-
-	/**
-	 * Set the type length.
-	 * @param size.
-	 */
-	void set_type_length(uint8_t size) {
-		typeLength = size;
-	}
-
-	/**
-	 * Get the type length.
-	 * @return type length
-	 */
-	uint8_t get_type_length() const {
-		return typeLength;
-	}
-
-	/**
-	 * Set the id length.
-	 * @param size.
-	 */
-	void set_id_length(uint8_t size) {
-		if (size!=0) {
-			idLength = size;
-			set_IL(true);
-		} else {
-			set_IL(false);
-		}
-	}
-
-	/**
-	 * Get the id length.
-	 * @return id length
-	 */
-	uint8_t get_id_length() const {
-		return idLength;
-	}
-
-	/**
-	 * Get the number of bytes needed to store this record.
-	 * @return 3 or 6
-	 */
-	uint16_t get_record_length() const {
-		return (get_SR() ? 3 : 6) + (get_IL() ? idLength : 0)+typeLength + payloadLength;
-	}
-
-	/**
-	 * Store the header information in the buffer.
-	 * @param[out] outBuffer Buffer to write the header into.
-	 * @return number of write bytes
-	 */
-	uint8_t write_header(uint8_t *outBuffer) const {
-
-		uint32_t index = 0;
-
-		outBuffer[index++] = headerFlags;
-		outBuffer[index++] = typeLength;
-		if (get_SR()) {
-			outBuffer[index++] = (uint8_t) payloadLength;
-		} else {
-			outBuffer[index++] = (uint8_t) ((payloadLength & 0xFF000000)
-					>> 24);
-			outBuffer[index++] = (uint8_t) ((payloadLength & 0x00FF0000)
-					>> 16);
-			outBuffer[index++] = (uint8_t) ((payloadLength & 0x0000FF00)
-					>> 8);
-			outBuffer[index++] = (uint8_t) (payloadLength & 0x000000FF);
-		} //if-else
-		if (get_IL()) {
-			outBuffer[index++] =idLength;
-		}
-
-		return index;
-	} //writeHeader
-
-	/**
-	 * Load an header from a buffer.
-	 * @param buffer Buffer to load the header from.
-	 * @return number of read bytes
-	 */
-	uint16_t load_header(const uint8_t * const buffer) {
-		uint32_t index = 0;
-		headerFlags = buffer[index++];
-		typeLength = buffer[index++];
-		if (get_SR()) {
-			payloadLength = buffer[index++];
-		} else {
-			payloadLength = (((uint32_t) buffer[index + 0]) << 24)
-				| (((uint32_t) buffer[index + 1]) << 16)
-				| (((uint32_t) buffer[index + 2]) << 8)
-				| ((uint32_t) buffer[index + 3]);
-			index += 4;
-		} //if-else
-		if (get_IL()) {
-			idLength = buffer[index++];
-		} else { 
-			idLength = 0;
-		}
-
-		return index;
-	} //loadHeader
-
-	/**
-	 * Equal operator.
-	 * @param other Other object to compare with.
-	 * @return true if the two record headers are equal
-	 */
-	bool operator==(const RecordHeader &other) const{
-		return (headerFlags==other.headerFlags) &&
-		(typeLength==other.typeLength) &&
-		(payloadLength==other.payloadLength);
-	}
-
-	bool operator!=(const RecordHeader &other) const{
-		return !(*this==other);
-	}
-
-private:
-	uint8_t idLength;
-	uint8_t headerFlags;
-	uint8_t typeLength;
-	uint32_t payloadLength;
-};
-
-} /* namespace NDefLib */
-
-#endif /* NDEFLIB_RECORDHEADER_H_ */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
--- a/NDefLib/RecordType.lib	Sun Dec 10 17:17:41 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://os.mbed.com/users/DuyLionTran/code/RecordType/#51d7bdf88981
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensor/ReadSensor.cpp	Tue Dec 12 15:58:44 2017 +0000
@@ -0,0 +1,29 @@
+#include "mbed.h"
+#include "ReadSensor.h"
+
+const float saturationValueTab[41] = {      //saturation dissolved oxygen concentrations at various temperatures
+14.46, 14.22, 13.82, 13.44, 13.09,
+12.74, 12.42, 12.11, 11.81, 11.53,
+11.26, 11.01, 10.77, 10.53, 10.30,
+10.08, 9.86,  9.66,  9.46,  9.27,
+9.08,  8.90,  8.73,  8.57,  8.41,
+8.25,  8.11,  7.96,  7.82,  7.69,
+7.56,  7.43,  7.30,  7.18,  7.07,
+6.95,  6.84,  6.73,  6.63,  6.53,
+6.41,
+};
+
+float saturationDoVoltage; 
+float saturationDoTemperature;
+float averageVoltage;
+
+AnalogIn    phSensor(SENSOR_1_PIN);
+AnalogIn    DOSensor(SENSOR_2_PIN);
+
+void SENSOR_Calib() {
+    
+}
+
+float SENSOR_ReadPHValue() {
+    return phSensor.read();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensor/ReadSensor.h	Tue Dec 12 15:58:44 2017 +0000
@@ -0,0 +1,18 @@
+#ifndef __READSENSOR_H__
+#define __READSENSOR_H__
+
+#define SENSOR_1_PIN  (A0)
+#define SENSOR_2_PIN  (A1)
+#define SENSOR_3_PIN  (A3)
+#define SENSOR_4_PIN  (A4)
+
+#define SaturationDoVoltageAddress     12          //the address of the Saturation Oxygen voltage stored in the Flash
+#define SaturationDoTemperatureAddress 16      //the address of the Saturation Oxygen temperature stored in the Flash
+
+#define VREF           3.3 
+#define SCOUNT         30 
+
+void SENSOR_Calib();
+float SENSOR_ReadPHValue();
+
+#endif /* __READSENSOR_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleMQTT.cpp	Tue Dec 12 15:58:44 2017 +0000
@@ -0,0 +1,3 @@
+#include "SimpleMQTT.h"
+
+#include "mbed.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleMQTT.h	Tue Dec 12 15:58:44 2017 +0000
@@ -0,0 +1,4 @@
+#ifndef __SIMPLEMQTT_H__
+#define __SIMPLEMQTT_H__
+
+#endif /* __SIMPLEMQTT_H__ */
\ No newline at end of file
--- a/easy-connect.lib	Sun Dec 10 17:17:41 2017 +0000
+++ b/easy-connect.lib	Tue Dec 12 15:58:44 2017 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/DuyLionTran/code/easy-connect/#c9094fbda0bd
+easy-connect#9fa9929d1a8c
--- a/main.cpp	Sun Dec 10 17:17:41 2017 +0000
+++ b/main.cpp	Tue Dec 12 15:58:44 2017 +0000
@@ -8,6 +8,8 @@
 #include "NDefLib/RecordType/RecordURI.h"
 #include "MQTTNetwork.h"
 #include "MQTTmbed.h"
+#include "ReadSensor.h"
+#include "SimpleMQTT.h"
 
 /***************************************************************
  * Definitions
@@ -17,17 +19,14 @@
 #define ID 					MQTT_DEVICE_ID         	// For a registered connection is your device id
 #define AUTH_TOKEN  		MQTT_DEVICE_PASSWORD  	// For a registered connection is a device auth-token
 #define DEFAULT_TYPE_NAME  	MQTT_DEVICE_TYPE  		// For a registered connection is device type
+#define AUTH_METHOD         MQTT_USERNAME
 
-#define TYPE DEFAULT_TYPE_NAME       // For a registered connection, replace with your type
-#define IBM_IOT_PORT MQTT_PORT
+#define TYPE 				DEFAULT_TYPE_NAME       // For a registered connection, replace with your type
+#define IBM_IOT_PORT 		MQTT_PORT
 
 #define MQTT_MAX_PACKET_SIZE 	400   
 #define MQTT_MAX_PAYLOAD_SIZE 	300 
 
-#define SENSOR_1_PIN  (A0)
-#define SENSOR_2_PIN  (A1)
-#define SENSOR_3_PIN  (A3)
-#define SENSOR_4_PIN  (A4)
 #define RELAY_1_PIN   (D11)
 #define RELAY_2_PIN   (D12)
 
@@ -64,37 +63,34 @@
 static Serial pc(SERIAL_TX, SERIAL_RX); 
 
 DigitalOut 	myled(LED1);
-AnalogIn 	phSensor(SENSOR_1_PIN);
-AnalogIn 	DOSensor(SENSOR_2_PIN);
 
 Timer timer;
 
 /***************************************************************
  * Unity function definitions
  ***************************************************************/
-void subscribe_cb(MQTT::MessageData & msgMQTT); 
-int subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client);
-int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
-int getConnTimeout(int attemptNumber);
-void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
-int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client);
-void getADC();
+void MQTT_SubscribeCallback(MQTT::MessageData & msgMQTT); 
+int MQTT_Subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client);
+int MQTT_Connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
+int MQTT_GetConnTimeout(int attemptNumber);
+void MQTT_AttemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
+int MQTT_Publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime);
 
 /***************************************************************
  * Unity function declarations
  ***************************************************************/ 
-void subscribe_cb(MQTT::MessageData & msgMQTT) {
+void MQTT_SubscribeCallback(MQTT::MessageData & msgMQTT) {
     char msg[MQTT_MAX_PAYLOAD_SIZE];
     msg[0]='\0';
     strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen);
-    printf ("--->>> subscribe_cb msg: %s\n\r", msg);
+    printf ("--->>> MQTT_SubscribeCallback msg: %s\n\r", msg);
 }
 
-int subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) {
-    return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb);
+int MQTT_Subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) {
+    return client->subscribe(pubTopic, MQTT::QOS1, MQTT_SubscribeCallback);
 }
 
-int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
+int MQTT_Connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
     const char* iot_ibm = MQTT_BROKER_URL;     
     char hostname[strlen(org) + strlen(iot_ibm) + 1];
     
@@ -109,9 +105,6 @@
     LOG("Nucleo IP ADDRESS: %s\n\r", network->get_ip_address());
     LOG("Nucleo MAC ADDRESS: %s\n\r", network->get_mac_address());
     LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT);
-//    for(int i = 0; clientId[i]; i++){  // set lowercase mac
-//       clientId[i] = tolower(clientId[i]); 
-//    }    
     LOG("Client ID: %s\n\r", clientId);
     LOG("Topic: %s\n\r",MQTT_EVENT_TOPIC);
     LOG("Subscription URL: %s\n\r", subscription_url);
@@ -134,7 +127,7 @@
     data.struct_version 		= 0;
     data.clientID.cstring 		= clientId; 
 	data.keepAliveInterval 		= MQTT_KEEPALIVE;  // in Sec   
-    data.username.cstring 		= "use-token-auth";
+    data.username.cstring 		= AUTH_METHOD;
     data.password.cstring 		= auth_token;
     printf ("AutToken: %s\n\r", auth_token);
        
@@ -145,7 +138,7 @@
     }
     connected = true;
     printf ("--->MQTT Connected\n\r"); 
-    if ((rc=subscribe(topicCMD, client)) == 0) { 
+    if ((rc = MQTT_Subscribe(topicCMD, client)) == 0) { 
        	LOG ("--->>>MQTT subscribed to: %s\n\r", topicCMD);
     } else {
 		LOG ("--->>>ERROR MQTT subscribe : %s\n\r", topicCMD);
@@ -156,25 +149,25 @@
 }
 
 
-int getConnTimeout(int attemptNumber) {  // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
+int MQTT_GetConnTimeout(int attemptNumber) {  // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
    // after 20 attempts, retry every 10 minutes
     return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
 }
 
 
-void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
+void MQTT_AttemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
     connected = false;
            
-    while (connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) {    
+    while (MQTT_Connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) {    
         if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
             printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc);        
             return; // don't reattempt to connect if credentials are wrong
         } 
-        int timeout = getConnTimeout(++retryAttempt);
+        int timeout = MQTT_GetConnTimeout(++retryAttempt);
         WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
         
         // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
-        //  or maybe just add the proper members to do this disconnect and call attemptConnect(...)        
+        //  or maybe just add the proper members to do this disconnect and call MQTT_AttemptConnect(...)        
         // this works - reset the system when the retry count gets to a threshold
         if (retryAttempt == 5)
             NVIC_SystemReset(); 
@@ -183,23 +176,21 @@
     }    
 }
 
-int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime) {
+int MQTT_Publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime) {
     MQTT::Message message;
     const char* pubTopic = MQTT_EVENT_TOPIC;
             
     char buf[MQTT_MAX_PAYLOAD_SIZE];
     char timeBuf[50];
-    float adc0;
 
 	if (!client->isConnected()) { 
 		printf ("---> MQTT DISCONNECTED\n\r"); return MQTT::FAILURE; 
 	}
 	
-	adc0 = ADC_PHVal;
 	strftime(timeBuf, 50, "%Y/%m/%d %H:%M:%S", localtime(&inputTime));
     sprintf(buf,
      "{\"Project\":\"%s\",\"Time\":\"%s\",\"Type\":1,\"cmdID\":%d,\"ADC0\":%0.4f}",
-              projectName, timeBuf, cmdID, adc0);
+              projectName, timeBuf, cmdID, ADC_PHVal);
     message.qos        = MQTT::QOS0;
     message.retained   = false;
     message.dup        = false;
@@ -213,11 +204,6 @@
     return client->publish(pubTopic, message);    
 }
 
-void getADC() {
-    ADC_PHVal    = phSensor.read();
-//    ADC_DOVal    = DOSensor.read();
-//    voltageValue = (ADC_PHVal * 5.0);  
-}
 /***************************************************************
  * Main
  ***************************************************************/ 
@@ -238,7 +224,7 @@
    MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork);
 		
    printf ("ATTEMPT CONNECT\n\r");
-   attemptConnect(&client, &mqttNetwork, network);
+   MQTT_AttemptConnect(&client, &mqttNetwork, network);
    if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)     {
        printf ("---ERROR line : %d\n\r", __LINE__);
        while (true)
@@ -248,14 +234,14 @@
    myled=1;          
 	while (true) {
 		time_t seconds = time(NULL);
-		getADC();
+		ADC_PHVal = SENSOR_ReadPHValue();
 		if (connected == true) {
 	       	if ((uint32_t)(timer.read() - lastRead) >= uploadInterval) {               // Publish a message every 3 second
-	    		if (publish(&client, seconds) != MQTT::SUCCESS) {    			 
+	    		if (MQTT_Publish(&client, seconds) != MQTT::SUCCESS) {    			 
 	        		myled=0;
 	            	client.disconnect();
 					mqttNetwork.disconnect();			   
-	            	attemptConnect(&client, &mqttNetwork, network);   // if we have lost the connection                
+	            	MQTT_AttemptConnect(&client, &mqttNetwork, network);   // if we have lost the connection                
 	        	} else {					 
 					myled = 1;
 	            	cmdID++;