Everything Example

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of TCPEthernet by Artur Lachowicz

Committer:
lachu
Date:
Tue Jan 24 22:17:00 2017 +0000
Revision:
9:b08a28f659eb
Working Program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lachu 9:b08a28f659eb 1 /*
lachu 9:b08a28f659eb 2 * (c) Copyright 2012 EVRYTHNG Ltd London / Zurich
lachu 9:b08a28f659eb 3 * www.evrythng.com
lachu 9:b08a28f659eb 4 *
lachu 9:b08a28f659eb 5 * --- DISCLAIMER ---
lachu 9:b08a28f659eb 6 *
lachu 9:b08a28f659eb 7 * EVRYTHNG provides this source code "as is" and without warranty of any kind,
lachu 9:b08a28f659eb 8 * and hereby disclaims all express or implied warranties, including without
lachu 9:b08a28f659eb 9 * limitation warranties of merchantability, fitness for a particular purpose,
lachu 9:b08a28f659eb 10 * performance, accuracy, reliability, and non-infringement.
lachu 9:b08a28f659eb 11 *
lachu 9:b08a28f659eb 12 * Author: Michel Yerly
lachu 9:b08a28f659eb 13 *
lachu 9:b08a28f659eb 14 */
lachu 9:b08a28f659eb 15 #include "EvrythngApi.h"
lachu 9:b08a28f659eb 16
lachu 9:b08a28f659eb 17 #include <string>
lachu 9:b08a28f659eb 18
lachu 9:b08a28f659eb 19 #include "util.h"
lachu 9:b08a28f659eb 20 #include "evry_error.h"
lachu 9:b08a28f659eb 21 #include "JsonParser.h"
lachu 9:b08a28f659eb 22
lachu 9:b08a28f659eb 23 //#define DEBUG_EVRYTHNG_API
lachu 9:b08a28f659eb 24
lachu 9:b08a28f659eb 25 using namespace std;
lachu 9:b08a28f659eb 26
lachu 9:b08a28f659eb 27 const int HTTP_OK = 200;
lachu 9:b08a28f659eb 28
lachu 9:b08a28f659eb 29 const char* THNG_PATH = "/thngs/";
lachu 9:b08a28f659eb 30 const char* THNG_PROP_PATH = "/properties/";
lachu 9:b08a28f659eb 31
lachu 9:b08a28f659eb 32 EvrythngApi::EvrythngApi(const string& token, const string& host, int port)
lachu 9:b08a28f659eb 33 {
lachu 9:b08a28f659eb 34 this->token = token;
lachu 9:b08a28f659eb 35 this->host = host;
lachu 9:b08a28f659eb 36 this->port = port;
lachu 9:b08a28f659eb 37 }
lachu 9:b08a28f659eb 38
lachu 9:b08a28f659eb 39 EvrythngApi::~EvrythngApi()
lachu 9:b08a28f659eb 40 {
lachu 9:b08a28f659eb 41 }
lachu 9:b08a28f659eb 42
lachu 9:b08a28f659eb 43 int EvrythngApi::getThngPropertyValue(const string& thngId, const string& key, string& value)
lachu 9:b08a28f659eb 44 {
lachu 9:b08a28f659eb 45 string path = THNG_PATH;
lachu 9:b08a28f659eb 46 path += thngId;
lachu 9:b08a28f659eb 47 path += THNG_PROP_PATH;
lachu 9:b08a28f659eb 48 path += key;
lachu 9:b08a28f659eb 49 path += "?from=latest";
lachu 9:b08a28f659eb 50 string res;
lachu 9:b08a28f659eb 51 int err;
lachu 9:b08a28f659eb 52 int code;
lachu 9:b08a28f659eb 53 if ((err = httpGet(path, res, code)) != 0) return err;
lachu 9:b08a28f659eb 54 if (code != HTTP_OK) return EVRY_ERR_UNEXPECTEDHTTPSTATUS;
lachu 9:b08a28f659eb 55 JsonParser json;
lachu 9:b08a28f659eb 56 json.parse(res.c_str());
lachu 9:b08a28f659eb 57 JsonValue* doc = json.getDocument();
lachu 9:b08a28f659eb 58 const char* v = doc->getString("0/value");
lachu 9:b08a28f659eb 59 if (v) {
lachu 9:b08a28f659eb 60 value.assign(v);
lachu 9:b08a28f659eb 61 return 0;
lachu 9:b08a28f659eb 62 } else {
lachu 9:b08a28f659eb 63 return -1;
lachu 9:b08a28f659eb 64 }
lachu 9:b08a28f659eb 65 }
lachu 9:b08a28f659eb 66
lachu 9:b08a28f659eb 67 int EvrythngApi::setThngPropertyValue(const std::string& thngId, const std::string& key, const std::string& value, int64_t timestamp)
lachu 9:b08a28f659eb 68 {
lachu 9:b08a28f659eb 69 char strTimestamp[21];
lachu 9:b08a28f659eb 70 char* end;
lachu 9:b08a28f659eb 71 sprinti64(strTimestamp, timestamp, &end);
lachu 9:b08a28f659eb 72 *end = '\0';
lachu 9:b08a28f659eb 73
lachu 9:b08a28f659eb 74 string path = THNG_PATH;
lachu 9:b08a28f659eb 75 path += thngId;
lachu 9:b08a28f659eb 76 path += THNG_PROP_PATH;
lachu 9:b08a28f659eb 77 path += key;
lachu 9:b08a28f659eb 78
lachu 9:b08a28f659eb 79 string json = "[{\"timestamp\":";
lachu 9:b08a28f659eb 80 json += strTimestamp;
lachu 9:b08a28f659eb 81 json += ",\"value\":\"";
lachu 9:b08a28f659eb 82 json += value;
lachu 9:b08a28f659eb 83 json += "\"}]";
lachu 9:b08a28f659eb 84
lachu 9:b08a28f659eb 85 string res;
lachu 9:b08a28f659eb 86 int err;
lachu 9:b08a28f659eb 87 int code;
lachu 9:b08a28f659eb 88 if ((err = httpPut(path, json, res, code)) != 0) return err;
lachu 9:b08a28f659eb 89 if (code != HTTP_OK) return EVRY_ERR_UNEXPECTEDHTTPSTATUS;
lachu 9:b08a28f659eb 90
lachu 9:b08a28f659eb 91 return 0;
lachu 9:b08a28f659eb 92 }
lachu 9:b08a28f659eb 93
lachu 9:b08a28f659eb 94
lachu 9:b08a28f659eb 95 int EvrythngApi::httpRequest(HttpMethod method, const string& path, const string& content, string& out, int& codeOut)
lachu 9:b08a28f659eb 96 {
lachu 9:b08a28f659eb 97 int ret;
lachu 9:b08a28f659eb 98
lachu 9:b08a28f659eb 99 const char* strMethod;
lachu 9:b08a28f659eb 100 switch (method) {
lachu 9:b08a28f659eb 101 case GET:
lachu 9:b08a28f659eb 102 strMethod = "GET";
lachu 9:b08a28f659eb 103 break;
lachu 9:b08a28f659eb 104 case PUT:
lachu 9:b08a28f659eb 105 strMethod = "PUT";
lachu 9:b08a28f659eb 106 break;
lachu 9:b08a28f659eb 107 case POST:
lachu 9:b08a28f659eb 108 strMethod = "POST";
lachu 9:b08a28f659eb 109 break;
lachu 9:b08a28f659eb 110 case DELETE:
lachu 9:b08a28f659eb 111 strMethod = "DELETE";
lachu 9:b08a28f659eb 112 break;
lachu 9:b08a28f659eb 113 default:
lachu 9:b08a28f659eb 114 return EVRY_ERR_UNSUPPORTED;
lachu 9:b08a28f659eb 115 }
lachu 9:b08a28f659eb 116
lachu 9:b08a28f659eb 117 char contentLength[16];
lachu 9:b08a28f659eb 118 snprintf(contentLength, sizeof(contentLength), "%d", content.size());
lachu 9:b08a28f659eb 119
lachu 9:b08a28f659eb 120 string req = strMethod;
lachu 9:b08a28f659eb 121 req += " ";
lachu 9:b08a28f659eb 122 req += path;
lachu 9:b08a28f659eb 123 req += " HTTP/1.0\r\n"
lachu 9:b08a28f659eb 124 "Host: ";
lachu 9:b08a28f659eb 125 req += host;
lachu 9:b08a28f659eb 126 req += "\r\n"
lachu 9:b08a28f659eb 127 "Accept: application/json\r\n"
lachu 9:b08a28f659eb 128 "Content-Length: ";
lachu 9:b08a28f659eb 129 req += contentLength;
lachu 9:b08a28f659eb 130 req += "\r\n"
lachu 9:b08a28f659eb 131 "Content-Type: application/json\r\n"
lachu 9:b08a28f659eb 132 "Connection: close\r\n"
lachu 9:b08a28f659eb 133 "Authorization: ";
lachu 9:b08a28f659eb 134 req += token;
lachu 9:b08a28f659eb 135 req += "\r\n\r\n";
lachu 9:b08a28f659eb 136
lachu 9:b08a28f659eb 137 req += content;
lachu 9:b08a28f659eb 138
lachu 9:b08a28f659eb 139 #ifdef DEBUG_EVRYTHNG_API
lachu 9:b08a28f659eb 140 dbg.printf("%s\r\n\r\n", req.c_str());
lachu 9:b08a28f659eb 141 #endif
lachu 9:b08a28f659eb 142
lachu 9:b08a28f659eb 143 TCPSocketConnection socket;
lachu 9:b08a28f659eb 144
lachu 9:b08a28f659eb 145 out.clear();
lachu 9:b08a28f659eb 146
lachu 9:b08a28f659eb 147 string res;
lachu 9:b08a28f659eb 148
lachu 9:b08a28f659eb 149 if (socket.connect(host.c_str(), port) == 0) {
lachu 9:b08a28f659eb 150
lachu 9:b08a28f659eb 151 char* snd = new char[req.size()+1];
lachu 9:b08a28f659eb 152 req.copy(snd, req.size());
lachu 9:b08a28f659eb 153 snd[req.size()]='\0';
lachu 9:b08a28f659eb 154 bool sent = socket.send_all(snd, req.size()) >= 0;
lachu 9:b08a28f659eb 155 delete[] snd;
lachu 9:b08a28f659eb 156
lachu 9:b08a28f659eb 157 if (sent) {
lachu 9:b08a28f659eb 158
lachu 9:b08a28f659eb 159 char rcv[256];
lachu 9:b08a28f659eb 160
lachu 9:b08a28f659eb 161 int r;
lachu 9:b08a28f659eb 162 while (true) {
lachu 9:b08a28f659eb 163 r = socket.receive(rcv, sizeof(rcv));
lachu 9:b08a28f659eb 164 if (r <= 0)
lachu 9:b08a28f659eb 165 break;
lachu 9:b08a28f659eb 166 res.append(rcv, r);
lachu 9:b08a28f659eb 167 }
lachu 9:b08a28f659eb 168
lachu 9:b08a28f659eb 169 ret = EVRY_ERR_OK;
lachu 9:b08a28f659eb 170
lachu 9:b08a28f659eb 171 } else {
lachu 9:b08a28f659eb 172 ret = EVRY_ERR_CANTSEND;
lachu 9:b08a28f659eb 173 }
lachu 9:b08a28f659eb 174
lachu 9:b08a28f659eb 175 socket.close();
lachu 9:b08a28f659eb 176
lachu 9:b08a28f659eb 177 } else {
lachu 9:b08a28f659eb 178 ret = EVRY_ERR_CANTCONNECT;
lachu 9:b08a28f659eb 179 }
lachu 9:b08a28f659eb 180
lachu 9:b08a28f659eb 181 #ifdef DEBUG_EVRYTHNG_API
lachu 9:b08a28f659eb 182 dbg.printf("%s", res.c_str());
lachu 9:b08a28f659eb 183 #endif
lachu 9:b08a28f659eb 184
lachu 9:b08a28f659eb 185 if (res.compare(0,5,"HTTP/") != 0) {
lachu 9:b08a28f659eb 186 return EVRY_ERR_UNKNOWN;
lachu 9:b08a28f659eb 187 }
lachu 9:b08a28f659eb 188
lachu 9:b08a28f659eb 189 int spPos = res.find(' ', 5);
lachu 9:b08a28f659eb 190 if (spPos == string::npos) {
lachu 9:b08a28f659eb 191 return EVRY_ERR_UNKNOWN;
lachu 9:b08a28f659eb 192 }
lachu 9:b08a28f659eb 193
lachu 9:b08a28f659eb 194 // TODO: check str length
lachu 9:b08a28f659eb 195 int code = atoi(res.c_str()+spPos+1);
lachu 9:b08a28f659eb 196 if (code < 100 || code > 999) {
lachu 9:b08a28f659eb 197 return EVRY_ERR_UNKNOWN;
lachu 9:b08a28f659eb 198 }
lachu 9:b08a28f659eb 199 codeOut = code;
lachu 9:b08a28f659eb 200
lachu 9:b08a28f659eb 201 int startContent = res.find("\r\n\r\n");
lachu 9:b08a28f659eb 202 if (startContent != string::npos) {
lachu 9:b08a28f659eb 203 out.append(res.substr(startContent+4,res.size()-startContent-4));
lachu 9:b08a28f659eb 204 }
lachu 9:b08a28f659eb 205
lachu 9:b08a28f659eb 206 return ret;
lachu 9:b08a28f659eb 207 }
lachu 9:b08a28f659eb 208
lachu 9:b08a28f659eb 209 int EvrythngApi::httpPut(const string& path, const string& json, string& out, int& codeOut)
lachu 9:b08a28f659eb 210 {
lachu 9:b08a28f659eb 211 return httpRequest(PUT, path, json, out, codeOut);
lachu 9:b08a28f659eb 212 }
lachu 9:b08a28f659eb 213
lachu 9:b08a28f659eb 214 int EvrythngApi::httpGet(const string& path, string& out, int& codeOut)
lachu 9:b08a28f659eb 215 {
lachu 9:b08a28f659eb 216 return httpRequest(GET, path, "", out, codeOut);
lachu 9:b08a28f659eb 217 }
lachu 9:b08a28f659eb 218
lachu 9:b08a28f659eb 219 int EvrythngApi::httpPost(const string& path, const string& json, string& out, int& codeOut)
lachu 9:b08a28f659eb 220 {
lachu 9:b08a28f659eb 221 return httpRequest(POST, path, json, out, codeOut);
lachu 9:b08a28f659eb 222 }
lachu 9:b08a28f659eb 223
lachu 9:b08a28f659eb 224 int EvrythngApi::httpDelete(const string& path, string& out, int& codeOut)
lachu 9:b08a28f659eb 225 {
lachu 9:b08a28f659eb 226 return httpRequest(DELETE, path, "", out, codeOut);
lachu 9:b08a28f659eb 227 }