branch with improvemnts

Fork of M2XStreamClient by AT&T M2X Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers M2XStreamClient.h Source File

M2XStreamClient.h

00001 #ifndef M2XStreamClient_h
00002 #define M2XStreamClient_h
00003 
00004 #define MIN(a, b) (((a) > (b))?(b):(a))
00005 
00006 #define MBED_PLATFORM
00007 
00008 #ifdef ARDUINO_PLATFORM
00009 #include "Arduino.h"
00010 
00011 #define USER_AGENT "User-Agent: M2X Arduino Client/0.1"
00012 #endif
00013 
00014 #ifdef MBED_PLATFORM
00015 #include "mbed.h"
00016 
00017 #define USER_AGENT "User-Agent: M2X Mbed Client/0.1"
00018 #endif
00019 
00020 #include "Client.h"
00021 #include "NullPrint.h"
00022 
00023 #ifdef DEBUG
00024 #ifdef ARDUINO_PLATFORM
00025 #define DBG(fmt_, data_) Serial.print(data_)
00026 #define DBGLN(fmt_, data_) Serial.println(data_)
00027 #define DBGLNEND Serial.println()
00028 #endif  // ARDUINO_PLATFORM
00029 
00030 #ifdef MBED_PLATFORM
00031 #define DBG(fmt_, data_) printf((fmt_), (data_))
00032 #define DBGLN(fmt_, data_) printf((fmt_), (data_)); printf("\n")
00033 #define DBGLNEND printf("\n")
00034 #endif  // MBED_PLATFORM
00035 #else
00036 #define DBG(fmt_, data_)
00037 #define DBGLN(fmt_, data_)
00038 #define DBGLNEND
00039 #endif  // DEBUG
00040 
00041 #define HEX(t_) ((char) (((t_) > 9) ? ((t_) - 10 + 'A') : ((t_) + '0')))
00042 #define MAX_DOUBLE_DIGITS 7
00043 
00044 static const int E_OK = 0;
00045 static const int E_NOCONNECTION = -1;
00046 static const int E_DISCONNECTED = -2;
00047 static const int E_NOTREACHABLE = -3;
00048 static const int E_INVALID = -4;
00049 static const int E_JSON_INVALID = -5;
00050 
00051 /*
00052  * +type+ indicates the value type: 1 for string, 2 for number
00053  * NOTE that the value type here only contains a hint on how
00054  * you can use the value. Even though 2 is returned, the value
00055  * is still stored in (const char *), and atoi/atof is needed to
00056  * get the actual value
00057  */
00058 typedef void (*stream_value_read_callback)(const char* at,
00059                                            const char* value,
00060                                            int index,
00061                                            void* context,
00062                                            int type);
00063 
00064 typedef void (*location_read_callback)(const char* name,
00065                                        double latitude,
00066                                        double longitude,
00067                                        double elevation,
00068                                        const char* timestamp,
00069                                        int index,
00070                                        void* context);
00071 
00072 class M2XStreamClient {
00073 public:
00074   static const char* kDefaultM2XHost;
00075   static const int kDefaultM2XPort = 80;
00076 
00077   M2XStreamClient(Client* client,
00078                   const char* key,
00079                   int case_insensitive = 1,
00080                   const char* host = kDefaultM2XHost,
00081                   int port = kDefaultM2XPort);
00082 
00083   // Push data stream value using PUT request, returns the HTTP status code
00084   template <class T>
00085   int put(const char* feedId, const char* streamName, T value);
00086 
00087   // Post multiple values to M2X all at once.
00088   // +feedId+ - id of the feed to post values
00089   // +streamNum+ - Number of streams to post
00090   // +names+ - Array of stream names, the length of the array should
00091   // be exactly +streamNum+
00092   // +counts+ - Array of +streamNum+ length, each item in this array
00093   // containing the number of values we want to post for each stream
00094   // +ats+ - Timestamps for each value, the length of this array should
00095   // be the some of all values in +counts+, for the first +counts[0]+
00096   // items, the values belong to the first stream, for the following
00097   // +counts[1]+ number of items, the values belong to the second stream,
00098   // etc. Notice that timestamps are required here: you must provide
00099   // a timestamp for each value posted.
00100   // +values+ - Values to post. This works the same way as +ats+, the
00101   // first +counts[0]+ number of items contain values to post to the first
00102   // stream, the succeeding +counts[1]+ number of items contain values
00103   // for the second stream, etc. The length of this array should be
00104   // the sum of all values in +counts+ array.
00105   template <class T>
00106   int postMultiple(const char* feedId, int streamNum,
00107                    const char* names[], const int counts[],
00108                    const char* ats[], T values[]);
00109 
00110   // Fetch values for a particular data stream. Since memory is
00111   // very limited on an Arduino, we cannot parse and get all the
00112   // data points in memory. Instead, we use callbacks here: whenever
00113   // a new data point is parsed, we call the callback using the values,
00114   // after that, the values will be thrown away to make space for new
00115   // values.
00116   // Note that you can also pass in a user-specified context in this
00117   // function, this context will be passed to the callback function
00118   // each time we get a data point.
00119   // For each data point, the callback will be called once. The HTTP
00120   // status code will be returned. And the content is only parsed when
00121   // the status code is 200.
00122   int fetchValues(const char* feedId, const char* streamName,
00123                   stream_value_read_callback callback, void* context,
00124                   const char* startTime = NULL, const char* endTime = NULL,
00125                   const char* limit = NULL);
00126 
00127   // Update datasource location
00128   // NOTE: On an Arduino Uno and other ATMEGA based boards, double has
00129   // 4-byte (32 bits) precision, which is the same as float. So there's
00130   // no natural double-precision floating number on these boards. With
00131   // a float value, we have a precision of roughly 7 digits, that means
00132   // either 5 or 6 digits after the floating point. According to wikipedia,
00133   // a difference of 0.00001 will give us ~1.1132m distance. If this
00134   // precision is good for you, you can use the double-version we provided
00135   // here. Otherwise, you may need to use the string-version and do the
00136   // actual conversion by yourselves.
00137   // However, with an Arduino Due board, double has 8-bytes (64 bits)
00138   // precision, which means you are free to use the double-version only
00139   // without any precision problems.
00140   // Returned value is the http status code.
00141   template <class T>
00142   int updateLocation(const char* feedId, const char* name,
00143                      T latitude, T longitude, T elevation);
00144 
00145   // Read location information for a feed. Also used callback to process
00146   // data points for memory reasons. The HTTP status code is returned,
00147   // response is only parsed when the HTTP status code is 200
00148   int readLocation(const char* feedId, location_read_callback callback,
00149                    void* context);
00150 
00151   // Delete values from a data stream
00152   // You will need to provide from and end date/time strings in the ISO8601
00153   // format "yyyy-mm-ddTHH:MM:SS.SSSZ" where
00154   //   yyyy: the year
00155   //   mm: the month
00156   //   dd: the day
00157   //   HH: the hour (24 hour format)
00158   //   MM: the minute
00159   //   SS.SSS: the seconds (to the millisecond)
00160   // NOTE: the time is given in Zulu (GMT)
00161   // M2X will delete all values within the from to end date/time range.
00162   // The status code is 204 on success and 400 on a bad request (e.g. the
00163   // timestamp is not in ISO8601 format or the from timestamp is not less than
00164   // or equal to the end timestamp.
00165   int deleteValues(const char* feedId, const char* streamName,
00166                    const char* from, const char* end);
00167 private:
00168   Client* _client;
00169   const char* _key;
00170   int _case_insensitive;
00171   const char* _host;
00172   int _port;
00173   NullPrint _null_print;
00174 
00175   // Writes the HTTP header part for updating a stream value
00176   void writePutHeader(const char* feedId,
00177                       const char* streamName,
00178                       int contentLength);
00179   // Writes the HTTP header part for deleting stream values
00180   void writeDeleteHeader(const char* feedId,
00181                          const char* streamName,
00182                          int contentLength);
00183   // Writes HTTP header lines including M2X API Key, host, content
00184   // type and content length(if the body exists)
00185   void writeHttpHeader(int contentLength);
00186   // Parses HTTP response header and return the content length.
00187   // Note that this function does not parse all http headers, as long
00188   // as the content length is found, this function will return
00189   int readContentLength();
00190   // Skips all HTTP response header part. Return minus value in case
00191   // the connection is closed before we got all headers
00192   int skipHttpHeader();
00193   // Parses and returns the HTTP status code, note this function will
00194   // return immediately once it gets the status code
00195   int readStatusCode(bool closeClient);
00196   // Waits for a certain string pattern in the HTTP header, and returns
00197   // once the pattern is found. In the pattern, you can use '*' to denote
00198   // any character
00199   int waitForString(const char* str);
00200   // Closes the connection
00201   void close();
00202   // Parses JSON response of stream value API, and calls callback function
00203   // once we get a data point
00204   int readStreamValue(stream_value_read_callback callback, void* context);
00205   // Parses JSON response of location API, and calls callback function once
00206   // we get a data point
00207   int readLocation(location_read_callback callback, void* context);
00208 };
00209 
00210 #include "M2XStreamClient_template.h"
00211 
00212 #endif  /* M2XStreamClient_h */