test
Fork of mbed-libxively-6eca970 by
src/libxively/xively.h@0:82702e998d3f, 2013-06-26 (annotated)
- Committer:
- xively
- Date:
- Wed Jun 26 10:40:43 2013 +0000
- Revision:
- 0:82702e998d3f
libxively v0.1.1-rc0 (34c8b32)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xively | 0:82702e998d3f | 1 | // Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved. |
xively | 0:82702e998d3f | 2 | // This is part of Xively C library, it is under the BSD 3-Clause license. |
xively | 0:82702e998d3f | 3 | |
xively | 0:82702e998d3f | 4 | /** |
xively | 0:82702e998d3f | 5 | * \file xively.h |
xively | 0:82702e998d3f | 6 | * \brief Xively C library |
xively | 0:82702e998d3f | 7 | */ |
xively | 0:82702e998d3f | 8 | |
xively | 0:82702e998d3f | 9 | #ifndef __XI_H__ |
xively | 0:82702e998d3f | 10 | #define __XI_H__ |
xively | 0:82702e998d3f | 11 | |
xively | 0:82702e998d3f | 12 | #include <stdlib.h> |
xively | 0:82702e998d3f | 13 | #include <stdint.h> |
xively | 0:82702e998d3f | 14 | |
xively | 0:82702e998d3f | 15 | #include <time.h> |
xively | 0:82702e998d3f | 16 | |
xively | 0:82702e998d3f | 17 | #include "comm_layer.h" |
xively | 0:82702e998d3f | 18 | #include "xi_consts.h" |
xively | 0:82702e998d3f | 19 | |
xively | 0:82702e998d3f | 20 | #ifdef __cplusplus |
xively | 0:82702e998d3f | 21 | extern "C" { |
xively | 0:82702e998d3f | 22 | #endif |
xively | 0:82702e998d3f | 23 | |
xively | 0:82702e998d3f | 24 | //----------------------------------------------------------------------- |
xively | 0:82702e998d3f | 25 | // TYPES AND STRUCTURES |
xively | 0:82702e998d3f | 26 | //----------------------------------------------------------------------- |
xively | 0:82702e998d3f | 27 | |
xively | 0:82702e998d3f | 28 | /** |
xively | 0:82702e998d3f | 29 | * \brief The protocols currently supported by Xively |
xively | 0:82702e998d3f | 30 | * \note See source code for details of what's implemented. |
xively | 0:82702e998d3f | 31 | */ |
xively | 0:82702e998d3f | 32 | typedef enum { |
xively | 0:82702e998d3f | 33 | /** `http://api.xively.com` */ |
xively | 0:82702e998d3f | 34 | XI_HTTP, |
xively | 0:82702e998d3f | 35 | /** `https://api.xively.com` */ |
xively | 0:82702e998d3f | 36 | XI_HTTPS, |
xively | 0:82702e998d3f | 37 | /** `telnet api.xively.com 8081` */ |
xively | 0:82702e998d3f | 38 | XI_TCP, |
xively | 0:82702e998d3f | 39 | /** `openssl s_client -host api.xively.com -port 8091 -tls1` */ |
xively | 0:82702e998d3f | 40 | XI_TCPS, |
xively | 0:82702e998d3f | 41 | /** `ws://api.xively.com:8080` */ |
xively | 0:82702e998d3f | 42 | XI_WS, |
xively | 0:82702e998d3f | 43 | /** `wss://api.xively.com:8090` */ |
xively | 0:82702e998d3f | 44 | XI_WSS, |
xively | 0:82702e998d3f | 45 | } xi_protocol_t; |
xively | 0:82702e998d3f | 46 | |
xively | 0:82702e998d3f | 47 | /** |
xively | 0:82702e998d3f | 48 | * \brief _The context structure_ - it's the first agument for all functions |
xively | 0:82702e998d3f | 49 | * that communicate with Xively API (_i.e. not helpers or utilities_) |
xively | 0:82702e998d3f | 50 | */ |
xively | 0:82702e998d3f | 51 | typedef struct { |
xively | 0:82702e998d3f | 52 | char *api_key; /** Xively API key */ |
xively | 0:82702e998d3f | 53 | xi_protocol_t protocol; /** Xively protocol */ |
xively | 0:82702e998d3f | 54 | int32_t feed_id; /** Xively feed ID */ |
xively | 0:82702e998d3f | 55 | } xi_context_t; |
xively | 0:82702e998d3f | 56 | |
xively | 0:82702e998d3f | 57 | /** |
xively | 0:82702e998d3f | 58 | * \brief HTTP headers |
xively | 0:82702e998d3f | 59 | */ |
xively | 0:82702e998d3f | 60 | typedef enum |
xively | 0:82702e998d3f | 61 | { |
xively | 0:82702e998d3f | 62 | /** `Date` */ |
xively | 0:82702e998d3f | 63 | XI_HTTP_HEADER_DATE = 0, |
xively | 0:82702e998d3f | 64 | /** `Content-Type` */ |
xively | 0:82702e998d3f | 65 | XI_HTTP_HEADER_CONTENT_TYPE, |
xively | 0:82702e998d3f | 66 | /** `Content-Length` */ |
xively | 0:82702e998d3f | 67 | XI_HTTP_HEADER_CONTENT_LENGTH, |
xively | 0:82702e998d3f | 68 | /** `Connection` */ |
xively | 0:82702e998d3f | 69 | XI_HTTP_HEADER_CONNECTION, |
xively | 0:82702e998d3f | 70 | /** `X-Request-Id` */ |
xively | 0:82702e998d3f | 71 | XI_HTTP_HEADER_X_REQUEST_ID, |
xively | 0:82702e998d3f | 72 | /** `Cache-Control` */ |
xively | 0:82702e998d3f | 73 | XI_HTTP_HEADER_CACHE_CONTROL, |
xively | 0:82702e998d3f | 74 | /** `Vary` */ |
xively | 0:82702e998d3f | 75 | XI_HTTP_HEADER_VARY, |
xively | 0:82702e998d3f | 76 | /** `Count` */ |
xively | 0:82702e998d3f | 77 | XI_HTTP_HEADER_COUNT, |
xively | 0:82702e998d3f | 78 | /** `Age` */ |
xively | 0:82702e998d3f | 79 | XI_HTTP_HEADER_AGE, |
xively | 0:82702e998d3f | 80 | // must go before the last here |
xively | 0:82702e998d3f | 81 | XI_HTTP_HEADER_UNKNOWN, |
xively | 0:82702e998d3f | 82 | // must be the last here |
xively | 0:82702e998d3f | 83 | XI_HTTP_HEADERS_COUNT |
xively | 0:82702e998d3f | 84 | } http_header_type_t; |
xively | 0:82702e998d3f | 85 | |
xively | 0:82702e998d3f | 86 | /** Datapoint value types */ |
xively | 0:82702e998d3f | 87 | typedef enum |
xively | 0:82702e998d3f | 88 | { /** 32-bit signed integer */ |
xively | 0:82702e998d3f | 89 | XI_VALUE_TYPE_I32 = 0, |
xively | 0:82702e998d3f | 90 | /** 32-bit floating point number */ |
xively | 0:82702e998d3f | 91 | XI_VALUE_TYPE_F32, |
xively | 0:82702e998d3f | 92 | /** any string-econded data */ |
xively | 0:82702e998d3f | 93 | XI_VALUE_TYPE_STR, |
xively | 0:82702e998d3f | 94 | XI_VALUE_TYPE_COUNT |
xively | 0:82702e998d3f | 95 | } xi_value_type_t; |
xively | 0:82702e998d3f | 96 | |
xively | 0:82702e998d3f | 97 | typedef struct { |
xively | 0:82702e998d3f | 98 | http_header_type_t header_type; |
xively | 0:82702e998d3f | 99 | char name[ XI_HTTP_HEADER_NAME_MAX_SIZE ]; |
xively | 0:82702e998d3f | 100 | char value[ XI_HTTP_HEADER_VALUE_MAX_SIZE ]; |
xively | 0:82702e998d3f | 101 | } http_header_t; |
xively | 0:82702e998d3f | 102 | |
xively | 0:82702e998d3f | 103 | typedef struct { |
xively | 0:82702e998d3f | 104 | int http_version1; |
xively | 0:82702e998d3f | 105 | int http_version2; |
xively | 0:82702e998d3f | 106 | int http_status; |
xively | 0:82702e998d3f | 107 | char http_status_string[ XI_HTTP_STATUS_STRING_SIZE ]; |
xively | 0:82702e998d3f | 108 | http_header_t* http_headers_checklist[ XI_HTTP_HEADERS_COUNT ]; |
xively | 0:82702e998d3f | 109 | http_header_t http_headers[ XI_HTTP_MAX_HEADERS ]; |
xively | 0:82702e998d3f | 110 | size_t http_headers_size; |
xively | 0:82702e998d3f | 111 | char http_content[ XI_HTTP_MAX_CONTENT_SIZE ]; |
xively | 0:82702e998d3f | 112 | } http_response_t; |
xively | 0:82702e998d3f | 113 | |
xively | 0:82702e998d3f | 114 | /** |
xively | 0:82702e998d3f | 115 | * \brief _The response structure_ - it's the return type for all functions |
xively | 0:82702e998d3f | 116 | * that communicate with Xively API (_i.e. not helpers or utilities_) |
xively | 0:82702e998d3f | 117 | */ |
xively | 0:82702e998d3f | 118 | typedef struct { |
xively | 0:82702e998d3f | 119 | http_response_t http; |
xively | 0:82702e998d3f | 120 | } xi_response_t; |
xively | 0:82702e998d3f | 121 | |
xively | 0:82702e998d3f | 122 | /** |
xively | 0:82702e998d3f | 123 | * \brief The datapoint value union |
xively | 0:82702e998d3f | 124 | */ |
xively | 0:82702e998d3f | 125 | typedef union { |
xively | 0:82702e998d3f | 126 | int32_t i32_value; |
xively | 0:82702e998d3f | 127 | float f32_value; |
xively | 0:82702e998d3f | 128 | char str_value[ XI_VALUE_STRING_MAX_SIZE ]; |
xively | 0:82702e998d3f | 129 | } xi_datapoint_value_t; |
xively | 0:82702e998d3f | 130 | |
xively | 0:82702e998d3f | 131 | /** |
xively | 0:82702e998d3f | 132 | * \brief The datapoint timestamp |
xively | 0:82702e998d3f | 133 | */ |
xively | 0:82702e998d3f | 134 | typedef struct { |
xively | 0:82702e998d3f | 135 | time_t timestamp; |
xively | 0:82702e998d3f | 136 | time_t micro; |
xively | 0:82702e998d3f | 137 | } xi_timestamp_t; |
xively | 0:82702e998d3f | 138 | |
xively | 0:82702e998d3f | 139 | /** |
xively | 0:82702e998d3f | 140 | * \brief _Xively datapoint structure_ - it contains value and timestamp |
xively | 0:82702e998d3f | 141 | * \note A zero-valued timestamp is used by most functions as a convention |
xively | 0:82702e998d3f | 142 | * to opt for server-side timestamps. |
xively | 0:82702e998d3f | 143 | */ |
xively | 0:82702e998d3f | 144 | typedef struct { |
xively | 0:82702e998d3f | 145 | xi_datapoint_value_t value; |
xively | 0:82702e998d3f | 146 | xi_value_type_t value_type; |
xively | 0:82702e998d3f | 147 | xi_timestamp_t timestamp; |
xively | 0:82702e998d3f | 148 | } xi_datapoint_t; |
xively | 0:82702e998d3f | 149 | |
xively | 0:82702e998d3f | 150 | typedef struct { |
xively | 0:82702e998d3f | 151 | char datastream_id[ XI_MAX_DATASTREAM_NAME ]; |
xively | 0:82702e998d3f | 152 | size_t datapoint_count; |
xively | 0:82702e998d3f | 153 | xi_datapoint_t datapoints[ XI_MAX_DATAPOINTS ]; |
xively | 0:82702e998d3f | 154 | } xi_datastream_t; |
xively | 0:82702e998d3f | 155 | |
xively | 0:82702e998d3f | 156 | /** |
xively | 0:82702e998d3f | 157 | * \brief _Xively feed structure_ - it contains a fixed array of datastream |
xively | 0:82702e998d3f | 158 | * \note The implementation is such that user will need to know in advance |
xively | 0:82702e998d3f | 159 | * how many datastreams there can be, which should be sufficent for |
xively | 0:82702e998d3f | 160 | * a real-world application. It's also undesired to have some devices |
xively | 0:82702e998d3f | 161 | * create dozens of datastreams due to a bug. |
xively | 0:82702e998d3f | 162 | */ |
xively | 0:82702e998d3f | 163 | typedef struct { |
xively | 0:82702e998d3f | 164 | int32_t feed_id; |
xively | 0:82702e998d3f | 165 | size_t datastream_count; |
xively | 0:82702e998d3f | 166 | xi_datastream_t datastreams[ XI_MAX_DATASTREAMS ]; |
xively | 0:82702e998d3f | 167 | } xi_feed_t; |
xively | 0:82702e998d3f | 168 | |
xively | 0:82702e998d3f | 169 | //----------------------------------------------------------------------- |
xively | 0:82702e998d3f | 170 | // HELPER FUNCTIONS |
xively | 0:82702e998d3f | 171 | //----------------------------------------------------------------------- |
xively | 0:82702e998d3f | 172 | |
xively | 0:82702e998d3f | 173 | /** |
xively | 0:82702e998d3f | 174 | * \brief Sets the xi_datapoint_t value field to `int32_t` value |
xively | 0:82702e998d3f | 175 | * |
xively | 0:82702e998d3f | 176 | * \return Pointer or `0` if an error occurred. |
xively | 0:82702e998d3f | 177 | */ |
xively | 0:82702e998d3f | 178 | extern xi_datapoint_t* xi_set_value_i32( xi_datapoint_t* dp, int32_t v ); |
xively | 0:82702e998d3f | 179 | |
xively | 0:82702e998d3f | 180 | /** |
xively | 0:82702e998d3f | 181 | * \brief Sets the `xi_datapoint_t` value field to `float` value |
xively | 0:82702e998d3f | 182 | * \return Pointer or `0` if an error occurred. |
xively | 0:82702e998d3f | 183 | */ |
xively | 0:82702e998d3f | 184 | extern xi_datapoint_t* xi_set_value_f32( xi_datapoint_t* dp, float v ); |
xively | 0:82702e998d3f | 185 | |
xively | 0:82702e998d3f | 186 | /** |
xively | 0:82702e998d3f | 187 | * \brief Sets the `xi_datapoint_t` value field to zero-terminated string value |
xively | 0:82702e998d3f | 188 | * |
xively | 0:82702e998d3f | 189 | * \return Pointer or `0` if an error occurred. |
xively | 0:82702e998d3f | 190 | */ |
xively | 0:82702e998d3f | 191 | extern xi_datapoint_t* xi_set_value_str( xi_datapoint_t* dp, const char* v ); |
xively | 0:82702e998d3f | 192 | |
xively | 0:82702e998d3f | 193 | /** |
xively | 0:82702e998d3f | 194 | * \brief Sets the timeout for network operations |
xively | 0:82702e998d3f | 195 | * |
xively | 0:82702e998d3f | 196 | * \note The timeout is used by the comunication layer |
xively | 0:82702e998d3f | 197 | * to determine whenever it should treat the lag |
xively | 0:82702e998d3f | 198 | * in a connection as an error, so if your device |
xively | 0:82702e998d3f | 199 | * or your connection is slow, you can try to increase |
xively | 0:82702e998d3f | 200 | * the timeout for network operations. It only affects the |
xively | 0:82702e998d3f | 201 | * send/recv operations it does not work with connect but that |
xively | 0:82702e998d3f | 202 | * behaviour may differ between platforms and communication |
xively | 0:82702e998d3f | 203 | * layer imlementations. |
xively | 0:82702e998d3f | 204 | */ |
xively | 0:82702e998d3f | 205 | extern void xi_set_network_timeout( uint32_t milliseconds ); |
xively | 0:82702e998d3f | 206 | |
xively | 0:82702e998d3f | 207 | /** |
xively | 0:82702e998d3f | 208 | * \brief Gets the current network timeout |
xively | 0:82702e998d3f | 209 | */ |
xively | 0:82702e998d3f | 210 | extern uint32_t xi_get_network_timeout( void ); |
xively | 0:82702e998d3f | 211 | |
xively | 0:82702e998d3f | 212 | //----------------------------------------------------------------------- |
xively | 0:82702e998d3f | 213 | // MAIN LIBRARY FUNCTIONS |
xively | 0:82702e998d3f | 214 | //----------------------------------------------------------------------- |
xively | 0:82702e998d3f | 215 | |
xively | 0:82702e998d3f | 216 | /** |
xively | 0:82702e998d3f | 217 | * \brief Library context constructor |
xively | 0:82702e998d3f | 218 | * |
xively | 0:82702e998d3f | 219 | * The purpose of this function is to allocate memory and initialise the |
xively | 0:82702e998d3f | 220 | * data structures needed in order to use any other library functions. |
xively | 0:82702e998d3f | 221 | * |
xively | 0:82702e998d3f | 222 | * \return Initialised context structure or `0` if an error occurred |
xively | 0:82702e998d3f | 223 | */ |
xively | 0:82702e998d3f | 224 | extern xi_context_t* xi_create_context( |
xively | 0:82702e998d3f | 225 | xi_protocol_t protocol, const char* api_key |
xively | 0:82702e998d3f | 226 | , int32_t feed_id ); |
xively | 0:82702e998d3f | 227 | |
xively | 0:82702e998d3f | 228 | /** |
xively | 0:82702e998d3f | 229 | * \brief Library context destructor |
xively | 0:82702e998d3f | 230 | * |
xively | 0:82702e998d3f | 231 | * The purpose of this fucntion is to free all allocated resources |
xively | 0:82702e998d3f | 232 | * when the application is intending to terminate or stop using the library. |
xively | 0:82702e998d3f | 233 | */ |
xively | 0:82702e998d3f | 234 | extern void xi_delete_context( xi_context_t* context ); |
xively | 0:82702e998d3f | 235 | |
xively | 0:82702e998d3f | 236 | |
xively | 0:82702e998d3f | 237 | /** |
xively | 0:82702e998d3f | 238 | * \brief Update Xively feed |
xively | 0:82702e998d3f | 239 | */ |
xively | 0:82702e998d3f | 240 | extern const xi_response_t* xi_feed_update( |
xively | 0:82702e998d3f | 241 | xi_context_t* xi |
xively | 0:82702e998d3f | 242 | , const xi_feed_t* value ); |
xively | 0:82702e998d3f | 243 | |
xively | 0:82702e998d3f | 244 | /** |
xively | 0:82702e998d3f | 245 | * \brief Retrieve Xively feed |
xively | 0:82702e998d3f | 246 | */ |
xively | 0:82702e998d3f | 247 | extern const xi_response_t* xi_feed_get( |
xively | 0:82702e998d3f | 248 | xi_context_t* xi |
xively | 0:82702e998d3f | 249 | , xi_feed_t* value ); |
xively | 0:82702e998d3f | 250 | |
xively | 0:82702e998d3f | 251 | /** |
xively | 0:82702e998d3f | 252 | * \brief Create a datastream with given value using server timestamp |
xively | 0:82702e998d3f | 253 | */ |
xively | 0:82702e998d3f | 254 | extern const xi_response_t* xi_datastream_create( |
xively | 0:82702e998d3f | 255 | xi_context_t* xi, int32_t feed_id |
xively | 0:82702e998d3f | 256 | , const char * datastream_id |
xively | 0:82702e998d3f | 257 | , const xi_datapoint_t* value); |
xively | 0:82702e998d3f | 258 | |
xively | 0:82702e998d3f | 259 | /** |
xively | 0:82702e998d3f | 260 | * \brief Update a datastream with given datapoint using server or local timestamp |
xively | 0:82702e998d3f | 261 | */ |
xively | 0:82702e998d3f | 262 | extern const xi_response_t* xi_datastream_update( |
xively | 0:82702e998d3f | 263 | xi_context_t* xi, int32_t feed_id |
xively | 0:82702e998d3f | 264 | , const char * datastream_id |
xively | 0:82702e998d3f | 265 | , const xi_datapoint_t* value ); |
xively | 0:82702e998d3f | 266 | |
xively | 0:82702e998d3f | 267 | /** |
xively | 0:82702e998d3f | 268 | * \brief Retrieve latest datapoint from a given datastream |
xively | 0:82702e998d3f | 269 | */ |
xively | 0:82702e998d3f | 270 | extern const xi_response_t* xi_datastream_get( |
xively | 0:82702e998d3f | 271 | xi_context_t* xi, int32_t feed_id |
xively | 0:82702e998d3f | 272 | , const char * datastream_id, xi_datapoint_t* dp ); |
xively | 0:82702e998d3f | 273 | |
xively | 0:82702e998d3f | 274 | /** |
xively | 0:82702e998d3f | 275 | * \brief Delete datastream |
xively | 0:82702e998d3f | 276 | * \warning This function destroys the data in Xively and there is no way to restore it! |
xively | 0:82702e998d3f | 277 | */ |
xively | 0:82702e998d3f | 278 | extern const xi_response_t* xi_datastream_delete( |
xively | 0:82702e998d3f | 279 | xi_context_t* xi, int feed_id |
xively | 0:82702e998d3f | 280 | , const char* datastream_id ); |
xively | 0:82702e998d3f | 281 | |
xively | 0:82702e998d3f | 282 | /** |
xively | 0:82702e998d3f | 283 | * \brief Delete datapoint at a given timestamp |
xively | 0:82702e998d3f | 284 | * \warning This function destroys the data in Xively and there is no way to restore it! |
xively | 0:82702e998d3f | 285 | * \note You need to provide exact timestamp value to guarantee successful response |
xively | 0:82702e998d3f | 286 | * from the API, i.e. it will respond with error 404 if datapoint didn't exist. |
xively | 0:82702e998d3f | 287 | * If you need to determine the exact timestamp, it may be easier to call |
xively | 0:82702e998d3f | 288 | * `xi_datapoint_delete_range()` with short range instead. |
xively | 0:82702e998d3f | 289 | */ |
xively | 0:82702e998d3f | 290 | extern const xi_response_t* xi_datapoint_delete( |
xively | 0:82702e998d3f | 291 | const xi_context_t* xi, int feed_id |
xively | 0:82702e998d3f | 292 | , const char * datastream_id |
xively | 0:82702e998d3f | 293 | , const xi_datapoint_t* dp ); |
xively | 0:82702e998d3f | 294 | |
xively | 0:82702e998d3f | 295 | /** |
xively | 0:82702e998d3f | 296 | * \brief Delete all datapoints in given time range |
xively | 0:82702e998d3f | 297 | * \warning This function destroys the data in Xively and there is no way to restore it! |
xively | 0:82702e998d3f | 298 | */ |
xively | 0:82702e998d3f | 299 | extern const xi_response_t* xi_datapoint_delete_range( |
xively | 0:82702e998d3f | 300 | const xi_context_t* xi, int feed_id, const char * datastream_id |
xively | 0:82702e998d3f | 301 | , const xi_timestamp_t* start, const xi_timestamp_t* end ); |
xively | 0:82702e998d3f | 302 | |
xively | 0:82702e998d3f | 303 | #ifdef __cplusplus |
xively | 0:82702e998d3f | 304 | } |
xively | 0:82702e998d3f | 305 | #endif |
xively | 0:82702e998d3f | 306 | |
xively | 0:82702e998d3f | 307 | #endif // __XI_H__ |