Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of M2XStreamClient by
M2XStreamClient.cpp@5:ea68c8980ad8, 2013-10-24 (annotated)
- Committer:
- citrusbyte
- Date:
- Thu Oct 24 12:22:33 2013 +0000
- Revision:
- 5:ea68c8980ad8
- Child:
- 6:e6d66d99dd6f
Initial commit for M2X mbed client library
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| citrusbyte | 5:ea68c8980ad8 | 1 | #include "M2XStreamClient.h" |
| citrusbyte | 5:ea68c8980ad8 | 2 | |
| citrusbyte | 5:ea68c8980ad8 | 3 | #include <jsonlite.h> |
| citrusbyte | 5:ea68c8980ad8 | 4 | |
| citrusbyte | 5:ea68c8980ad8 | 5 | #include "StreamParseFunctions.h" |
| citrusbyte | 5:ea68c8980ad8 | 6 | #include "LocationParseFunctions.h" |
| citrusbyte | 5:ea68c8980ad8 | 7 | |
| citrusbyte | 5:ea68c8980ad8 | 8 | #define HEX(t_) ((char) (((t_) > 9) ? ((t_) - 10 + 'A') : ((t_) + '0'))) |
| citrusbyte | 5:ea68c8980ad8 | 9 | #define MAX_DOUBLE_DIGITS 7 |
| citrusbyte | 5:ea68c8980ad8 | 10 | |
| citrusbyte | 5:ea68c8980ad8 | 11 | const char* M2XStreamClient::kDefaultM2XHost = "api-m2x.att.com"; |
| citrusbyte | 5:ea68c8980ad8 | 12 | const char* kUserAgentLine = "User-Agent: M2X Arduino Client/0.1"; |
| citrusbyte | 5:ea68c8980ad8 | 13 | |
| citrusbyte | 5:ea68c8980ad8 | 14 | static int print_encoded_string(Print* print, const char* str); |
| citrusbyte | 5:ea68c8980ad8 | 15 | |
| citrusbyte | 5:ea68c8980ad8 | 16 | M2XStreamClient::M2XStreamClient(Client* client, |
| citrusbyte | 5:ea68c8980ad8 | 17 | const char* key, |
| citrusbyte | 5:ea68c8980ad8 | 18 | const char* host, |
| citrusbyte | 5:ea68c8980ad8 | 19 | int port) : _client(client), |
| citrusbyte | 5:ea68c8980ad8 | 20 | _key(key), |
| citrusbyte | 5:ea68c8980ad8 | 21 | _host(host), |
| citrusbyte | 5:ea68c8980ad8 | 22 | _port(port), |
| citrusbyte | 5:ea68c8980ad8 | 23 | _null_print() { |
| citrusbyte | 5:ea68c8980ad8 | 24 | } |
| citrusbyte | 5:ea68c8980ad8 | 25 | |
| citrusbyte | 5:ea68c8980ad8 | 26 | int M2XStreamClient::send(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 27 | const char* streamName, |
| citrusbyte | 5:ea68c8980ad8 | 28 | double value) { |
| citrusbyte | 5:ea68c8980ad8 | 29 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 30 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 31 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 32 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 33 | writeSendHeader(feedId, streamName, |
| citrusbyte | 5:ea68c8980ad8 | 34 | // 6 for "value=" |
| citrusbyte | 5:ea68c8980ad8 | 35 | _null_print.print(value) + 6); |
| citrusbyte | 5:ea68c8980ad8 | 36 | _client->print("value="); |
| citrusbyte | 5:ea68c8980ad8 | 37 | // value is a double, does not need encoding |
| citrusbyte | 5:ea68c8980ad8 | 38 | _client->print(value); |
| citrusbyte | 5:ea68c8980ad8 | 39 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 40 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 41 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 42 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 43 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 44 | } |
| citrusbyte | 5:ea68c8980ad8 | 45 | |
| citrusbyte | 5:ea68c8980ad8 | 46 | return readStatusCode(true); |
| citrusbyte | 5:ea68c8980ad8 | 47 | } |
| citrusbyte | 5:ea68c8980ad8 | 48 | |
| citrusbyte | 5:ea68c8980ad8 | 49 | int M2XStreamClient::send(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 50 | const char* streamName, |
| citrusbyte | 5:ea68c8980ad8 | 51 | long value) { |
| citrusbyte | 5:ea68c8980ad8 | 52 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 53 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 54 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 55 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 56 | writeSendHeader(feedId, streamName, |
| citrusbyte | 5:ea68c8980ad8 | 57 | // 6 for "value=" |
| citrusbyte | 5:ea68c8980ad8 | 58 | _null_print.print(value) + 6); |
| citrusbyte | 5:ea68c8980ad8 | 59 | |
| citrusbyte | 5:ea68c8980ad8 | 60 | _client->print("value="); |
| citrusbyte | 5:ea68c8980ad8 | 61 | // value is a long, does not need encoding |
| citrusbyte | 5:ea68c8980ad8 | 62 | _client->print(value); |
| citrusbyte | 5:ea68c8980ad8 | 63 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 64 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 65 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 66 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 67 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 68 | } |
| citrusbyte | 5:ea68c8980ad8 | 69 | |
| citrusbyte | 5:ea68c8980ad8 | 70 | return readStatusCode(true); |
| citrusbyte | 5:ea68c8980ad8 | 71 | } |
| citrusbyte | 5:ea68c8980ad8 | 72 | |
| citrusbyte | 5:ea68c8980ad8 | 73 | int M2XStreamClient::send(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 74 | const char* streamName, |
| citrusbyte | 5:ea68c8980ad8 | 75 | int value) { |
| citrusbyte | 5:ea68c8980ad8 | 76 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 77 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 78 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 79 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 80 | writeSendHeader(feedId, streamName, |
| citrusbyte | 5:ea68c8980ad8 | 81 | // 6 for "value=" |
| citrusbyte | 5:ea68c8980ad8 | 82 | _null_print.print(value) + 6); |
| citrusbyte | 5:ea68c8980ad8 | 83 | |
| citrusbyte | 5:ea68c8980ad8 | 84 | _client->print("value="); |
| citrusbyte | 5:ea68c8980ad8 | 85 | // value is an int, does not need encoding |
| citrusbyte | 5:ea68c8980ad8 | 86 | _client->print(value); |
| citrusbyte | 5:ea68c8980ad8 | 87 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 88 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 89 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 90 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 91 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 92 | } |
| citrusbyte | 5:ea68c8980ad8 | 93 | |
| citrusbyte | 5:ea68c8980ad8 | 94 | return readStatusCode(true); |
| citrusbyte | 5:ea68c8980ad8 | 95 | } |
| citrusbyte | 5:ea68c8980ad8 | 96 | |
| citrusbyte | 5:ea68c8980ad8 | 97 | int M2XStreamClient::send(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 98 | const char* streamName, |
| citrusbyte | 5:ea68c8980ad8 | 99 | const char* value) { |
| citrusbyte | 5:ea68c8980ad8 | 100 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 101 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 102 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 103 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 104 | writeSendHeader(feedId, streamName, |
| citrusbyte | 5:ea68c8980ad8 | 105 | // 6 for "value=" |
| citrusbyte | 5:ea68c8980ad8 | 106 | _null_print.print(value) + 6); |
| citrusbyte | 5:ea68c8980ad8 | 107 | |
| citrusbyte | 5:ea68c8980ad8 | 108 | _client->print("value="); |
| citrusbyte | 5:ea68c8980ad8 | 109 | print_encoded_string(_client, value); |
| citrusbyte | 5:ea68c8980ad8 | 110 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 111 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 112 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 113 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 114 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 115 | } |
| citrusbyte | 5:ea68c8980ad8 | 116 | |
| citrusbyte | 5:ea68c8980ad8 | 117 | return readStatusCode(true); |
| citrusbyte | 5:ea68c8980ad8 | 118 | } |
| citrusbyte | 5:ea68c8980ad8 | 119 | |
| citrusbyte | 5:ea68c8980ad8 | 120 | int M2XStreamClient::receive(const char* feedId, const char* streamName, |
| citrusbyte | 5:ea68c8980ad8 | 121 | stream_value_read_callback callback, void* context) { |
| citrusbyte | 5:ea68c8980ad8 | 122 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 123 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 124 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 125 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 126 | _client->print("GET /v1/feeds/"); |
| citrusbyte | 5:ea68c8980ad8 | 127 | print_encoded_string(_client, feedId); |
| citrusbyte | 5:ea68c8980ad8 | 128 | _client->print("/streams/"); |
| citrusbyte | 5:ea68c8980ad8 | 129 | print_encoded_string(_client, streamName); |
| citrusbyte | 5:ea68c8980ad8 | 130 | _client->println("/values HTTP/1.0"); |
| citrusbyte | 5:ea68c8980ad8 | 131 | |
| citrusbyte | 5:ea68c8980ad8 | 132 | writeHttpHeader(-1); |
| citrusbyte | 5:ea68c8980ad8 | 133 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 134 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 135 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 136 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 137 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 138 | } |
| citrusbyte | 5:ea68c8980ad8 | 139 | int status = readStatusCode(false); |
| citrusbyte | 5:ea68c8980ad8 | 140 | if (status == 200) { |
| citrusbyte | 5:ea68c8980ad8 | 141 | readStreamValue(callback, context); |
| citrusbyte | 5:ea68c8980ad8 | 142 | } |
| citrusbyte | 5:ea68c8980ad8 | 143 | |
| citrusbyte | 5:ea68c8980ad8 | 144 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 145 | return status; |
| citrusbyte | 5:ea68c8980ad8 | 146 | } |
| citrusbyte | 5:ea68c8980ad8 | 147 | |
| citrusbyte | 5:ea68c8980ad8 | 148 | int M2XStreamClient::readLocation(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 149 | location_read_callback callback, |
| citrusbyte | 5:ea68c8980ad8 | 150 | void* context) { |
| citrusbyte | 5:ea68c8980ad8 | 151 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 152 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 153 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 154 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 155 | _client->print("GET /v1/feeds/"); |
| citrusbyte | 5:ea68c8980ad8 | 156 | print_encoded_string(_client, feedId); |
| citrusbyte | 5:ea68c8980ad8 | 157 | _client->println("/location HTTP/1.0"); |
| citrusbyte | 5:ea68c8980ad8 | 158 | |
| citrusbyte | 5:ea68c8980ad8 | 159 | writeHttpHeader(-1); |
| citrusbyte | 5:ea68c8980ad8 | 160 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 161 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 162 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 163 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 164 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 165 | } |
| citrusbyte | 5:ea68c8980ad8 | 166 | int status = readStatusCode(false); |
| citrusbyte | 5:ea68c8980ad8 | 167 | if (status == 200) { |
| citrusbyte | 5:ea68c8980ad8 | 168 | readLocation(callback, context); |
| citrusbyte | 5:ea68c8980ad8 | 169 | } |
| citrusbyte | 5:ea68c8980ad8 | 170 | |
| citrusbyte | 5:ea68c8980ad8 | 171 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 172 | return status; |
| citrusbyte | 5:ea68c8980ad8 | 173 | } |
| citrusbyte | 5:ea68c8980ad8 | 174 | |
| citrusbyte | 5:ea68c8980ad8 | 175 | // Encodes and prints string using Percent-encoding specified |
| citrusbyte | 5:ea68c8980ad8 | 176 | // in RFC 1738, Section 2.2 |
| citrusbyte | 5:ea68c8980ad8 | 177 | static int print_encoded_string(Print* print, const char* str) { |
| citrusbyte | 5:ea68c8980ad8 | 178 | int bytes = 0; |
| citrusbyte | 5:ea68c8980ad8 | 179 | for (int i = 0; str[i] != 0; i++) { |
| citrusbyte | 5:ea68c8980ad8 | 180 | if (((str[i] >= 'A') && (str[i] <= 'Z')) || |
| citrusbyte | 5:ea68c8980ad8 | 181 | ((str[i] >= 'a') && (str[i] <= 'z')) || |
| citrusbyte | 5:ea68c8980ad8 | 182 | ((str[i] >= '0') && (str[i] <= '9')) || |
| citrusbyte | 5:ea68c8980ad8 | 183 | (str[i] == '-') || (str[i] == '_') || |
| citrusbyte | 5:ea68c8980ad8 | 184 | (str[i] == '.') || (str[i] == '~')) { |
| citrusbyte | 5:ea68c8980ad8 | 185 | bytes += print->print(str[i]); |
| citrusbyte | 5:ea68c8980ad8 | 186 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 187 | // Encode all other characters |
| citrusbyte | 5:ea68c8980ad8 | 188 | bytes += print->print('%'); |
| citrusbyte | 5:ea68c8980ad8 | 189 | bytes += print->print(HEX(str[i] / 16)); |
| citrusbyte | 5:ea68c8980ad8 | 190 | bytes += print->print(HEX(str[i] % 16)); |
| citrusbyte | 5:ea68c8980ad8 | 191 | } |
| citrusbyte | 5:ea68c8980ad8 | 192 | } |
| citrusbyte | 5:ea68c8980ad8 | 193 | return bytes; |
| citrusbyte | 5:ea68c8980ad8 | 194 | } |
| citrusbyte | 5:ea68c8980ad8 | 195 | |
| citrusbyte | 5:ea68c8980ad8 | 196 | static int write_location_data(Print* print, const char* name, |
| citrusbyte | 5:ea68c8980ad8 | 197 | double latitude, double longitude, |
| citrusbyte | 5:ea68c8980ad8 | 198 | double elevation) { |
| citrusbyte | 5:ea68c8980ad8 | 199 | int bytes = 0; |
| citrusbyte | 5:ea68c8980ad8 | 200 | bytes += print->print("name="); |
| citrusbyte | 5:ea68c8980ad8 | 201 | bytes += print_encoded_string(print, name); |
| citrusbyte | 5:ea68c8980ad8 | 202 | bytes += print->print("&latitude="); |
| citrusbyte | 5:ea68c8980ad8 | 203 | bytes += print->print(latitude, MAX_DOUBLE_DIGITS); |
| citrusbyte | 5:ea68c8980ad8 | 204 | bytes += print->print("&longitude="); |
| citrusbyte | 5:ea68c8980ad8 | 205 | bytes += print->print(longitude, MAX_DOUBLE_DIGITS); |
| citrusbyte | 5:ea68c8980ad8 | 206 | bytes += print->print("&elevation="); |
| citrusbyte | 5:ea68c8980ad8 | 207 | bytes += print->print(elevation); |
| citrusbyte | 5:ea68c8980ad8 | 208 | return bytes; |
| citrusbyte | 5:ea68c8980ad8 | 209 | } |
| citrusbyte | 5:ea68c8980ad8 | 210 | |
| citrusbyte | 5:ea68c8980ad8 | 211 | static int write_location_data(Print* print, const char* name, |
| citrusbyte | 5:ea68c8980ad8 | 212 | const char* latitude, const char* longitude, |
| citrusbyte | 5:ea68c8980ad8 | 213 | const char* elevation) { |
| citrusbyte | 5:ea68c8980ad8 | 214 | int bytes = 0; |
| citrusbyte | 5:ea68c8980ad8 | 215 | bytes += print->print("name="); |
| citrusbyte | 5:ea68c8980ad8 | 216 | bytes += print_encoded_string(print, name); |
| citrusbyte | 5:ea68c8980ad8 | 217 | bytes += print->print("&latitude="); |
| citrusbyte | 5:ea68c8980ad8 | 218 | bytes += print_encoded_string(print, latitude); |
| citrusbyte | 5:ea68c8980ad8 | 219 | bytes += print->print("&longitude="); |
| citrusbyte | 5:ea68c8980ad8 | 220 | bytes += print_encoded_string(print, longitude); |
| citrusbyte | 5:ea68c8980ad8 | 221 | bytes += print->print("&elevation="); |
| citrusbyte | 5:ea68c8980ad8 | 222 | bytes += print_encoded_string(print, elevation); |
| citrusbyte | 5:ea68c8980ad8 | 223 | return bytes; |
| citrusbyte | 5:ea68c8980ad8 | 224 | } |
| citrusbyte | 5:ea68c8980ad8 | 225 | |
| citrusbyte | 5:ea68c8980ad8 | 226 | int M2XStreamClient::updateLocation(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 227 | const char* name, |
| citrusbyte | 5:ea68c8980ad8 | 228 | double latitude, |
| citrusbyte | 5:ea68c8980ad8 | 229 | double longitude, |
| citrusbyte | 5:ea68c8980ad8 | 230 | double elevation) { |
| citrusbyte | 5:ea68c8980ad8 | 231 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 232 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 233 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 234 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 235 | |
| citrusbyte | 5:ea68c8980ad8 | 236 | int length = write_location_data(&_null_print, name, latitude, longitude, |
| citrusbyte | 5:ea68c8980ad8 | 237 | elevation); |
| citrusbyte | 5:ea68c8980ad8 | 238 | _client->print("PUT /v1/feeds/"); |
| citrusbyte | 5:ea68c8980ad8 | 239 | print_encoded_string(_client, feedId); |
| citrusbyte | 5:ea68c8980ad8 | 240 | _client->println("/location HTTP/1.0"); |
| citrusbyte | 5:ea68c8980ad8 | 241 | |
| citrusbyte | 5:ea68c8980ad8 | 242 | writeHttpHeader(length); |
| citrusbyte | 5:ea68c8980ad8 | 243 | write_location_data(_client, name, latitude, longitude, elevation); |
| citrusbyte | 5:ea68c8980ad8 | 244 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 245 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 246 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 247 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 248 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 249 | } |
| citrusbyte | 5:ea68c8980ad8 | 250 | return readStatusCode(true); |
| citrusbyte | 5:ea68c8980ad8 | 251 | } |
| citrusbyte | 5:ea68c8980ad8 | 252 | |
| citrusbyte | 5:ea68c8980ad8 | 253 | int M2XStreamClient::updateLocation(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 254 | const char* name, |
| citrusbyte | 5:ea68c8980ad8 | 255 | const char* latitude, |
| citrusbyte | 5:ea68c8980ad8 | 256 | const char* longitude, |
| citrusbyte | 5:ea68c8980ad8 | 257 | const char* elevation) { |
| citrusbyte | 5:ea68c8980ad8 | 258 | if (_client->connect(_host, _port)) { |
| citrusbyte | 5:ea68c8980ad8 | 259 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 260 | printf("Connected to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 261 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 262 | |
| citrusbyte | 5:ea68c8980ad8 | 263 | int length = write_location_data(&_null_print, name, latitude, longitude, |
| citrusbyte | 5:ea68c8980ad8 | 264 | elevation); |
| citrusbyte | 5:ea68c8980ad8 | 265 | _client->print("PUT /v1/feeds/"); |
| citrusbyte | 5:ea68c8980ad8 | 266 | print_encoded_string(_client, feedId); |
| citrusbyte | 5:ea68c8980ad8 | 267 | _client->println("/location HTTP/1.0"); |
| citrusbyte | 5:ea68c8980ad8 | 268 | |
| citrusbyte | 5:ea68c8980ad8 | 269 | writeHttpHeader(length); |
| citrusbyte | 5:ea68c8980ad8 | 270 | write_location_data(_client, name, latitude, longitude, elevation); |
| citrusbyte | 5:ea68c8980ad8 | 271 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 272 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 273 | printf("ERROR: Cannot connect to M2X server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 274 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 275 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 276 | } |
| citrusbyte | 5:ea68c8980ad8 | 277 | return readStatusCode(true); |
| citrusbyte | 5:ea68c8980ad8 | 278 | } |
| citrusbyte | 5:ea68c8980ad8 | 279 | |
| citrusbyte | 5:ea68c8980ad8 | 280 | void M2XStreamClient::writeSendHeader(const char* feedId, |
| citrusbyte | 5:ea68c8980ad8 | 281 | const char* streamName, |
| citrusbyte | 5:ea68c8980ad8 | 282 | int contentLength) { |
| citrusbyte | 5:ea68c8980ad8 | 283 | _client->print("PUT /v1/feeds/"); |
| citrusbyte | 5:ea68c8980ad8 | 284 | print_encoded_string(_client, feedId); |
| citrusbyte | 5:ea68c8980ad8 | 285 | _client->print("/streams/"); |
| citrusbyte | 5:ea68c8980ad8 | 286 | print_encoded_string(_client, streamName); |
| citrusbyte | 5:ea68c8980ad8 | 287 | _client->println(" HTTP/1.0"); |
| citrusbyte | 5:ea68c8980ad8 | 288 | |
| citrusbyte | 5:ea68c8980ad8 | 289 | writeHttpHeader(contentLength); |
| citrusbyte | 5:ea68c8980ad8 | 290 | } |
| citrusbyte | 5:ea68c8980ad8 | 291 | |
| citrusbyte | 5:ea68c8980ad8 | 292 | void M2XStreamClient::writeHttpHeader(int contentLength) { |
| citrusbyte | 5:ea68c8980ad8 | 293 | _client->println(kUserAgentLine); |
| citrusbyte | 5:ea68c8980ad8 | 294 | _client->print("X-M2X-KEY: "); |
| citrusbyte | 5:ea68c8980ad8 | 295 | _client->println(_key); |
| citrusbyte | 5:ea68c8980ad8 | 296 | |
| citrusbyte | 5:ea68c8980ad8 | 297 | _client->print("Host: "); |
| citrusbyte | 5:ea68c8980ad8 | 298 | print_encoded_string(_client, _host); |
| citrusbyte | 5:ea68c8980ad8 | 299 | if (_port != kDefaultM2XPort) { |
| citrusbyte | 5:ea68c8980ad8 | 300 | _client->print(":"); |
| citrusbyte | 5:ea68c8980ad8 | 301 | // port is an integer, does not need encoding |
| citrusbyte | 5:ea68c8980ad8 | 302 | _client->print(_port); |
| citrusbyte | 5:ea68c8980ad8 | 303 | } |
| citrusbyte | 5:ea68c8980ad8 | 304 | _client->println(); |
| citrusbyte | 5:ea68c8980ad8 | 305 | |
| citrusbyte | 5:ea68c8980ad8 | 306 | if (contentLength > 0) { |
| citrusbyte | 5:ea68c8980ad8 | 307 | _client->println("Content-Type: application/x-www-form-urlencoded"); |
| citrusbyte | 5:ea68c8980ad8 | 308 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 309 | printf("Content Length: %d\n", contentLength); |
| citrusbyte | 5:ea68c8980ad8 | 310 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 311 | _client->print("Content-Length: "); |
| citrusbyte | 5:ea68c8980ad8 | 312 | _client->println(contentLength); |
| citrusbyte | 5:ea68c8980ad8 | 313 | } |
| citrusbyte | 5:ea68c8980ad8 | 314 | _client->println(); |
| citrusbyte | 5:ea68c8980ad8 | 315 | } |
| citrusbyte | 5:ea68c8980ad8 | 316 | |
| citrusbyte | 5:ea68c8980ad8 | 317 | int M2XStreamClient::waitForString(const char* str) { |
| citrusbyte | 5:ea68c8980ad8 | 318 | int currentIndex = 0; |
| citrusbyte | 5:ea68c8980ad8 | 319 | if (str[currentIndex] == '\0') return E_OK; |
| citrusbyte | 5:ea68c8980ad8 | 320 | |
| citrusbyte | 5:ea68c8980ad8 | 321 | while (true) { |
| citrusbyte | 5:ea68c8980ad8 | 322 | while (_client->available()) { |
| citrusbyte | 5:ea68c8980ad8 | 323 | char c = _client->read(); |
| citrusbyte | 5:ea68c8980ad8 | 324 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 325 | printf("%c", c); |
| citrusbyte | 5:ea68c8980ad8 | 326 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 327 | |
| citrusbyte | 5:ea68c8980ad8 | 328 | if ((str[currentIndex] == '*') || |
| citrusbyte | 5:ea68c8980ad8 | 329 | (c == str[currentIndex])) { |
| citrusbyte | 5:ea68c8980ad8 | 330 | currentIndex++; |
| citrusbyte | 5:ea68c8980ad8 | 331 | if (str[currentIndex] == '\0') { |
| citrusbyte | 5:ea68c8980ad8 | 332 | return E_OK; |
| citrusbyte | 5:ea68c8980ad8 | 333 | } |
| citrusbyte | 5:ea68c8980ad8 | 334 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 335 | // start from the beginning |
| citrusbyte | 5:ea68c8980ad8 | 336 | currentIndex = 0; |
| citrusbyte | 5:ea68c8980ad8 | 337 | } |
| citrusbyte | 5:ea68c8980ad8 | 338 | } |
| citrusbyte | 5:ea68c8980ad8 | 339 | |
| citrusbyte | 5:ea68c8980ad8 | 340 | if (!_client->connected()) { |
| citrusbyte | 5:ea68c8980ad8 | 341 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 342 | printf("ERROR: The client is disconnected from the server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 343 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 344 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 345 | return E_DISCONNECTED; |
| citrusbyte | 5:ea68c8980ad8 | 346 | } |
| citrusbyte | 5:ea68c8980ad8 | 347 | |
| citrusbyte | 5:ea68c8980ad8 | 348 | delay(1000); |
| citrusbyte | 5:ea68c8980ad8 | 349 | } |
| citrusbyte | 5:ea68c8980ad8 | 350 | // never reached here |
| citrusbyte | 5:ea68c8980ad8 | 351 | return E_NOTREACHABLE; |
| citrusbyte | 5:ea68c8980ad8 | 352 | } |
| citrusbyte | 5:ea68c8980ad8 | 353 | |
| citrusbyte | 5:ea68c8980ad8 | 354 | int M2XStreamClient::readStatusCode(bool closeClient) { |
| citrusbyte | 5:ea68c8980ad8 | 355 | int responseCode = 0; |
| citrusbyte | 5:ea68c8980ad8 | 356 | int ret = waitForString("HTTP/*.* "); |
| citrusbyte | 5:ea68c8980ad8 | 357 | if (ret != E_OK) { |
| citrusbyte | 5:ea68c8980ad8 | 358 | if (closeClient) close(); |
| citrusbyte | 5:ea68c8980ad8 | 359 | return ret; |
| citrusbyte | 5:ea68c8980ad8 | 360 | } |
| citrusbyte | 5:ea68c8980ad8 | 361 | |
| citrusbyte | 5:ea68c8980ad8 | 362 | // ret is not needed from here(since it must be E_OK), so we can use it |
| citrusbyte | 5:ea68c8980ad8 | 363 | // as a regular variable now. |
| citrusbyte | 5:ea68c8980ad8 | 364 | ret = 0; |
| citrusbyte | 5:ea68c8980ad8 | 365 | while (true) { |
| citrusbyte | 5:ea68c8980ad8 | 366 | while (_client->available()) { |
| citrusbyte | 5:ea68c8980ad8 | 367 | char c = _client->read(); |
| citrusbyte | 5:ea68c8980ad8 | 368 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 369 | printf("%c", c); |
| citrusbyte | 5:ea68c8980ad8 | 370 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 371 | responseCode = responseCode * 10 + (c - '0'); |
| citrusbyte | 5:ea68c8980ad8 | 372 | ret++; |
| citrusbyte | 5:ea68c8980ad8 | 373 | if (ret == 3) { |
| citrusbyte | 5:ea68c8980ad8 | 374 | if (closeClient) close(); |
| citrusbyte | 5:ea68c8980ad8 | 375 | return responseCode; |
| citrusbyte | 5:ea68c8980ad8 | 376 | } |
| citrusbyte | 5:ea68c8980ad8 | 377 | } |
| citrusbyte | 5:ea68c8980ad8 | 378 | |
| citrusbyte | 5:ea68c8980ad8 | 379 | if (!_client->connected()) { |
| citrusbyte | 5:ea68c8980ad8 | 380 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 381 | printf("ERROR: The client is disconnected from the server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 382 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 383 | if (closeClient) close(); |
| citrusbyte | 5:ea68c8980ad8 | 384 | return E_DISCONNECTED; |
| citrusbyte | 5:ea68c8980ad8 | 385 | } |
| citrusbyte | 5:ea68c8980ad8 | 386 | |
| citrusbyte | 5:ea68c8980ad8 | 387 | delay(1000); |
| citrusbyte | 5:ea68c8980ad8 | 388 | } |
| citrusbyte | 5:ea68c8980ad8 | 389 | |
| citrusbyte | 5:ea68c8980ad8 | 390 | // never reached here |
| citrusbyte | 5:ea68c8980ad8 | 391 | return E_NOTREACHABLE; |
| citrusbyte | 5:ea68c8980ad8 | 392 | } |
| citrusbyte | 5:ea68c8980ad8 | 393 | |
| citrusbyte | 5:ea68c8980ad8 | 394 | int M2XStreamClient::readContentLength() { |
| citrusbyte | 5:ea68c8980ad8 | 395 | int ret = waitForString("Content-Length: "); |
| citrusbyte | 5:ea68c8980ad8 | 396 | if (ret != E_OK) { |
| citrusbyte | 5:ea68c8980ad8 | 397 | return ret; |
| citrusbyte | 5:ea68c8980ad8 | 398 | } |
| citrusbyte | 5:ea68c8980ad8 | 399 | |
| citrusbyte | 5:ea68c8980ad8 | 400 | // From now on, ret is not needed, we can use it |
| citrusbyte | 5:ea68c8980ad8 | 401 | // to keep the final result |
| citrusbyte | 5:ea68c8980ad8 | 402 | ret = 0; |
| citrusbyte | 5:ea68c8980ad8 | 403 | while (true) { |
| citrusbyte | 5:ea68c8980ad8 | 404 | while (_client->available()) { |
| citrusbyte | 5:ea68c8980ad8 | 405 | char c = _client->read(); |
| citrusbyte | 5:ea68c8980ad8 | 406 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 407 | printf("%c", c); |
| citrusbyte | 5:ea68c8980ad8 | 408 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 409 | if ((c == '\r') || (c == '\n')) { |
| citrusbyte | 5:ea68c8980ad8 | 410 | return (ret == 0) ? (E_INVALID) : (ret); |
| citrusbyte | 5:ea68c8980ad8 | 411 | } else { |
| citrusbyte | 5:ea68c8980ad8 | 412 | ret = ret * 10 + (c - '0'); |
| citrusbyte | 5:ea68c8980ad8 | 413 | } |
| citrusbyte | 5:ea68c8980ad8 | 414 | } |
| citrusbyte | 5:ea68c8980ad8 | 415 | |
| citrusbyte | 5:ea68c8980ad8 | 416 | if (!_client->connected()) { |
| citrusbyte | 5:ea68c8980ad8 | 417 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 418 | printf("ERROR: The client is disconnected from the server!\n"); |
| citrusbyte | 5:ea68c8980ad8 | 419 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 420 | return E_DISCONNECTED; |
| citrusbyte | 5:ea68c8980ad8 | 421 | } |
| citrusbyte | 5:ea68c8980ad8 | 422 | |
| citrusbyte | 5:ea68c8980ad8 | 423 | delay(1000); |
| citrusbyte | 5:ea68c8980ad8 | 424 | } |
| citrusbyte | 5:ea68c8980ad8 | 425 | |
| citrusbyte | 5:ea68c8980ad8 | 426 | // never reached here |
| citrusbyte | 5:ea68c8980ad8 | 427 | return E_NOTREACHABLE; |
| citrusbyte | 5:ea68c8980ad8 | 428 | } |
| citrusbyte | 5:ea68c8980ad8 | 429 | |
| citrusbyte | 5:ea68c8980ad8 | 430 | int M2XStreamClient::skipHttpHeader() { |
| citrusbyte | 5:ea68c8980ad8 | 431 | return waitForString("\r\n\r\n"); |
| citrusbyte | 5:ea68c8980ad8 | 432 | } |
| citrusbyte | 5:ea68c8980ad8 | 433 | |
| citrusbyte | 5:ea68c8980ad8 | 434 | void M2XStreamClient::close() { |
| citrusbyte | 5:ea68c8980ad8 | 435 | // Eats up buffered data before closing |
| citrusbyte | 5:ea68c8980ad8 | 436 | _client->flush(); |
| citrusbyte | 5:ea68c8980ad8 | 437 | _client->stop(); |
| citrusbyte | 5:ea68c8980ad8 | 438 | } |
| citrusbyte | 5:ea68c8980ad8 | 439 | |
| citrusbyte | 5:ea68c8980ad8 | 440 | int M2XStreamClient::readStreamValue(stream_value_read_callback callback, |
| citrusbyte | 5:ea68c8980ad8 | 441 | void* context) { |
| citrusbyte | 5:ea68c8980ad8 | 442 | const int BUF_LEN = 32; |
| citrusbyte | 5:ea68c8980ad8 | 443 | char buf[BUF_LEN]; |
| citrusbyte | 5:ea68c8980ad8 | 444 | |
| citrusbyte | 5:ea68c8980ad8 | 445 | int length = readContentLength(); |
| citrusbyte | 5:ea68c8980ad8 | 446 | if (length < 0) { |
| citrusbyte | 5:ea68c8980ad8 | 447 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 448 | return length; |
| citrusbyte | 5:ea68c8980ad8 | 449 | } |
| citrusbyte | 5:ea68c8980ad8 | 450 | |
| citrusbyte | 5:ea68c8980ad8 | 451 | int index = skipHttpHeader(); |
| citrusbyte | 5:ea68c8980ad8 | 452 | if (index != E_OK) { |
| citrusbyte | 5:ea68c8980ad8 | 453 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 454 | return index; |
| citrusbyte | 5:ea68c8980ad8 | 455 | } |
| citrusbyte | 5:ea68c8980ad8 | 456 | index = 0; |
| citrusbyte | 5:ea68c8980ad8 | 457 | |
| citrusbyte | 5:ea68c8980ad8 | 458 | stream_parsing_context_state state; |
| citrusbyte | 5:ea68c8980ad8 | 459 | state.state = state.index = 0; |
| citrusbyte | 5:ea68c8980ad8 | 460 | state.callback = callback; |
| citrusbyte | 5:ea68c8980ad8 | 461 | state.context = context; |
| citrusbyte | 5:ea68c8980ad8 | 462 | |
| citrusbyte | 5:ea68c8980ad8 | 463 | jsonlite_parser_callbacks cbs = jsonlite_default_callbacks; |
| citrusbyte | 5:ea68c8980ad8 | 464 | cbs.key_found = on_stream_key_found; |
| citrusbyte | 5:ea68c8980ad8 | 465 | cbs.string_found = on_stream_string_found; |
| citrusbyte | 5:ea68c8980ad8 | 466 | cbs.context.client_state = &state; |
| citrusbyte | 5:ea68c8980ad8 | 467 | |
| citrusbyte | 5:ea68c8980ad8 | 468 | jsonlite_parser p = jsonlite_parser_init(jsonlite_parser_estimate_size(5)); |
| citrusbyte | 5:ea68c8980ad8 | 469 | jsonlite_parser_set_callback(p, &cbs); |
| citrusbyte | 5:ea68c8980ad8 | 470 | |
| citrusbyte | 5:ea68c8980ad8 | 471 | jsonlite_result result = jsonlite_result_unknown; |
| citrusbyte | 5:ea68c8980ad8 | 472 | while (index < length) { |
| citrusbyte | 5:ea68c8980ad8 | 473 | int i = 0; |
| citrusbyte | 5:ea68c8980ad8 | 474 | |
| citrusbyte | 5:ea68c8980ad8 | 475 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 476 | printf("Received Data: "); |
| citrusbyte | 5:ea68c8980ad8 | 477 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 478 | while ((i < BUF_LEN) && _client->available()) { |
| citrusbyte | 5:ea68c8980ad8 | 479 | buf[i++] = _client->read(); |
| citrusbyte | 5:ea68c8980ad8 | 480 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 481 | printf("%c", buf[i - 1]); |
| citrusbyte | 5:ea68c8980ad8 | 482 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 483 | } |
| citrusbyte | 5:ea68c8980ad8 | 484 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 485 | printf("\n"); |
| citrusbyte | 5:ea68c8980ad8 | 486 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 487 | |
| citrusbyte | 5:ea68c8980ad8 | 488 | if ((!_client->connected()) && |
| citrusbyte | 5:ea68c8980ad8 | 489 | (!_client->available()) && |
| citrusbyte | 5:ea68c8980ad8 | 490 | ((index + i) < length)) { |
| citrusbyte | 5:ea68c8980ad8 | 491 | jsonlite_parser_release(p); |
| citrusbyte | 5:ea68c8980ad8 | 492 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 493 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 494 | } |
| citrusbyte | 5:ea68c8980ad8 | 495 | |
| citrusbyte | 5:ea68c8980ad8 | 496 | result = jsonlite_parser_tokenize(p, buf, i); |
| citrusbyte | 5:ea68c8980ad8 | 497 | if ((result != jsonlite_result_ok) && |
| citrusbyte | 5:ea68c8980ad8 | 498 | (result != jsonlite_result_end_of_stream)) { |
| citrusbyte | 5:ea68c8980ad8 | 499 | jsonlite_parser_release(p); |
| citrusbyte | 5:ea68c8980ad8 | 500 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 501 | return E_JSON_INVALID; |
| citrusbyte | 5:ea68c8980ad8 | 502 | } |
| citrusbyte | 5:ea68c8980ad8 | 503 | |
| citrusbyte | 5:ea68c8980ad8 | 504 | index += i; |
| citrusbyte | 5:ea68c8980ad8 | 505 | } |
| citrusbyte | 5:ea68c8980ad8 | 506 | |
| citrusbyte | 5:ea68c8980ad8 | 507 | jsonlite_parser_release(p); |
| citrusbyte | 5:ea68c8980ad8 | 508 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 509 | return (result == jsonlite_result_ok) ? (E_OK) : (E_JSON_INVALID); |
| citrusbyte | 5:ea68c8980ad8 | 510 | } |
| citrusbyte | 5:ea68c8980ad8 | 511 | |
| citrusbyte | 5:ea68c8980ad8 | 512 | int M2XStreamClient::readLocation(location_read_callback callback, |
| citrusbyte | 5:ea68c8980ad8 | 513 | void* context) { |
| citrusbyte | 5:ea68c8980ad8 | 514 | const int BUF_LEN = 40; |
| citrusbyte | 5:ea68c8980ad8 | 515 | char buf[BUF_LEN]; |
| citrusbyte | 5:ea68c8980ad8 | 516 | |
| citrusbyte | 5:ea68c8980ad8 | 517 | int length = readContentLength(); |
| citrusbyte | 5:ea68c8980ad8 | 518 | if (length < 0) { |
| citrusbyte | 5:ea68c8980ad8 | 519 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 520 | return length; |
| citrusbyte | 5:ea68c8980ad8 | 521 | } |
| citrusbyte | 5:ea68c8980ad8 | 522 | |
| citrusbyte | 5:ea68c8980ad8 | 523 | int index = skipHttpHeader(); |
| citrusbyte | 5:ea68c8980ad8 | 524 | if (index != E_OK) { |
| citrusbyte | 5:ea68c8980ad8 | 525 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 526 | return index; |
| citrusbyte | 5:ea68c8980ad8 | 527 | } |
| citrusbyte | 5:ea68c8980ad8 | 528 | index = 0; |
| citrusbyte | 5:ea68c8980ad8 | 529 | |
| citrusbyte | 5:ea68c8980ad8 | 530 | location_parsing_context_state state; |
| citrusbyte | 5:ea68c8980ad8 | 531 | state.state = state.index = 0; |
| citrusbyte | 5:ea68c8980ad8 | 532 | state.callback = callback; |
| citrusbyte | 5:ea68c8980ad8 | 533 | state.context = context; |
| citrusbyte | 5:ea68c8980ad8 | 534 | |
| citrusbyte | 5:ea68c8980ad8 | 535 | jsonlite_parser_callbacks cbs = jsonlite_default_callbacks; |
| citrusbyte | 5:ea68c8980ad8 | 536 | cbs.key_found = on_location_key_found; |
| citrusbyte | 5:ea68c8980ad8 | 537 | cbs.string_found = on_location_string_found; |
| citrusbyte | 5:ea68c8980ad8 | 538 | cbs.context.client_state = &state; |
| citrusbyte | 5:ea68c8980ad8 | 539 | |
| citrusbyte | 5:ea68c8980ad8 | 540 | jsonlite_parser p = jsonlite_parser_init(jsonlite_parser_estimate_size(5)); |
| citrusbyte | 5:ea68c8980ad8 | 541 | jsonlite_parser_set_callback(p, &cbs); |
| citrusbyte | 5:ea68c8980ad8 | 542 | |
| citrusbyte | 5:ea68c8980ad8 | 543 | jsonlite_result result = jsonlite_result_unknown; |
| citrusbyte | 5:ea68c8980ad8 | 544 | while (index < length) { |
| citrusbyte | 5:ea68c8980ad8 | 545 | int i = 0; |
| citrusbyte | 5:ea68c8980ad8 | 546 | |
| citrusbyte | 5:ea68c8980ad8 | 547 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 548 | printf("Received Data: "); |
| citrusbyte | 5:ea68c8980ad8 | 549 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 550 | while ((i < BUF_LEN) && _client->available()) { |
| citrusbyte | 5:ea68c8980ad8 | 551 | buf[i++] = _client->read(); |
| citrusbyte | 5:ea68c8980ad8 | 552 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 553 | printf("%c", buf[i - 1]); |
| citrusbyte | 5:ea68c8980ad8 | 554 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 555 | } |
| citrusbyte | 5:ea68c8980ad8 | 556 | #ifdef DEBUG |
| citrusbyte | 5:ea68c8980ad8 | 557 | printf("\n"); |
| citrusbyte | 5:ea68c8980ad8 | 558 | #endif |
| citrusbyte | 5:ea68c8980ad8 | 559 | |
| citrusbyte | 5:ea68c8980ad8 | 560 | if ((!_client->connected()) && |
| citrusbyte | 5:ea68c8980ad8 | 561 | (!_client->available()) && |
| citrusbyte | 5:ea68c8980ad8 | 562 | ((index + i) < length)) { |
| citrusbyte | 5:ea68c8980ad8 | 563 | jsonlite_parser_release(p); |
| citrusbyte | 5:ea68c8980ad8 | 564 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 565 | return E_NOCONNECTION; |
| citrusbyte | 5:ea68c8980ad8 | 566 | } |
| citrusbyte | 5:ea68c8980ad8 | 567 | |
| citrusbyte | 5:ea68c8980ad8 | 568 | result = jsonlite_parser_tokenize(p, buf, i); |
| citrusbyte | 5:ea68c8980ad8 | 569 | if ((result != jsonlite_result_ok) && |
| citrusbyte | 5:ea68c8980ad8 | 570 | (result != jsonlite_result_end_of_stream)) { |
| citrusbyte | 5:ea68c8980ad8 | 571 | jsonlite_parser_release(p); |
| citrusbyte | 5:ea68c8980ad8 | 572 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 573 | return E_JSON_INVALID; |
| citrusbyte | 5:ea68c8980ad8 | 574 | } |
| citrusbyte | 5:ea68c8980ad8 | 575 | |
| citrusbyte | 5:ea68c8980ad8 | 576 | index += i; |
| citrusbyte | 5:ea68c8980ad8 | 577 | } |
| citrusbyte | 5:ea68c8980ad8 | 578 | |
| citrusbyte | 5:ea68c8980ad8 | 579 | jsonlite_parser_release(p); |
| citrusbyte | 5:ea68c8980ad8 | 580 | close(); |
| citrusbyte | 5:ea68c8980ad8 | 581 | return (result == jsonlite_result_ok) ? (E_OK) : (E_JSON_INVALID); |
| citrusbyte | 5:ea68c8980ad8 | 582 | } |
| citrusbyte | 5:ea68c8980ad8 | 583 | |
| citrusbyte | 5:ea68c8980ad8 | 584 |
