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.
Dependents: WNCInterface_M2Xdemo ATT_WNCInterface_Info WNCInterface_HTTP_example Public_IoT_M2X_Cellular_Demo
Fork of M2XStreamClient by
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 */
