Shane Kirkbride / Mbed 2 deprecated STM-Client

Dependencies:   mbed DHT Matrix

Files at this revision

API Documentation at this revision

Comitter:
ShaneKirkbride
Date:
Thu Jul 14 20:38:18 2016 +0000
Child:
1:99c58a942425
Commit message:
first commit. Rest example working

Changed in this revision

FP.cpp Show annotated file Show diff for this revision Revisions of this file
FP.h Show annotated file Show diff for this revision Revisions of this file
STMClient.cpp Show annotated file Show diff for this revision Revisions of this file
STMClient.h Show annotated file Show diff for this revision Revisions of this file
STMClientCmd.cpp Show annotated file Show diff for this revision Revisions of this file
STMClientCmd.h Show annotated file Show diff for this revision Revisions of this file
STMClientResponse.cpp Show annotated file Show diff for this revision Revisions of this file
STMClientResponse.h Show annotated file Show diff for this revision Revisions of this file
STMClientRest.cpp Show annotated file Show diff for this revision Revisions of this file
STMClientRest.h Show annotated file Show diff for this revision Revisions of this file
library.json Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
millis.cpp Show annotated file Show diff for this revision Revisions of this file
millis.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FP.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,597 @@
+/**
+ * @file    FP.cpp
+ * @brief   Core Utility - Templated Function Pointer Class
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FP.h"
+#include <stdint.h>
+
+template<class retT, class argT>
+FP<retT, argT>::FP()
+{
+    obj_callback = 0;
+    c_callback = 0;
+}
+
+template<class retT, class argT>
+bool FP<retT, argT>::attached()
+{
+    return obj_callback || c_callback;
+}
+
+
+template<class retT, class argT>
+void FP<retT, argT>::detach()
+{
+    obj_callback = 0;
+    c_callback = 0;
+}
+
+
+template<class retT, class argT>
+void FP<retT, argT>::attach(retT (*function)(argT))
+{
+    c_callback = function;
+}
+
+template<class retT, class argT>
+retT FP<retT, argT>::operator()(argT arg) const
+{
+    if( 0 != c_callback )
+    {
+        return obj_callback ? (obj_callback->*method_callback)(arg) : (*c_callback)(arg);
+    }
+    return (retT)0;
+}
+
+// pre-define the types for the linker
+template class FP<void,char>;
+template class FP<void,char*>;
+template class FP<void,int8_t>;
+template class FP<void,int8_t*>;
+template class FP<void,uint8_t>;
+template class FP<void,uint8_t*>;
+template class FP<void,int16_t>;
+template class FP<void,int16_t*>;
+template class FP<void,uint16_t>;
+template class FP<void,uint16_t*>;
+template class FP<void,int32_t>;
+template class FP<void,int32_t*>;
+template class FP<void,uint32_t>;
+template class FP<void,uint32_t*>;
+template class FP<void,int64_t>;
+template class FP<void,int64_t*>;
+template class FP<void,uint64_t>;
+template class FP<void,uint64_t*>;
+template class FP<void,bool>;
+template class FP<void,bool*>;
+template class FP<void,float>;
+template class FP<void,float*>;
+template class FP<void,double>;
+template class FP<void,double*>;
+template class FP<void,void*>;
+
+template class FP<int8_t,char>;
+template class FP<int8_t,char*>;
+template class FP<int8_t,int8_t>;
+template class FP<int8_t,int8_t*>;
+template class FP<int8_t,uint8_t>;
+template class FP<int8_t,uint8_t*>;
+template class FP<int8_t,int16_t>;
+template class FP<int8_t,int16_t*>;
+template class FP<int8_t,uint16_t>;
+template class FP<int8_t,uint16_t*>;
+template class FP<int8_t,int32_t>;
+template class FP<int8_t,int32_t*>;
+template class FP<int8_t,uint32_t>;
+template class FP<int8_t,uint32_t*>;
+template class FP<int8_t,int64_t>;
+template class FP<int8_t,int64_t*>;
+template class FP<int8_t,uint64_t>;
+template class FP<int8_t,uint64_t*>;
+template class FP<int8_t,bool>;
+template class FP<int8_t,bool*>;
+template class FP<int8_t,float>;
+template class FP<int8_t,float*>;
+template class FP<int8_t,double>;
+template class FP<int8_t,double*>;
+
+template class FP<int8_t*,char>;
+template class FP<int8_t*,char*>;
+template class FP<int8_t*,int8_t>;
+template class FP<int8_t*,int8_t*>;
+template class FP<int8_t*,uint8_t>;
+template class FP<int8_t*,uint8_t*>;
+template class FP<int8_t*,int16_t>;
+template class FP<int8_t*,int16_t*>;
+template class FP<int8_t*,uint16_t>;
+template class FP<int8_t*,uint16_t*>;
+template class FP<int8_t*,int32_t>;
+template class FP<int8_t*,int32_t*>;
+template class FP<int8_t*,uint32_t>;
+template class FP<int8_t*,uint32_t*>;
+template class FP<int8_t*,int64_t>;
+template class FP<int8_t*,int64_t*>;
+template class FP<int8_t*,uint64_t>;
+template class FP<int8_t*,uint64_t*>;
+template class FP<int8_t*,bool>;
+template class FP<int8_t*,bool*>;
+template class FP<int8_t*,float>;
+template class FP<int8_t*,float*>;
+template class FP<int8_t*,double>;
+template class FP<int8_t*,double*>;
+
+template class FP<uint8_t,char>;
+template class FP<uint8_t,char*>;
+template class FP<uint8_t,int8_t>;
+template class FP<uint8_t,int8_t*>;
+template class FP<uint8_t,uint8_t>;
+template class FP<uint8_t,uint8_t*>;
+template class FP<uint8_t,int16_t>;
+template class FP<uint8_t,int16_t*>;
+template class FP<uint8_t,uint16_t>;
+template class FP<uint8_t,uint16_t*>;
+template class FP<uint8_t,int32_t>;
+template class FP<uint8_t,int32_t*>;
+template class FP<uint8_t,uint32_t>;
+template class FP<uint8_t,uint32_t*>;
+template class FP<uint8_t,int64_t>;
+template class FP<uint8_t,int64_t*>;
+template class FP<uint8_t,uint64_t>;
+template class FP<uint8_t,uint64_t*>;
+template class FP<uint8_t,bool>;
+template class FP<uint8_t,bool*>;
+template class FP<uint8_t,float>;
+template class FP<uint8_t,float*>;
+template class FP<uint8_t,double>;
+template class FP<uint8_t,double*>;
+
+template class FP<uint8_t*,char>;
+template class FP<uint8_t*,char*>;
+template class FP<uint8_t*,int8_t>;
+template class FP<uint8_t*,int8_t*>;
+template class FP<uint8_t*,uint8_t>;
+template class FP<uint8_t*,uint8_t*>;
+template class FP<uint8_t*,int16_t>;
+template class FP<uint8_t*,int16_t*>;
+template class FP<uint8_t*,uint16_t>;
+template class FP<uint8_t*,uint16_t*>;
+template class FP<uint8_t*,int32_t>;
+template class FP<uint8_t*,int32_t*>;
+template class FP<uint8_t*,uint32_t>;
+template class FP<uint8_t*,uint32_t*>;
+template class FP<uint8_t*,int64_t>;
+template class FP<uint8_t*,int64_t*>;
+template class FP<uint8_t*,uint64_t>;
+template class FP<uint8_t*,uint64_t*>;
+template class FP<uint8_t*,bool>;
+template class FP<uint8_t*,bool*>;
+template class FP<uint8_t*,float>;
+template class FP<uint8_t*,float*>;
+template class FP<uint8_t*,double>;
+template class FP<uint8_t*,double*>;
+
+template class FP<int16_t,char>;
+template class FP<int16_t,char*>;
+template class FP<int16_t,int8_t>;
+template class FP<int16_t,int8_t*>;
+template class FP<int16_t,uint8_t>;
+template class FP<int16_t,uint8_t*>;
+template class FP<int16_t,int16_t>;
+template class FP<int16_t,int16_t*>;
+template class FP<int16_t,uint16_t>;
+template class FP<int16_t,uint16_t*>;
+template class FP<int16_t,int32_t>;
+template class FP<int16_t,int32_t*>;
+template class FP<int16_t,uint32_t>;
+template class FP<int16_t,uint32_t*>;
+template class FP<int16_t,int64_t>;
+template class FP<int16_t,int64_t*>;
+template class FP<int16_t,uint64_t>;
+template class FP<int16_t,uint64_t*>;
+template class FP<int16_t,bool>;
+template class FP<int16_t,bool*>;
+template class FP<int16_t,float>;
+template class FP<int16_t,float*>;
+template class FP<int16_t,double>;
+template class FP<int16_t,double*>;
+
+template class FP<int16_t*,char>;
+template class FP<int16_t*,char*>;
+template class FP<int16_t*,int8_t>;
+template class FP<int16_t*,int8_t*>;
+template class FP<int16_t*,uint8_t>;
+template class FP<int16_t*,uint8_t*>;
+template class FP<int16_t*,int16_t>;
+template class FP<int16_t*,int16_t*>;
+template class FP<int16_t*,uint16_t>;
+template class FP<int16_t*,uint16_t*>;
+template class FP<int16_t*,int32_t>;
+template class FP<int16_t*,int32_t*>;
+template class FP<int16_t*,uint32_t>;
+template class FP<int16_t*,uint32_t*>;
+template class FP<int16_t*,int64_t>;
+template class FP<int16_t*,int64_t*>;
+template class FP<int16_t*,uint64_t>;
+template class FP<int16_t*,uint64_t*>;
+template class FP<int16_t*,bool>;
+template class FP<int16_t*,bool*>;
+template class FP<int16_t*,float>;
+template class FP<int16_t*,float*>;
+template class FP<int16_t*,double>;
+template class FP<int16_t*,double*>;
+
+template class FP<uint16_t,char>;
+template class FP<uint16_t,char*>;
+template class FP<uint16_t,int8_t>;
+template class FP<uint16_t,int8_t*>;
+template class FP<uint16_t,uint8_t>;
+template class FP<uint16_t,uint8_t*>;
+template class FP<uint16_t,int16_t>;
+template class FP<uint16_t,int16_t*>;
+template class FP<uint16_t,uint16_t>;
+template class FP<uint16_t,uint16_t*>;
+template class FP<uint16_t,int32_t>;
+template class FP<uint16_t,int32_t*>;
+template class FP<uint16_t,uint32_t>;
+template class FP<uint16_t,uint32_t*>;
+template class FP<uint16_t,int64_t>;
+template class FP<uint16_t,int64_t*>;
+template class FP<uint16_t,uint64_t>;
+template class FP<uint16_t,uint64_t*>;
+template class FP<uint16_t,bool>;
+template class FP<uint16_t,bool*>;
+template class FP<uint16_t,float>;
+template class FP<uint16_t,float*>;
+template class FP<uint16_t,double>;
+template class FP<uint16_t,double*>;
+
+template class FP<uint16_t*,char>;
+template class FP<uint16_t*,char*>;
+template class FP<uint16_t*,int8_t>;
+template class FP<uint16_t*,int8_t*>;
+template class FP<uint16_t*,uint8_t>;
+template class FP<uint16_t*,uint8_t*>;
+template class FP<uint16_t*,int16_t>;
+template class FP<uint16_t*,int16_t*>;
+template class FP<uint16_t*,uint16_t>;
+template class FP<uint16_t*,uint16_t*>;
+template class FP<uint16_t*,int32_t>;
+template class FP<uint16_t*,int32_t*>;
+template class FP<uint16_t*,uint32_t>;
+template class FP<uint16_t*,uint32_t*>;
+template class FP<uint16_t*,int64_t>;
+template class FP<uint16_t*,int64_t*>;
+template class FP<uint16_t*,uint64_t>;
+template class FP<uint16_t*,uint64_t*>;
+template class FP<uint16_t*,bool>;
+template class FP<uint16_t*,bool*>;
+template class FP<uint16_t*,float>;
+template class FP<uint16_t*,float*>;
+template class FP<uint16_t*,double>;
+template class FP<uint16_t*,double*>;
+
+template class FP<int32_t,char>;
+template class FP<int32_t,char*>;
+template class FP<int32_t,int8_t>;
+template class FP<int32_t,int8_t*>;
+template class FP<int32_t,uint8_t>;
+template class FP<int32_t,uint8_t*>;
+template class FP<int32_t,int16_t>;
+template class FP<int32_t,int16_t*>;
+template class FP<int32_t,uint16_t>;
+template class FP<int32_t,uint16_t*>;
+template class FP<int32_t,int32_t>;
+template class FP<int32_t,int32_t*>;
+template class FP<int32_t,uint32_t>;
+template class FP<int32_t,uint32_t*>;
+template class FP<int32_t,int64_t>;
+template class FP<int32_t,int64_t*>;
+template class FP<int32_t,uint64_t>;
+template class FP<int32_t,uint64_t*>;
+template class FP<int32_t,bool>;
+template class FP<int32_t,bool*>;
+template class FP<int32_t,float>;
+template class FP<int32_t,float*>;
+template class FP<int32_t,double>;
+template class FP<int32_t,double*>;
+
+template class FP<int32_t*,char>;
+template class FP<int32_t*,char*>;
+template class FP<int32_t*,int8_t>;
+template class FP<int32_t*,int8_t*>;
+template class FP<int32_t*,uint8_t>;
+template class FP<int32_t*,uint8_t*>;
+template class FP<int32_t*,int16_t>;
+template class FP<int32_t*,int16_t*>;
+template class FP<int32_t*,uint16_t>;
+template class FP<int32_t*,uint16_t*>;
+template class FP<int32_t*,int32_t>;
+template class FP<int32_t*,int32_t*>;
+template class FP<int32_t*,uint32_t>;
+template class FP<int32_t*,uint32_t*>;
+template class FP<int32_t*,int64_t>;
+template class FP<int32_t*,int64_t*>;
+template class FP<int32_t*,uint64_t>;
+template class FP<int32_t*,uint64_t*>;
+template class FP<int32_t*,bool>;
+template class FP<int32_t*,bool*>;
+template class FP<int32_t*,float>;
+template class FP<int32_t*,float*>;
+template class FP<int32_t*,double>;
+template class FP<int32_t*,double*>;
+
+template class FP<uint32_t,char>;
+template class FP<uint32_t,char*>;
+template class FP<uint32_t,int8_t>;
+template class FP<uint32_t,int8_t*>;
+template class FP<uint32_t,uint8_t>;
+template class FP<uint32_t,uint8_t*>;
+template class FP<uint32_t,int16_t>;
+template class FP<uint32_t,int16_t*>;
+template class FP<uint32_t,uint16_t>;
+template class FP<uint32_t,uint16_t*>;
+template class FP<uint32_t,int32_t>;
+template class FP<uint32_t,int32_t*>;
+template class FP<uint32_t,uint32_t>;
+template class FP<uint32_t,uint32_t*>;
+template class FP<uint32_t,int64_t>;
+template class FP<uint32_t,int64_t*>;
+template class FP<uint32_t,uint64_t>;
+template class FP<uint32_t,uint64_t*>;
+template class FP<uint32_t,bool>;
+template class FP<uint32_t,bool*>;
+template class FP<uint32_t,float>;
+template class FP<uint32_t,float*>;
+template class FP<uint32_t,double>;
+template class FP<uint32_t,double*>;
+
+template class FP<uint32_t*,char>;
+template class FP<uint32_t*,char*>;
+template class FP<uint32_t*,int8_t>;
+template class FP<uint32_t*,int8_t*>;
+template class FP<uint32_t*,uint8_t>;
+template class FP<uint32_t*,uint8_t*>;
+template class FP<uint32_t*,int16_t>;
+template class FP<uint32_t*,int16_t*>;
+template class FP<uint32_t*,uint16_t>;
+template class FP<uint32_t*,uint16_t*>;
+template class FP<uint32_t*,int32_t>;
+template class FP<uint32_t*,int32_t*>;
+template class FP<uint32_t*,uint32_t>;
+template class FP<uint32_t*,uint32_t*>;
+template class FP<uint32_t*,int64_t>;
+template class FP<uint32_t*,int64_t*>;
+template class FP<uint32_t*,uint64_t>;
+template class FP<uint32_t*,uint64_t*>;
+template class FP<uint32_t*,bool>;
+template class FP<uint32_t*,bool*>;
+template class FP<uint32_t*,float>;
+template class FP<uint32_t*,float*>;
+template class FP<uint32_t*,double>;
+template class FP<uint32_t*,double*>;
+
+template class FP<int64_t,char>;
+template class FP<int64_t,char*>;
+template class FP<int64_t,int8_t>;
+template class FP<int64_t,int8_t*>;
+template class FP<int64_t,uint8_t>;
+template class FP<int64_t,uint8_t*>;
+template class FP<int64_t,int16_t>;
+template class FP<int64_t,int16_t*>;
+template class FP<int64_t,uint16_t>;
+template class FP<int64_t,uint16_t*>;
+template class FP<int64_t,int32_t>;
+template class FP<int64_t,int32_t*>;
+template class FP<int64_t,uint32_t>;
+template class FP<int64_t,uint32_t*>;
+template class FP<int64_t,int64_t>;
+template class FP<int64_t,int64_t*>;
+template class FP<int64_t,uint64_t>;
+template class FP<int64_t,uint64_t*>;
+template class FP<int64_t,bool>;
+template class FP<int64_t,bool*>;
+template class FP<int64_t,float>;
+template class FP<int64_t,float*>;
+template class FP<int64_t,double>;
+template class FP<int64_t,double*>;
+
+template class FP<int64_t*,char>;
+template class FP<int64_t*,char*>;
+template class FP<int64_t*,int8_t>;
+template class FP<int64_t*,int8_t*>;
+template class FP<int64_t*,uint8_t>;
+template class FP<int64_t*,uint8_t*>;
+template class FP<int64_t*,int16_t>;
+template class FP<int64_t*,int16_t*>;
+template class FP<int64_t*,uint16_t>;
+template class FP<int64_t*,uint16_t*>;
+template class FP<int64_t*,int32_t>;
+template class FP<int64_t*,int32_t*>;
+template class FP<int64_t*,uint32_t>;
+template class FP<int64_t*,uint32_t*>;
+template class FP<int64_t*,int64_t>;
+template class FP<int64_t*,int64_t*>;
+template class FP<int64_t*,uint64_t>;
+template class FP<int64_t*,uint64_t*>;
+template class FP<int64_t*,bool>;
+template class FP<int64_t*,bool*>;
+template class FP<int64_t*,float>;
+template class FP<int64_t*,float*>;
+template class FP<int64_t*,double>;
+template class FP<int64_t*,double*>;
+
+template class FP<uint64_t,char>;
+template class FP<uint64_t,char*>;
+template class FP<uint64_t,int8_t>;
+template class FP<uint64_t,int8_t*>;
+template class FP<uint64_t,uint8_t>;
+template class FP<uint64_t,uint8_t*>;
+template class FP<uint64_t,int16_t>;
+template class FP<uint64_t,int16_t*>;
+template class FP<uint64_t,uint16_t>;
+template class FP<uint64_t,uint16_t*>;
+template class FP<uint64_t,int32_t>;
+template class FP<uint64_t,int32_t*>;
+template class FP<uint64_t,uint32_t>;
+template class FP<uint64_t,uint32_t*>;
+template class FP<uint64_t,int64_t>;
+template class FP<uint64_t,int64_t*>;
+template class FP<uint64_t,uint64_t>;
+template class FP<uint64_t,uint64_t*>;
+template class FP<uint64_t,bool>;
+template class FP<uint64_t,bool*>;
+template class FP<uint64_t,float>;
+template class FP<uint64_t,float*>;
+template class FP<uint64_t,double>;
+template class FP<uint64_t,double*>;
+
+template class FP<uint64_t*,char>;
+template class FP<uint64_t*,char*>;
+template class FP<uint64_t*,int8_t>;
+template class FP<uint64_t*,int8_t*>;
+template class FP<uint64_t*,uint8_t>;
+template class FP<uint64_t*,uint8_t*>;
+template class FP<uint64_t*,int16_t>;
+template class FP<uint64_t*,int16_t*>;
+template class FP<uint64_t*,uint16_t>;
+template class FP<uint64_t*,uint16_t*>;
+template class FP<uint64_t*,int32_t>;
+template class FP<uint64_t*,int32_t*>;
+template class FP<uint64_t*,uint32_t>;
+template class FP<uint64_t*,uint32_t*>;
+template class FP<uint64_t*,int64_t>;
+template class FP<uint64_t*,int64_t*>;
+template class FP<uint64_t*,uint64_t>;
+template class FP<uint64_t*,uint64_t*>;
+template class FP<uint64_t*,bool>;
+template class FP<uint64_t*,bool*>;
+template class FP<uint64_t*,float>;
+template class FP<uint64_t*,float*>;
+template class FP<uint64_t*,double>;
+template class FP<uint64_t*,double*>;
+
+template class FP<float,char>;
+template class FP<float,char*>;
+template class FP<float,int8_t>;
+template class FP<float,int8_t*>;
+template class FP<float,uint8_t>;
+template class FP<float,uint8_t*>;
+template class FP<float,int16_t>;
+template class FP<float,int16_t*>;
+template class FP<float,uint16_t>;
+template class FP<float,uint16_t*>;
+template class FP<float,int32_t>;
+template class FP<float,int32_t*>;
+template class FP<float,uint32_t>;
+template class FP<float,uint32_t*>;
+template class FP<float,int64_t>;
+template class FP<float,int64_t*>;
+template class FP<float,uint64_t>;
+template class FP<float,uint64_t*>;
+template class FP<float,bool>;
+template class FP<float,bool*>;
+template class FP<float,float>;
+template class FP<float,float*>;
+template class FP<float,double>;
+template class FP<float,double*>;
+
+template class FP<float*,char>;
+template class FP<float*,char*>;
+template class FP<float*,int8_t>;
+template class FP<float*,int8_t*>;
+template class FP<float*,uint8_t>;
+template class FP<float*,uint8_t*>;
+template class FP<float*,int16_t>;
+template class FP<float*,int16_t*>;
+template class FP<float*,uint16_t>;
+template class FP<float*,uint16_t*>;
+template class FP<float*,int32_t>;
+template class FP<float*,int32_t*>;
+template class FP<float*,uint32_t>;
+template class FP<float*,uint32_t*>;
+template class FP<float*,int64_t>;
+template class FP<float*,int64_t*>;
+template class FP<float*,uint64_t>;
+template class FP<float*,uint64_t*>;
+template class FP<float*,bool>;
+template class FP<float*,bool*>;
+template class FP<float*,float>;
+template class FP<float*,float*>;
+template class FP<float*,double>;
+template class FP<float*,double*>;
+
+template class FP<double,char>;
+template class FP<double,char*>;
+template class FP<double,int8_t>;
+template class FP<double,int8_t*>;
+template class FP<double,uint8_t>;
+template class FP<double,uint8_t*>;
+template class FP<double,int16_t>;
+template class FP<double,int16_t*>;
+template class FP<double,uint16_t>;
+template class FP<double,uint16_t*>;
+template class FP<double,int32_t>;
+template class FP<double,int32_t*>;
+template class FP<double,uint32_t>;
+template class FP<double,uint32_t*>;
+template class FP<double,int64_t>;
+template class FP<double,int64_t*>;
+template class FP<double,uint64_t>;
+template class FP<double,uint64_t*>;
+template class FP<double,bool>;
+template class FP<double,bool*>;
+template class FP<double,float>;
+template class FP<double,float*>;
+template class FP<double,double>;
+template class FP<double,double*>;
+
+template class FP<double*,char>;
+template class FP<double*,char*>;
+template class FP<double*,int8_t>;
+template class FP<double*,int8_t*>;
+template class FP<double*,uint8_t>;
+template class FP<double*,uint8_t*>;
+template class FP<double*,int16_t>;
+template class FP<double*,int16_t*>;
+template class FP<double*,uint16_t>;
+template class FP<double*,uint16_t*>;
+template class FP<double*,int32_t>;
+template class FP<double*,int32_t*>;
+template class FP<double*,uint32_t>;
+template class FP<double*,uint32_t*>;
+template class FP<double*,int64_t>;
+template class FP<double*,int64_t*>;
+template class FP<double*,uint64_t>;
+template class FP<double*,uint64_t*>;
+template class FP<double*,bool>;
+template class FP<double*,bool*>;
+template class FP<double*,float>;
+template class FP<double*,float*>;
+template class FP<double*,double>;
+template class FP<double*,double*>;
+
+template class FP<char, char>;
+template class FP<char, char*>;
+template class FP<char, const char*>;
+
+template class FP<char*, char>;
+template class FP<char*, char*>;
+template class FP<char*, const char*>;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FP.h	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,187 @@
+/**
+ * @file    FP.h
+ * @brief   Core Utility - Templated Function Pointer Class
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FP_H
+#define FP_H
+
+/** Example using the FP Class with global functions
+ * @code
+ *  #include "mbed.h"
+ *  #include "FP.h"
+ *  
+ *  FP<void,bool>fp;
+ *  DigitalOut myled(LED1);
+ *  
+ *  void handler(bool value)
+ *  {
+ *      myled = value;
+ *      return;
+ *  }
+ *  
+ *  int main()
+ *  {
+ *      fp.attach(&handler);
+ *      
+ *      while(1) 
+ *      {
+ *          fp(1);
+ *          wait(0.2);
+ *          fp(0);
+ *          wait(0.2);
+ *      }
+ *  }
+ * @endcode
+ */
+ 
+/** Example using the FP Class with different class member functions
+ * @code
+ *  #include "mbed.h"
+ *  #include "FP.h"
+ *  
+ *  FP<void,bool>fp;
+ *  DigitalOut myled(LED4);
+ *  
+ *  class Wrapper
+ *  {
+ *  public:
+ *      Wrapper(){}
+ *  
+ *      void handler(bool value)
+ *      {
+ *          myled = value;
+ *          return;
+ *      }
+ *  };
+ *  
+ *  int main()
+ *  {
+ *      Wrapper wrapped;
+ *      fp.attach(&wrapped, &Wrapper::handler);
+ *      
+ *      while(1) 
+ *      {
+ *          fp(1);
+ *          wait(0.2);
+ *          fp(0);
+ *          wait(0.2);
+ *      }
+ *  }
+ * @endcode
+ */
+ 
+ /** Example using the FP Class with member FP and member function
+ * @code
+ *  #include "mbed.h"
+ *  #include "FP.h"
+ *  
+ *  DigitalOut myled(LED2);
+ *  
+ *  class Wrapper
+ *  {
+ *  public:
+ *      Wrapper()
+ *      {
+ *          fp.attach(this, &Wrapper::handler);
+ *      }
+ *  
+ *      void handler(bool value)
+ *      {
+ *          myled = value;
+ *          return;
+ *      }
+ *      
+ *      FP<void,bool>fp;
+ *  };
+ *  
+ *  int main()
+ *  {
+ *      Wrapper wrapped;
+ *      
+ *      while(1) 
+ *      {
+ *          wrapped.fp(1);
+ *          wait(0.2);
+ *          wrapped.fp(0);
+ *          wait(0.2);
+ *      }
+ *  }
+ * @endcode
+ */
+
+/**
+ *  @class FP
+ *  @brief API abstraction for a Function Pointers
+ */ 
+template<class retT, class argT>
+class FP
+{
+public:
+    /** Create the FP object
+     */ 
+    FP();
+
+    /** Add a callback function to the class
+     *  @param item - Address of the initialized class
+     *  @param member - Address of the member function (dont forget the scope that the function is defined in)
+     */
+    template<class T>
+    void attach(T *item, retT (T::*method)(argT))
+    {
+        obj_callback = (FPtrDummy *)(item);
+        method_callback = (retT (FPtrDummy::*)(argT))(method);
+        return;
+    }
+
+    /** Add a callback function to the class
+     *  @param function - The address of a globally defined function
+     */
+    void attach(retT (*function)(argT));
+    
+    /** Invoke the function attached to the class
+     *  @param arg - An argument that is passed into the function handler that is called
+     *  @return The return from the function hanlder called by this class
+     */
+    retT operator()(argT arg) const;
+    
+    bool attached();
+    
+    void detach();
+
+private:
+    
+    // empty type used for casting
+    class FPtrDummy;
+    
+    FPtrDummy *obj_callback;
+    
+    /**
+     *  @union Funciton
+     *  @brief Member or global callback function
+     */ 
+    union
+    {
+        retT (*c_callback)(argT);                   /*!< Footprint for a global function */
+        retT (FPtrDummy::*method_callback)(argT);   /*!< Footprint for a member function */
+    };
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClient.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,276 @@
+#include "STMClient.h"
+#include "millis.h"
+
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define SLIP_END  0300        // indicates end of packet
+#define SLIP_ESC  0333        // indicates byte stuffing
+#define SLIP_ESC_END  0334    // ESC ESC_END means END data byte
+#define SLIP_ESC_ESC  0335    // ESC ESC_ESC means ESC data byte
+
+//===== Input
+
+// Process a received SLIP message
+STMClientPacket* STMClient::protoCompletedCb(void) {
+  // the packet starts with a STMClientPacket
+  STMClientPacket* packet = (STMClientPacket*)_proto.buf;
+  if (_debugEn) {
+   // _debug->printf("STMC: got %i @ %i:\n\r 0x%x\n\r 0x%x\n\r 0x%x\n\r", _proto.dataLen,(uint32_t)_proto.buf, packet->cmd, packet->value, packet->argc);
+
+    for (uint16_t i=8; i<_proto.dataLen; i++) 
+    {
+    //  _debug->printf("%x", *(uint8_t*)(_proto.buf+i));
+    }
+    //_debug->printf("\n\r");
+  }
+
+  // verify CRC
+  uint16_t crc = crc16Data(_proto.buf, _proto.dataLen-2, 0);
+  //_debug->printf("CRC: %i\n\r",crc);
+  //wait(0.5);
+  uint16_t resp_crc = *(uint16_t*)(_proto.buf+_proto.dataLen-2);
+  //_debug->printf("resp_crc: %i\n\r",resp_crc);
+  if (crc != resp_crc) {
+    DBG("STMC: Invalid CRC\n\r");
+    wait(0.5);
+    
+    //return NULL; maybe the CRC isn't getting calculated correctly...
+  }
+
+  // dispatch based on command
+  if (packet->cmd == CMD_RESP_V) {
+    // value response
+    _debug->printf("RESP_V: 0x%x \n\r",packet->value);
+
+    return packet;
+  } else if (packet->cmd == CMD_RESP_CB) {
+    FP<void, void*> *fp;
+    // callback reponse
+    _debug->printf("RESP_CB: 0x%x 0x%x \n\r", packet->value, packet->argc);
+
+    fp = (FP<void, void*>*)packet->value;
+    if (fp->attached()) {
+      STMClientResponse resp(packet);
+      (*fp)(&resp);
+    }
+    return NULL;
+  } else {
+    // command (NOT IMPLEMENTED)
+    _debug->printf("CMD 0x%x Value 0x%x ??\n\r", packet->cmd, packet->value);
+    return NULL;
+  }
+}
+
+// Read all characters available on the serial input and process any messages that arrive, but
+// stop if a non-callback response comes in
+STMClientPacket *STMClient::Process() {
+  while (_serial->readable()) {
+    //value =_serial->getc(rxBuffer, 5, eSerialCb, SERIAL_EVENT_RX_ALL, '$');
+    char character=_serial->getc(); 
+    //value = _serial->read();
+    
+    if ((int)character == SLIP_ESC) {
+      _proto.isEsc = 1;
+    } else if ((int)character == SLIP_END) {
+      STMClientPacket *packet = _proto.dataLen >= 8 ? protoCompletedCb() : 0;
+      _proto.dataLen = 0;
+      _proto.isEsc = 0;
+      if (packet != NULL) return packet;
+    } else {
+      if (_proto.isEsc) {
+        if ((int)character == SLIP_ESC_END) character = SLIP_END;
+        if ((int)character == SLIP_ESC_ESC) character = SLIP_ESC;
+        _proto.isEsc = 0;
+      }
+      if (_proto.dataLen < _proto.bufSize) {
+        _proto.buf[_proto.dataLen++] = (int)character;
+      }
+    }
+  }
+  return NULL;
+}
+
+//===== Output
+
+// Write a byte to the output stream and perform SLIP escaping
+void STMClient::write(uint8_t data) {
+  switch (data) {
+  case SLIP_END:
+    _serial->putc(SLIP_ESC);
+    _serial->putc(SLIP_ESC_END);
+    break;
+  case SLIP_ESC:
+    _serial->putc(SLIP_ESC);
+    _serial->putc(SLIP_ESC_ESC);
+    break;
+  default:
+    _serial->putc(data);
+  }
+}
+
+// Write some bytes to the output stream
+void STMClient::write(void* data, uint16_t len) {
+  uint8_t *d = (uint8_t*)data;
+  while (len--)
+    write(*d++);
+}
+
+// Start a request. cmd=command, value=address of callback pointer or first arg,
+// argc=additional argument count
+void STMClient::Request(uint16_t cmd, uint32_t value, uint16_t argc) {
+  //_debug->printf("Starting a request...\n\r");
+  //wait(0.5);
+  crc = 0;
+  _serial->putc(SLIP_END);
+    
+  write(&cmd, 2);
+  crc = crc16Data((unsigned const char*)&cmd, 2, crc);
+
+  write(&argc, 2);
+  crc = crc16Data((unsigned const char*)&argc, 2, crc);
+
+  write(&value, 4);
+  crc = crc16Data((unsigned const char*)&value, 4, crc);
+}
+
+// Append a block of data as an argument to the request
+void STMClient::Request(const void* data, uint16_t len) {
+  uint8_t *d = (uint8_t*)data;
+
+  // write the length
+  write(&len, 2);
+  crc = crc16Data((unsigned const char*)&len, 2, crc);
+
+  // output the data
+  for (uint16_t l=len; l>0; l--) {
+    write(*d);
+    crc = crc16Add(*d, crc);
+    d++;
+  }
+
+  // output padding
+  uint16_t pad = (4-(len&3))&3;
+  uint8_t temp = 0;
+  while (pad--) {
+    write(temp);
+    crc = crc16Add(temp, crc);
+  }
+}
+
+/* Commented this out for now...
+// Append a block of data located in flash as an argument to the request
+void STMClient::Request(const __FlashStringHSTMper* data, uint16_t len) {
+  // write the length
+  write(&len, 2);
+  crc = crc16Data((unsigned const char*)&len, 2, crc);
+
+  // output the data
+  PGM_P p = reinterpret_cast<PGM_P>(data);
+  for (uint16_t l=len; l>0; l--) {
+    uint8_t c = pgm_read_byte(p++);
+    write(c);
+    crc = crc16Add(c, crc);
+  }
+
+  // output padding
+  uint16_t pad = (4-(len&3))&3;
+  uint8_t temp = 0;
+  while (pad--) {
+    write(temp);
+    crc = crc16Add(temp, crc);
+  }
+}
+*/
+
+// Append the final CRC to the request and finish the request
+void STMClient::Request(void) {
+  write((uint8_t*)&crc, 2);
+  _serial->putc(SLIP_END);
+}
+
+//===== Initialization
+
+void STMClient::init() {
+  _proto.buf = _protoBuf;
+  _proto.bufSize = sizeof(_protoBuf);
+  _proto.dataLen = 0;
+  _proto.isEsc = 0;
+}
+
+STMClient::STMClient(Serial* serial) :
+_serial(serial) {
+  _debugEn = false;
+  init();
+}
+
+STMClient::STMClient(Serial* serial, Serial* debug) :
+_debug(debug), _serial(serial) {
+  _debugEn = true;
+  init();
+}
+
+void STMClient::DBG(const char* info) {
+  if (_debugEn) _debug->printf(info);
+}
+
+//===== Responses
+
+// Wait for a response for a given timeout
+STMClientPacket *STMClient::WaitReturn(uint32_t timeout) {
+  uint32_t wait = millis();
+  while (millis() - wait < timeout) {
+    STMClientPacket *packet = Process();
+    if (packet != NULL) return packet;
+  }
+  return NULL;
+}
+
+//===== CRC hSTMper functions
+
+uint16_t STMClient::crc16Add(unsigned char b, uint16_t acc)
+{
+  acc ^= b;
+  acc = (acc >> 8) | (acc << 8);
+  acc ^= (acc & 0xff00) << 4;
+  acc ^= (acc >> 8) >> 4;
+  acc ^= (acc & 0xff00) >> 5;
+  return acc;
+}
+
+uint16_t STMClient::crc16Data(const unsigned char *data, uint16_t len, uint16_t acc)
+{
+  for (uint16_t i=0; i<len; i++)
+    acc = crc16Add(*data++, acc);
+  return acc;
+}
+
+//===== Basic requests built into STMClient
+
+bool STMClient::Sync(uint32_t timeout) {
+  //_debug->printf("syncing...");
+  wait(0.5);
+  // send sync request
+  Request(CMD_SYNC, (uint32_t)&wifiCb, 0);
+  Request();
+  
+  // empty the response queue hoping to find the wifiCb address
+  STMClientPacket *packet;
+  while ((packet = WaitReturn(timeout)) != NULL) {
+    if (packet->value == (uint32_t)&wifiCb) 
+    { 
+    //    _debug->printf("SYNC!");  
+    //    wait(0.5); 
+        return true; 
+    }
+    _debug->printf("BAD: %s /n/r", packet->value);
+  }
+  
+  // doesn't look like we got a real response
+  return false;
+}
+
+void STMClient::GetWifiStatus(void) {
+  Request(CMD_WIFI_STATUS, 0, 0);
+  Request();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClient.h	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,116 @@
+#ifndef _STM_CLIENT_H_
+#define _STM_CLIENT_H_
+
+#include "mbed.h"
+#include "STMClientResponse.h"
+#include "FP.h"
+
+#define ESP_TIMEOUT 2000
+
+// Enumeration of commands supported by esp-link, this needs to match the definition in
+// esp-link!
+typedef enum {
+  CMD_NULL = 0,     // null, mainly to prevent 0 from doing something bad
+  CMD_SYNC,         // synchronize, starts the protocol
+  CMD_RESP_V,       // response with a value
+  CMD_RESP_CB,      // response with a callback
+  CMD_WIFI_STATUS,  // get the wifi status
+  CMD_CB_ADD,       // add a custom callback
+  CMD_CB_EVENTS,    // ???
+  CMD_GET_TIME,     // get current time in seconds since the unix epoch
+  //CMD_GET_INFO,
+
+  CMD_MQTT_SETUP = 10,
+  CMD_MQTT_PUBLISH,
+  CMD_MQTT_SUBSCRIBE,
+  CMD_MQTT_LWT,
+  CMD_MQTT_EVENTS,
+
+  CMD_REST_SETUP = 20,
+  CMD_REST_REQUEST,
+  CMD_REST_SETHEADER,
+  CMD_REST_EVENTS
+
+} CmdName;
+
+enum WIFI_STATUS {
+  STATION_IDLE = 0,
+  STATION_CONNECTING,
+  STATION_WRONG_PASSWORD,
+  STATION_NO_AP_FOUND,
+  STATION_CONNECT_FAIL,
+  STATION_GOT_IP
+};
+
+typedef struct {
+  uint8_t* buf;
+  uint16_t bufSize;
+  uint16_t dataLen;
+  uint8_t isEsc;
+} STMClientProtocol;
+
+class STMClient {
+  public:
+    //Make the serial process interrupt driven
+  
+    // Create an esp-link client based on a stream and with a specified debug output stream.
+    STMClient(Serial* serial, Serial* debug);
+    
+    // Create an esp-link client based on a stream with no debug output
+    STMClient(Serial* serial);
+
+    Serial* _debug;
+
+    //== Requests
+    // Start a request. cmd is the command to execute, value is either the address of a function
+    // to call with a response or a first argument to the command if there is no CB.
+    // Argc is the number of additional arguments
+    void Request(uint16_t cmd, uint32_t value, uint16_t argc);
+    
+    // Add a data block as argument to a request
+    void Request(const void* data, uint16_t len);
+    
+    // Add a data block from flash as argument to a request
+    //void Request(const __FlashStringHelper* data, uint16_t len); //commented out for now...
+    
+    // Finish a request
+    void Request(void);
+
+    //== Responses
+    // Process the input stream, call this in loop() to dispatch call-back based responses.
+    // Callbacks are invoked with an STMClientResponse pointer as argument.
+    // Returns the STMClientPacket if a non-callback response was received, typically this is
+    // used to create an STMClientResponse. Returns NULL if no response needs to be processed.
+    STMClientPacket *Process(void);
+    
+    // Busy wait for a response with a timeout in milliseconds, returns an STMClientPacket
+    // if a response was recv'd and NULL otherwise. The STMClientPacket is typically used to
+    // create an STMClientResponse.
+    STMClientPacket *WaitReturn(uint32_t timeout=ESP_TIMEOUT);
+
+    //== Commands built-into STMClient
+    // Initialize and synchronize communication with esp-link with a timeout in milliseconds,
+    // and remove all existing callbacks. Registers the wifiCb and returns true on success
+    bool Sync(uint32_t timeout=ESP_TIMEOUT);
+    // Request the wifi status
+    void GetWifiStatus(void);
+
+    // Callback for wifi status changes that must be attached before calling Sync
+    FP<void, void*> wifiCb;
+
+  //private:
+    Serial* _serial;
+    bool _debugEn;
+    uint16_t crc;
+    STMClientProtocol _proto;
+    uint8_t _protoBuf[128];
+
+    void init();
+    void DBG(const char* info);
+    STMClientPacket *protoCompletedCb(void);
+    void write(uint8_t data);
+    void write(void* data, uint16_t len);
+    uint16_t crc16Add(unsigned char b, uint16_t acc);
+    uint16_t crc16Data(const unsigned char *data, uint16_t len, uint16_t acc);
+};
+#endif // _EL_CLIENT_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClientCmd.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,12 @@
+
+#include "STMClientCmd.h"
+
+STMClientCmd::STMClientCmd(STMClient* elc) :_elc(elc) {}
+
+uint32_t STMClientCmd::GetTime() {
+  _elc->Request(CMD_GET_TIME, 0, 0);
+  _elc->Request();
+
+  STMClientPacket *pkt = _elc->WaitReturn();
+  return pkt ? pkt->value : 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClientCmd.h	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,19 @@
+// MiscSTMlaneous commands
+
+#ifndef _STM_CLIENT_CMD_H_
+#define _STM_CLIENT_CMD_H_
+
+#include "STMClient.h"
+#include "FP.h"
+
+class STMClientCmd {
+  public:
+    // Constructor
+    STMClientCmd(STMClient* elc);
+    // Get the current time in seconds since the epoch, 0 if the time is unknown
+    uint32_t GetTime();
+
+  private:
+    STMClient* _elc;
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClientResponse.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,87 @@
+#include "STMClientResponse.h"
+
+STMClientResponse::STMClientResponse(STMClientPacket* packet) {
+  _cmd = packet;
+  _arg_ptr = _cmd->args;
+  _arg_num = 0;
+}
+
+STMClientResponse::STMClientResponse(void* packet) {
+  _cmd = (STMClientPacket *)packet;
+  _arg_ptr = _cmd->args;
+  _arg_num = 0;
+}
+
+int16_t STMClientResponse::popArgPtr(void **data) {
+  if (_arg_num >= _cmd->argc) return -1;
+
+  uint16_t len = *(uint16_t*)_arg_ptr;
+  uint16_t pad = (4-((len+2)&3))&3;    // pad to next multiple of 4, including length
+  _arg_ptr += 2;
+  _arg_num++;
+
+  *data = _arg_ptr;
+  _arg_ptr += len + pad;
+  return len;
+}
+
+int16_t STMClientResponse::popArg(void* d, uint16_t maxLen) {
+  if (_arg_num >= _cmd->argc) return -1;
+
+  uint16_t len = *(uint16_t*)_arg_ptr;
+  uint16_t pad = (4-((len+2)&3))&3;    // pad to next multiple of 4, including length
+  _arg_ptr += 2;
+  _arg_num++;
+
+  uint8_t *data = (uint8_t *)d;
+  uint16_t l = len > maxLen ? maxLen : len;
+  uint8_t *p = _arg_ptr;
+  while (l--)
+    *data++ = *p++;
+
+  _arg_ptr += len + pad;
+  return len;
+}
+
+void STMClientResponse::popChar(char* buffer) {
+  uint16_t len = *(uint16_t*)_arg_ptr;
+  uint16_t pad = (4-((len+2)&3))&3;    // pad to next multiple of 4, including length
+  _arg_ptr += 2;
+  _arg_num++;
+
+  uint8_t i;
+  for (i = 0; i < len; i++) {
+    buffer[i] = (char)*_arg_ptr++;
+  }
+  buffer[i] = '\0';
+
+  _arg_ptr += pad;
+}
+
+string STMClientResponse::popString() {
+  string ret;
+  uint16_t len = *(uint16_t*)_arg_ptr;
+  uint16_t pad = (4-((len+2)&3))&3;    // pad to next multiple of 4, including length
+  _arg_ptr += 2;
+  _arg_num++;
+
+  while (len--)
+    ret += (char)*_arg_ptr++;
+
+  _arg_ptr += pad;
+  return ret;
+}
+
+void STMClientResponse::popString(string* data) {
+  uint16_t len = *(uint16_t*)_arg_ptr;
+  uint16_t pad = (4-((len+2)&3))&3;    // pad to next multiple of 4, including length
+  _arg_ptr += 2;
+  _arg_num++;
+
+  while (len--)
+    //string.append((char)*_arg_ptr++);
+    //strcat (data,(char)*_arg_ptr++);
+    data += (char)*_arg_ptr++;
+
+  _arg_ptr += pad;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClientResponse.h	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,52 @@
+#ifndef _STM_CLIENT_RESPONSE_H_
+#define _STM_CLIENT_RESPONSE_H_
+
+#if _MSC_VER
+#define PACKED
+#else
+#define PACKED __attribute__ ((__packed__))
+#endif
+
+#include <mbed.h>
+#include <string> 
+
+typedef struct PACKED {
+  uint16_t cmd;            // command to execute
+  uint16_t argc;           // number of arguments
+  uint32_t value;          // callback to invoke, NULL if none; or response value
+  uint8_t  args[0];
+} STMClientPacket;
+
+class STMClientResponse {
+  public:
+    // Create a response from a packet, this is done internally in STMClient
+    STMClientResponse(STMClientPacket* packet);
+    STMClientResponse(void *packet);
+
+    // Accessors to the response fields
+    uint16_t argc() { return _cmd->argc; }
+    uint16_t cmd() { return _cmd->cmd; }
+    uint32_t value() { return _cmd->value; }
+
+    // Return the length of the next argument
+    uint16_t argLen() { return *(uint16_t*)_arg_ptr; }
+    // Pop one argument from the response, returns the actual length. Returns -1 if there is
+    // no arg left.
+    int16_t popArg(void* data, uint16_t maxLen);
+    // Pop one argument as a poiner from the response, returns the actual length.
+    int16_t popArgPtr(void **data);
+    // Pop one argument into a string buffer and append a null character. The buffer needs to
+    // be large enough (argLen()+1)
+    void popChar(char* buffer);
+    // Pop one argument into a String buffer
+    string popString();
+    // Pop one argument into a String buffer
+    void popString(string* data);
+
+  private:
+    uint16_t _arg_num;
+    uint8_t* _arg_ptr;
+    STMClientPacket* _cmd;
+};
+
+#endif // _STM_CLIENT_RESPONSE_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClientRest.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,115 @@
+#include "STMClientRest.h"
+#include "millis.h"
+
+typedef enum {
+  HEADER_GENERIC = 0,
+  HEADER_CONTENT_TYPE,
+  HEADER_USER_AGENT
+} HEADER_TYPE;
+
+STMClientRest::STMClientRest(STMClient *e)
+{
+  _elc = e;
+  remote_instance = -1;
+}
+
+void STMClientRest::restCallback(void *res)
+{
+  if (!res) return;
+
+  STMClientResponse *resp = (STMClientResponse *)res;
+
+  resp->popArg(&_status, sizeof(_status));
+  _elc->_debug->printf("REST code %i \n\r",_status);
+
+  _len = resp->popArgPtr(&_data);
+}
+
+int STMClientRest::begin(const char* host, uint16_t port, bool security)
+{
+  uint8_t sec = !!security;
+  restCb.attach(this, &STMClientRest::restCallback);
+
+  _elc->Request(CMD_REST_SETUP, (uint32_t)&restCb, 3);
+  _elc->Request(host, strlen(host));
+  _elc->Request(&port, 2);
+  _elc->Request(&sec, 1);
+  _elc->Request();
+
+  STMClientPacket *pkt = _elc->WaitReturn();
+  if (pkt && (int32_t)pkt->value >= 0) {
+    remote_instance = pkt->value;
+    return 0;
+  }
+  return (int)pkt->value;
+}
+
+void STMClientRest::request(const char* path, const char* method, const char* data, int len)
+{
+  _status = 0;
+  if (remote_instance < 0) return;
+  if (data != 0 && len > 0) _elc->Request(CMD_REST_REQUEST, remote_instance, 3);
+  else                      _elc->Request(CMD_REST_REQUEST, remote_instance, 2);
+  _elc->Request(method, strlen(method));
+  _elc->Request(path, strlen(path));
+  if (data != NULL && len > 0) {
+    _elc->Request(data, len);
+  }
+
+  _elc->Request();
+}
+
+void STMClientRest::request(const char* path, const char* method, const char* data)
+{
+  request(path, method, data, strlen(data));
+}
+
+void STMClientRest::get(const char* path, const char* data) { request(path, "GET", data); }
+void STMClientRest::post(const char* path, const char* data) { request(path, "POST", data); }
+void STMClientRest::put(const char* path, const char* data) { request(path, "PUT", data); }
+void STMClientRest::del(const char* path) { request(path, "DELETE", 0); }
+
+void STMClientRest::setHeader(const char* value)
+{
+  uint8_t header_index = HEADER_GENERIC;
+  _elc->Request(CMD_REST_SETHEADER, remote_instance, 2);
+  _elc->Request(&header_index, 1);
+  _elc->Request(value, strlen(value));
+  _elc->Request();
+}
+
+void STMClientRest::setContentType(const char* value)
+{
+  uint8_t header_index = HEADER_CONTENT_TYPE;
+  _elc->Request(CMD_REST_SETHEADER, remote_instance, 2);
+  _elc->Request(&header_index, 1);
+  _elc->Request(value, strlen(value));
+  _elc->Request();
+}
+
+void STMClientRest::setUserAgent(const char* value)
+{
+  uint8_t header_index = HEADER_USER_AGENT;
+  _elc->Request(CMD_REST_SETHEADER, remote_instance, 2);
+  _elc->Request(&header_index, 1);
+  _elc->Request(value, strlen(value));
+  _elc->Request();
+}
+
+uint16_t STMClientRest::getResponse(char* data, uint16_t maxLen)
+{
+  if (_status == 0) return 0;
+  memcpy(data, _data, _len>maxLen?maxLen:_len);
+  int16_t s = _status;
+  _status = 0;
+  return s;
+}
+
+uint16_t STMClientRest::waitResponse(char* data, uint16_t maxLen, uint32_t timeout)
+{
+  uint32_t wait = millis();
+  while (_status == 0 && (millis() - wait < timeout)) {
+    _elc->Process();
+  }
+  return getResponse(data, maxLen);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/STMClientRest.h	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,88 @@
+
+#ifndef _STM_CLIENT_REST_H_
+#define _STM_CLIENT_REST_H_
+
+#include "FP.h"
+#include "STMClient.h"
+
+// Default timeout for REST requests when waiting for a response
+#define DEFAULT_REST_TIMEOUT  5000
+
+typedef enum {
+  HTTP_STATUS_OK = 200
+} HTTP_STATUS;
+
+// The STMClientRest class makes simple REST requests to a remote server. Each instance
+// is used to communicate with one server and multiple instances can be created to make
+// requests to multiple servers.
+// The STMClientRest class does not support concurrent requests to the same server because
+// only a single response can be recevied at a time and the responses of the two requests
+// may arrive out of order.
+// A major limitation of the REST class is that it does not store the response body. The
+// response status is saved in the class instance, so after a request completes and before
+// the next request is made a call to getResponse will return the status. However, only a pointer
+// to the response body is saved, which means that if any other message arrives and is
+// processed then the response body is overwritten by it. What this means is that if you
+// need the response body you best use waitResponse or ensure that any call to STMClient::process
+// is followed by a call to getResponse. Ideally someone improves this class to take a callback
+// into the user's sketch?
+// Another limitation is that the response body is 100 chars long at most, this is due to the
+// limitation of the SLIP protocol buffer available.
+class STMClientRest {
+  public:
+    STMClientRest(STMClient *e);
+
+    // Initialize communication to a remote server, this communicates with esp-link but does not
+    // open a connection to the remote server. Host may be a hostname or an IP address,
+    // security causes HTTPS to be used (not yet supported). Returns 0 if the set-up is
+    // successful, returns a negative error code if it failed.
+    int begin(const char* host, uint16_t port=80, bool security=false);
+
+    // Make a request to the remote server. The data must be null-terminated
+    void request(const char* path, const char* method, const char* data=NULL);
+
+    // Make a request to the remote server.
+    void request(const char* path, const char* method, const char* data, int len);
+
+    // Make a GET request to the remote server with NULL-terminated data
+    void get(const char* path, const char* data=NULL);
+
+    // Make a POST request to the remote server with NULL-terminated data
+    void post(const char* path, const char* data);
+
+    // Make a PUT request to the remote server with NULL-terminated data
+    void put(const char* path, const char* data);
+
+    // Make a DELETE request to the remote server
+    void del(const char* path);
+
+    // Retrieve the response from the remote server, returns the HTTP status code, 0 if no
+    // response (may need to wait longer)
+    uint16_t getResponse(char* data, uint16_t maxLen);
+
+    // Wait for the response from the remote server, returns the HTTP status code, 0 if no
+    // response (timeout occurred)
+    uint16_t waitResponse(char* data, uint16_t maxLen, uint32_t timeout=DEFAULT_REST_TIMEOUT);
+
+    // Set the user-agent for all subsequent requests
+    void setUserAgent(const char* value);
+
+    // Set the Content-Type Header for all subsequent requests
+    void setContentType(const char* value);
+
+    // Set a custom header for all subsequent requests
+    void setHeader(const char* value);
+
+  private:
+    int32_t remote_instance;
+    STMClient *_elc;
+    void restCallback(void* resp);
+    FP<void, void*> restCb;
+
+    int16_t _status;
+    uint16_t _len;
+    void *_data;
+
+
+};
+#endif // _STM_CLIENT_REST_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/library.json	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,16 @@
+{
+  "name": "STMClient",
+  "keywords": "wifi, mqtt, rest",
+  "description": "Wifi library (Chip ESP8266 Wifi SoC) using SLIP protocol via Serial port",
+  "url": "https://github.com/",
+  "repository":
+  {
+    "type": "git",
+    "url": "https://github.com/"
+  },
+  "include": "STMClient",
+  "frameworks": "STM32-F446RE",
+  "platforms": [
+    "Nucleo"
+  ]
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,139 @@
+/**
+ * Simple example to demo the STM-Client REST calls
+ */
+#include "mbed.h"
+#include <STMClient.h>
+#include <STMClientRest.h>
+
+/*-------- Check if platform compatible ----------*/
+#if DEVICE_SERIAL_ASYNCH
+Serial debugSerial(SERIAL_TX, SERIAL_RX);
+Serial espSerial(PA_0, PA_1);
+#else
+    #warning "Platform not compatible with Low Power APIs for Serial"
+    Serial debugSerial(SERIAL_TX, SERIAL_RX);
+    Serial espSerial(PA_0, PA_1);
+#endif
+
+
+DigitalOut led1(LED1);             
+
+// Initialize a connection to esp-link using the normal hardware serial port both for
+// SLIP and for debug messages.
+STMClient esp(&espSerial, &debugSerial);
+
+
+// Initialize a REST client on the connection to esp-link
+STMClientRest rest(&esp);
+
+bool wifiConnected = false;
+
+// Callback made from esp-link to notify of wifi status changes
+// Here we print something out and set a global flag
+void wifiCb(void *response) {
+  debugSerial.printf("waiting for wifi status...\n\r"); //debug
+  STMClientResponse *res = (STMClientResponse*)response;
+  if (res->argc() == 1) {
+    uint8_t status;
+    res->popArg(&status, 1);
+    debugSerial.printf("waiting for wifi status...\n\r");
+    if(status == STATION_GOT_IP) {
+      debugSerial.printf("WIFI CONNECTED");
+      wifiConnected = true;
+    } else {
+      debugSerial.printf("WIFI NOT READY: %i",status);
+      //Serial.printf(status);
+      wifiConnected = false;
+    }
+  }
+}
+
+#define BUFLEN 266
+
+int loop() {
+  //debugSerial.printf("begin main loop \n\r");
+  // process any callbacks coming from esp_link
+  esp.Process();
+  debugSerial.printf("Wifi Connected: %i \n\r",wifiConnected);
+  // if we're connected make an HTTP request
+  while(wifiConnected) {
+    // Request /utc/now from the previously set-up server
+    rest.get("/utc/now");
+
+    char response[BUFLEN];
+    memset(response, 0, BUFLEN);
+    uint16_t code = rest.waitResponse(response, BUFLEN);
+    if(code == HTTP_STATUS_OK){
+      debugSerial.printf("STM: GET successful: %s\n\r", response);
+    } else {
+      debugSerial.printf("STM: GET failed: %i\n\r",code);
+      return code;
+    }
+    wait(1);
+  }
+  return 0; 
+  
+}
+
+int main() {
+  led1=0;
+  debugSerial.baud(115200);   // the baud rate here needs to match the esp-link config
+  espSerial.baud(115200);
+  
+  debugSerial.printf("STM-Client starting!\n\r");
+  wait(0.5);
+  
+  espSerial.printf("STM-Client starting!\n\r");
+  wait(0.5);
+
+  // Sync-up with esp-link, this is required at the start of any sketch and initializes the
+  // callbacks to the wifi status change callback. The callback gets called with the initial
+  // status right after Sync() below completes.
+  esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
+  bool ok;
+  do {
+      //debugSerial.printf("main syncing..\n\r");
+      wait(0.5);
+    ok = esp.Sync();      // sync up with esp-link, blocks for up to 2 seconds
+    if (!ok){ 
+        debugSerial.printf("STM-Client sync failed!\n\r");
+        wait(0.5);
+        }
+  } while(!ok);
+  
+  debugSerial.printf("STM-Client synced!\n\r");
+
+  // Get immediate wifi status info for demo purposes. This is not normally used because the
+  // wifi status callback registered above gets called immediately. 
+  esp.GetWifiStatus();
+  STMClientPacket *packet;
+  if ((packet=esp.WaitReturn()) != NULL) 
+  {
+    //debugSerial.printf("Wifi status: %i\n\r", packet->value);
+    //debugSerial.printf("waiting for wifi status...\n\r");
+    if(packet->value == 2) { ///ideally this would coincide with STATION_GOT_IP... 
+      debugSerial.printf("WIFI CONNECTED\n\r");
+      wifiConnected = true;
+    } else {
+      debugSerial.printf("WIFI NOT READY: %i\n\r",packet->value);
+      //Serial.printf(status);
+      wifiConnected = false;
+    }
+  }
+  
+
+  // Set up the REST client to talk to www.timeapi.org, this doesn't connect to that server,
+  // it just sets-up stuff on the esp-link side
+  int err = rest.begin("www.timeapi.org");
+  if (err != 0) {
+    debugSerial.printf("REST begin failed: %i\n\r",err);
+    while(1) ;
+  }
+  debugSerial.printf("STM-REST ready\n\r");
+  int loopStat = 0;
+  while(loopStat == 0){
+      debugSerial.printf("status: %i\n\r",loopStat);
+      loopStat = loop();
+      wait(1);
+    } 
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6c34061e7c34
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/millis.cpp	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,16 @@
+#include "mbed.h"
+#include "millis.h"
+ 
+volatile unsigned long  _millis;
+ 
+void millisStart(void) {
+    SysTick_Config(SystemCoreClock / 1000);
+}
+ 
+extern "C" void SysTick_Handler(void) {
+    _millis++;
+}
+ 
+unsigned long millis(void) {
+    return _millis;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/millis.h	Thu Jul 14 20:38:18 2016 +0000
@@ -0,0 +1,7 @@
+#ifndef MILLIS_H
+#define MILLIS_H
+ 
+void           millisStart(void);
+unsigned long  millis(void);
+ 
+#endif
\ No newline at end of file