Evrythng API for W5500, WIZ550io

Dependencies:   W5500Interface

Dependents:   EvrythngApiExampleW5500

Fork of EvrythngApi by Evry Thng

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EvrythngApi.cpp Source File

EvrythngApi.cpp

00001 /*
00002  * (c) Copyright 2012 EVRYTHNG Ltd London / Zurich
00003  * www.evrythng.com
00004  *
00005  * --- DISCLAIMER ---
00006  *
00007  * EVRYTHNG provides this source code "as is" and without warranty of any kind,
00008  * and hereby disclaims all express or implied warranties, including without
00009  * limitation warranties of merchantability, fitness for a particular purpose,
00010  * performance, accuracy, reliability, and non-infringement.
00011  *
00012  * Author: Michel Yerly
00013  *
00014  */
00015 #include "EvrythngApi.h"
00016 
00017 #include <string>
00018 
00019 #include "util.h"
00020 #include "evry_error.h"
00021 #include "JsonParser.h"
00022 
00023 //#define DEBUG_EVRYTHNG_API
00024 
00025 using namespace std;
00026 
00027 const int HTTP_OK = 200;
00028 
00029 const char* THNG_PATH = "/thngs/";
00030 const char* THNG_PROP_PATH = "/properties/";
00031 
00032 EvrythngApi::EvrythngApi(const string& token, const string& host, int port)
00033 {
00034     this->token = token;
00035     this->host = host;
00036     this->port = port;
00037 }
00038 
00039 EvrythngApi::~EvrythngApi()
00040 {
00041 }
00042 
00043 int EvrythngApi::getThngPropertyValue(const string& thngId, const string& key, string& value)
00044 {
00045     string path = THNG_PATH;
00046     path += thngId;
00047     path += THNG_PROP_PATH;
00048     path += key;
00049     path += "?from=latest";
00050     string res;
00051     int err;
00052     int code;
00053     if ((err = httpGet(path, res, code)) != 0) return err;
00054     if (code != HTTP_OK) return EVRY_ERR_UNEXPECTEDHTTPSTATUS;
00055     JsonParser json;
00056     json.parse(res.c_str());
00057     JsonValue* doc = json.getDocument();
00058     const char* v = doc->getString("0/value");
00059     if (v) {
00060         value.assign(v);
00061         return 0;
00062     } else {
00063         return -1;
00064     }
00065 }
00066 
00067 int EvrythngApi::setThngPropertyValue(const std::string& thngId, const std::string& key, const std::string& value, int64_t timestamp)
00068 {
00069     char strTimestamp[21];
00070     char* end;
00071     sprinti64(strTimestamp, timestamp, &end);
00072     *end = '\0';
00073 
00074     string path = THNG_PATH;
00075     path += thngId;
00076     path += THNG_PROP_PATH;
00077     path += key;
00078 
00079     string json = "[{\"timestamp\":";
00080     json += strTimestamp;
00081     json += ",\"value\":\"";
00082     json += value;
00083     json += "\"}]";
00084 
00085     string res;
00086     int err;
00087     int code;
00088     if ((err = httpPut(path, json, res, code)) != 0) return err;
00089     if (code != HTTP_OK) return EVRY_ERR_UNEXPECTEDHTTPSTATUS;
00090 
00091     return 0;
00092 }
00093 
00094 
00095 int EvrythngApi::httpRequest(HttpMethod method, const string& path, const string& content, string& out, int& codeOut)
00096 {
00097     int ret;
00098 
00099     const char* strMethod;
00100     switch (method) {
00101         case GET:
00102             strMethod = "GET";
00103             break;
00104         case PUT:
00105             strMethod = "PUT";
00106             break;
00107         case POST:
00108             strMethod = "POST";
00109             break;
00110         case DELETE:
00111             strMethod = "DELETE";
00112             break;
00113         default:
00114             return EVRY_ERR_UNSUPPORTED;
00115     }
00116 
00117     char contentLength[16];
00118     snprintf(contentLength, sizeof(contentLength), "%d", content.size());
00119 
00120     string req = strMethod;
00121     req += " ";
00122     req += path;
00123     req += " HTTP/1.0\r\n"
00124            "Host: ";
00125     req += host;
00126     req += "\r\n"
00127            "Accept: application/json\r\n"
00128            "Content-Length: ";
00129     req += contentLength;
00130     req += "\r\n"
00131            "Content-Type: application/json\r\n"
00132            "Connection: close\r\n"
00133            "Authorization: ";
00134     req += token;
00135     req += "\r\n\r\n";
00136 
00137     req += content;
00138 
00139 #ifdef DEBUG_EVRYTHNG_API
00140     dbg.printf("%s\r\n\r\n", req.c_str());
00141 #endif
00142 
00143     TCPSocketConnection socket;
00144 
00145     out.clear();
00146 
00147     string res;
00148 
00149     if (socket.connect(host.c_str(), port) == 0) {
00150 
00151         char* snd = new char[req.size()+1];
00152         req.copy(snd, req.size());
00153         snd[req.size()]='\0';
00154         bool sent = socket.send_all(snd, req.size()) >= 0;
00155         delete[] snd;
00156 
00157         if (sent) {
00158 
00159             char rcv[256];
00160             int r;
00161             while (true) {
00162                 r = socket.receive(rcv, sizeof(rcv));
00163                 if (r <= 0)
00164                     break;
00165                 res.append(rcv, r);
00166             }
00167 
00168             ret = EVRY_ERR_OK;
00169 
00170         } else {
00171             ret = EVRY_ERR_CANTSEND;
00172         }
00173 
00174         socket.close();
00175 
00176     } else {
00177         ret = EVRY_ERR_CANTCONNECT;
00178     }
00179 
00180 #ifdef DEBUG_EVRYTHNG_API
00181     dbg.printf("%s", res.c_str());
00182 #endif
00183 
00184     if (res.compare(0,5,"HTTP/") != 0) {
00185         return EVRY_ERR_UNKNOWN;
00186     }
00187 
00188     int spPos = res.find(' ', 5);
00189     if (spPos == string::npos) {
00190         return EVRY_ERR_UNKNOWN;
00191     }
00192 
00193     // TODO: check str length
00194     int code = atoi(res.c_str()+spPos+1);
00195     if (code < 100 || code > 999) {
00196         return EVRY_ERR_UNKNOWN;
00197     }
00198     codeOut = code;
00199 
00200     int startContent = res.find("\r\n\r\n");
00201     if (startContent != string::npos) {
00202         out.append(res.substr(startContent+4,res.size()-startContent-4));
00203     }
00204 
00205     return ret;
00206 }
00207 
00208 int EvrythngApi::httpPut(const string& path, const string& json, string& out, int& codeOut)
00209 {
00210     return httpRequest(PUT, path, json, out, codeOut);
00211 }
00212 
00213 int EvrythngApi::httpGet(const string& path, string& out, int& codeOut)
00214 {
00215     return httpRequest(GET, path, "", out, codeOut);
00216 }
00217 
00218 int EvrythngApi::httpPost(const string& path, const string& json, string& out, int& codeOut)
00219 {
00220     return httpRequest(POST, path, json, out, codeOut);
00221 }
00222 
00223 int EvrythngApi::httpDelete(const string& path, string& out, int& codeOut)
00224 {
00225     return httpRequest(DELETE, path, "", out, codeOut);
00226 }