ARM mbed M2X API Client: The ARM mbed client library is used to send/receive data to/from AT&T's M2X service from mbed LPC1768 microcontrollers.
Dependents: m2x-demo-all M2X_MTS_ACCEL_DEMO M2X_MTS_Accel M2X_K64F_ACCEL ... more
Revision 10:4ce9eba38dbe, committed 2014-09-10
- Comitter:
- citrusbyte
- Date:
- Wed Sep 10 13:07:34 2014 +0000
- Parent:
- 4:ba0d02be2835
- Child:
- 11:a11af0c81cfa
- Commit message:
- Sync changes with github repo
Changed in this revision
--- a/M2XStreamClient.cpp Sun Sep 07 17:56:18 2014 +0000 +++ b/M2XStreamClient.cpp Wed Sep 10 13:07:34 2014 +0000 @@ -7,6 +7,7 @@ const char* M2XStreamClient::kDefaultM2XHost = "api-m2x.att.com"; +static int write_delete_values(Print* print, const char* from, const char* end); int print_encoded_string(Print* print, const char* str); int tolower(int ch); @@ -105,6 +106,32 @@ return status; } +int M2XStreamClient::deleteValues(const char* feedId, const char* streamName, + const char* from, const char* end) { + if (_client->connect(_host, _port)) { + DBGLN("%s", "Connected to M2X server!"); + int length = write_delete_values(&_null_print, from, end); + writeDeleteHeader(feedId, streamName, length); + write_delete_values(_client, from, end); + } else { + DBGLN("%s", "ERROR: Cannot connect to M2X server!"); + return E_NOCONNECTION; + } + + return readStatusCode(true); +} + +static int write_delete_values(Print* print, const char* from, + const char* end) { + int bytes = 0; + bytes += print->print("{\"from\":\""); + bytes += print->print(from); + bytes += print->print("\",\"end\":\""); + bytes += print->print(end); + bytes += print->print("\"}"); + return bytes; +} + // Encodes and prints string using Percent-encoding specified // in RFC 1738, Section 2.2 int print_encoded_string(Print* print, const char* str) { @@ -126,9 +153,9 @@ return bytes; } -void M2XStreamClient::writePostHeader(const char* feedId, - const char* streamName, - int contentLength) { +void M2XStreamClient::writePutHeader(const char* feedId, + const char* streamName, + int contentLength) { _client->print("PUT /v1/feeds/"); print_encoded_string(_client, feedId); _client->print("/streams/"); @@ -138,6 +165,19 @@ writeHttpHeader(contentLength); } +void M2XStreamClient::writeDeleteHeader(const char* feedId, + const char* streamName, + int contentLength) { + _client->print("DELETE /v1/feeds/"); + print_encoded_string(_client, feedId); + _client->print("/streams/"); + print_encoded_string(_client, streamName); + _client->print("/values"); + _client->println(" HTTP/1.0"); + + writeHttpHeader(contentLength); +} + void M2XStreamClient::writeHttpHeader(int contentLength) { _client->println(USER_AGENT); _client->print("X-M2X-KEY: "); @@ -310,8 +350,8 @@ jsonlite_parser_callbacks cbs = jsonlite_default_callbacks; cbs.key_found = on_stream_key_found; + cbs.number_found = on_stream_number_found; cbs.string_found = on_stream_string_found; - cbs.number_found = on_stream_string_found; cbs.context.client_state = &state; jsonlite_parser p = jsonlite_parser_init(jsonlite_parser_estimate_size(5)); @@ -320,6 +360,7 @@ jsonlite_result result = jsonlite_result_unknown; while (index < length) { int i = 0; + DBG("%s", "Received Data: "); while ((i < BUF_LEN) && _client->available()) { buf[i++] = _client->read(); @@ -342,7 +383,7 @@ close(); return E_JSON_INVALID; } - + index += i; }
--- a/M2XStreamClient.h Sun Sep 07 17:56:18 2014 +0000 +++ b/M2XStreamClient.h Wed Sep 10 13:07:34 2014 +0000 @@ -48,10 +48,18 @@ static const int E_INVALID = -4; static const int E_JSON_INVALID = -5; +/* + * +type+ indicates the value type: 1 for string, 2 for number + * NOTE that the value type here only contains a hint on how + * you can use the value. Even though 2 is returned, the value + * is still stored in (const char *), and atoi/atof is needed to + * get the actual value + */ typedef void (*stream_value_read_callback)(const char* at, const char* value, int index, - void* context); + void* context, + int type); typedef void (*location_read_callback)(const char* name, double latitude, @@ -72,9 +80,9 @@ const char* host = kDefaultM2XHost, int port = kDefaultM2XPort); - // Post data stream value, returns the HTTP status code + // Push data stream value using PUT request, returns the HTTP status code template <class T> - int post(const char* feedId, const char* streamName, T value); + int put(const char* feedId, const char* streamName, T value); // Post multiple values to M2X all at once. // +feedId+ - id of the feed to post values @@ -87,9 +95,8 @@ // be the some of all values in +counts+, for the first +counts[0]+ // items, the values belong to the first stream, for the following // +counts[1]+ number of items, the values belong to the second stream, - // etc. Note timestamps are optional, if a value does not havee timestamp, - // we can simply put NULL here, or we can put NULl for +ats+, meaning - // none of the values has a timestamp + // etc. Notice that timestamps are required here: you must provide + // a timestamp for each value posted. // +values+ - Values to post. This works the same way as +ats+, the // first +counts[0]+ number of items contain values to post to the first // stream, the succeeding +counts[1]+ number of items contain values @@ -140,6 +147,23 @@ // response is only parsed when the HTTP status code is 200 int readLocation(const char* feedId, location_read_callback callback, void* context); + + // Delete values from a data stream + // You will need to provide from and end date/time strings in the ISO8601 + // format "yyyy-mm-ddTHH:MM:SS.SSSZ" where + // yyyy: the year + // mm: the month + // dd: the day + // HH: the hour (24 hour format) + // MM: the minute + // SS.SSS: the seconds (to the millisecond) + // NOTE: the time is given in Zulu (GMT) + // M2X will delete all values within the from to end date/time range. + // The status code is 204 on success and 400 on a bad request (e.g. the + // timestamp is not in ISO8601 format or the from timestamp is not less than + // or equal to the end timestamp. + int deleteValues(const char* feedId, const char* streamName, + const char* from, const char* end); private: Client* _client; const char* _key; @@ -149,9 +173,13 @@ NullPrint _null_print; // Writes the HTTP header part for updating a stream value - void writePostHeader(const char* feedId, - const char* streamName, - int contentLength); + void writePutHeader(const char* feedId, + const char* streamName, + int contentLength); + // Writes the HTTP header part for deleting stream values + void writeDeleteHeader(const char* feedId, + const char* streamName, + int contentLength); // Writes HTTP header lines including M2X API Key, host, content // type and content length(if the body exists) void writeHttpHeader(int contentLength);
--- a/M2XStreamClient_template.h Sun Sep 07 17:56:18 2014 +0000 +++ b/M2XStreamClient_template.h Wed Sep 10 13:07:34 2014 +0000 @@ -6,12 +6,12 @@ int print_encoded_string(Print* print, const char* str); template <class T> -int M2XStreamClient::post(const char* feedId, const char* streamName, T value) { +int M2XStreamClient::put(const char* feedId, const char* streamName, T value) { if (_client->connect(_host, _port)) { DBGLN("%s", "Connected to M2X server!"); - writePostHeader(feedId, streamName, - // for {"value": and } - _null_print.print(value) + 10); + writePutHeader(feedId, streamName, + // for {"value": and } + _null_print.print(value) + 10); _client->print("{\"value\":"); _client->print(value); _client->print("}"); @@ -34,13 +34,9 @@ bytes += print->print(names[i]); bytes += print->print("\":["); for (int j = 0; j < counts[i]; j++) { - bytes += print->print("{"); - if (ats && ats[value_index]) { - bytes += print->print("\"at\": \""); - bytes += print->print(ats[value_index]); - bytes += print->print("\","); - } - bytes += print->print("\"value\": \""); + bytes += print->print("{\"at\": \""); + bytes += print->print(ats[value_index]); + bytes += print->print("\", \"value\": \""); bytes += print->print(values[value_index]); bytes += print->print("\"}"); if (j < counts[i] - 1) { bytes += print->print(","); }
--- a/StreamParseFunctions.h Sun Sep 07 17:56:18 2014 +0000 +++ b/StreamParseFunctions.h Wed Sep 10 13:07:34 2014 +0000 @@ -3,7 +3,7 @@ // Data structures and functions used to parse stream values -#define STREAM_BUF_LEN 64 +#define STREAM_BUF_LEN 32 typedef struct { uint8_t state; @@ -40,11 +40,13 @@ } } -static void on_stream_string_found(jsonlite_callback_context* context, - jsonlite_token* token) +static void on_stream_value_found(jsonlite_callback_context* context, + jsonlite_token* token, + int type) { stream_parsing_context_state* state = (stream_parsing_context_state*) context->client_state; + if (TEST_IS_AT(state->state)) { strncpy(state->at_str, (const char*) token->start, MIN(token->end - token->start, STREAM_BUF_LEN)); @@ -59,9 +61,21 @@ if (TEST_GOT_STREAM(state->state)) { state->callback(state->at_str, state->value_str, - state->index++, state->context); + state->index++, state->context, type); state->state = 0; } } +static void on_stream_string_found(jsonlite_callback_context* context, + jsonlite_token* token) +{ + on_stream_value_found(context, token, 1); +} + +static void on_stream_number_found(jsonlite_callback_context* context, + jsonlite_token* token) +{ + on_stream_value_found(context, token, 2); +} + #endif /* StreamParseFunctions_h */