Api wrapper to communicate with EVRYTHNG's Engine.

Dependencies:   EthernetInterface mbed-rtos

Dependents:   EvrythngApiExample

Revision:
0:d38d192c2f5f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EvrythngApi.cpp	Thu Aug 30 13:20:01 2012 +0000
@@ -0,0 +1,227 @@
+/*
+ * (c) Copyright 2012 EVRYTHNG Ltd London / Zurich
+ * www.evrythng.com
+ *
+ * --- DISCLAIMER ---
+ *
+ * EVRYTHNG provides this source code "as is" and without warranty of any kind,
+ * and hereby disclaims all express or implied warranties, including without
+ * limitation warranties of merchantability, fitness for a particular purpose,
+ * performance, accuracy, reliability, and non-infringement.
+ *
+ * Author: Michel Yerly
+ *
+ */
+#include "EvrythngApi.h"
+
+#include <string>
+
+#include "util.h"
+#include "evry_error.h"
+#include "JsonParser.h"
+
+//#define DEBUG_EVRYTHNG_API
+
+using namespace std;
+
+const int HTTP_OK = 200;
+
+const char* THNG_PATH = "/thngs/";
+const char* THNG_PROP_PATH = "/properties/";
+
+EvrythngApi::EvrythngApi(const string& token, const string& host, int port)
+{
+    this->token = token;
+    this->host = host;
+    this->port = port;
+}
+
+EvrythngApi::~EvrythngApi()
+{
+}
+
+int EvrythngApi::getThngPropertyValue(const string& thngId, const string& key, string& value)
+{
+    string path = THNG_PATH;
+    path += thngId;
+    path += THNG_PROP_PATH;
+    path += key;
+    path += "?from=latest";
+    string res;
+    int err;
+    int code;
+    if ((err = httpGet(path, res, code)) != 0) return err;
+    if (code != HTTP_OK) return EVRY_ERR_UNEXPECTEDHTTPSTATUS;
+    JsonParser json;
+    json.parse(res.c_str());
+    JsonValue* doc = json.getDocument();
+    const char* v = doc->getString("0/value");
+    if (v) {
+        value.assign(v);
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+int EvrythngApi::setThngPropertyValue(const std::string& thngId, const std::string& key, const std::string& value, int64_t timestamp)
+{
+    char strTimestamp[21];
+    char* end;
+    sprinti64(strTimestamp, timestamp, &end);
+    *end = '\0';
+
+    string path = THNG_PATH;
+    path += thngId;
+    path += THNG_PROP_PATH;
+    path += key;
+
+    string json = "[{\"timestamp\":";
+    json += strTimestamp;
+    json += ",\"value\":\"";
+    json += value;
+    json += "\"}]";
+
+    string res;
+    int err;
+    int code;
+    if ((err = httpPut(path, json, res, code)) != 0) return err;
+    if (code != HTTP_OK) return EVRY_ERR_UNEXPECTEDHTTPSTATUS;
+
+    return 0;
+}
+
+
+int EvrythngApi::httpRequest(HttpMethod method, const string& path, const string& content, string& out, int& codeOut)
+{
+    int ret;
+
+    const char* strMethod;
+    switch (method) {
+        case GET:
+            strMethod = "GET";
+            break;
+        case PUT:
+            strMethod = "PUT";
+            break;
+        case POST:
+            strMethod = "POST";
+            break;
+        case DELETE:
+            strMethod = "DELETE";
+            break;
+        default:
+            return EVRY_ERR_UNSUPPORTED;
+    }
+
+    char contentLength[16];
+    snprintf(contentLength, sizeof(contentLength), "%d", content.size());
+
+    string req = strMethod;
+    req += " ";
+    req += path;
+    req += " HTTP/1.0\r\n"
+           "Host: ";
+    req += host;
+    req += "\r\n"
+           "Accept: application/json\r\n"
+           "Content-Length: ";
+    req += contentLength;
+    req += "\r\n"
+           "Content-Type: application/json\r\n"
+           "Connection: close\r\n"
+           "Authorization: ";
+    req += token;
+    req += "\r\n\r\n";
+
+    req += content;
+
+#ifdef DEBUG_EVRYTHNG_API
+    dbg.printf("%s\r\n\r\n", req.c_str());
+#endif
+
+    TCPSocketConnection socket;
+
+    out.clear();
+
+    string res;
+
+    if (socket.connect(host.c_str(), port) == 0) {
+
+        char* snd = new char[req.size()+1];
+        req.copy(snd, req.size());
+        snd[req.size()]='\0';
+        bool sent = socket.send_all(snd, req.size()) >= 0;
+        delete[] snd;
+
+        if (sent) {
+
+            char rcv[256];
+
+            int r;
+            while (true) {
+                r = socket.receive(rcv, sizeof(rcv));
+                if (r <= 0)
+                    break;
+                res.append(rcv, r);
+            }
+
+            ret = EVRY_ERR_OK;
+
+        } else {
+            ret = EVRY_ERR_CANTSEND;
+        }
+
+        socket.close();
+
+    } else {
+        ret = EVRY_ERR_CANTCONNECT;
+    }
+    
+#ifdef DEBUG_EVRYTHNG_API
+    dbg.printf("%s", res.c_str());
+#endif
+
+    if (res.compare(0,5,"HTTP/") != 0) {
+        return EVRY_ERR_UNKNOWN;
+    }
+
+    int spPos = res.find(' ', 5);
+    if (spPos == string::npos) {
+        return EVRY_ERR_UNKNOWN;
+    }
+
+    // TODO: check str length
+    int code = atoi(res.c_str()+spPos+1);
+    if (code < 100 || code > 999) {
+        return EVRY_ERR_UNKNOWN;
+    }
+    codeOut = code;
+
+    int startContent = res.find("\r\n\r\n");
+    if (startContent != string::npos) {
+        out.append(res.substr(startContent+4,res.size()-startContent-4));
+    }
+
+    return ret;
+}
+
+int EvrythngApi::httpPut(const string& path, const string& json, string& out, int& codeOut)
+{
+    return httpRequest(PUT, path, json, out, codeOut);
+}
+
+int EvrythngApi::httpGet(const string& path, string& out, int& codeOut)
+{
+    return httpRequest(GET, path, "", out, codeOut);
+}
+
+int EvrythngApi::httpPost(const string& path, const string& json, string& out, int& codeOut)
+{
+    return httpRequest(POST, path, json, out, codeOut);
+}
+
+int EvrythngApi::httpDelete(const string& path, string& out, int& codeOut)
+{
+    return httpRequest(DELETE, path, "", out, codeOut);
+}
\ No newline at end of file