branch with improvemnts
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 |