Xively Official / mbed-libxively-5d6fdd4

Dependents:   xively-jumpstart-demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xively.c Source File

xively.c

Go to the documentation of this file.
00001 // Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved.
00002 // This is part of Xively C library, it is under the BSD 3-Clause license.
00003 
00004 /**
00005  * \file    xively.c
00006  * \brief   Xively C library [see xively.h]
00007  */
00008 
00009 #include <string.h>
00010 #include <assert.h>
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 
00014 #include "xi_allocator.h"
00015 #include "xively.h"
00016 #include "http_transport.h"
00017 #include "csv_data_layer.h"
00018 #include "xi_macros.h"
00019 #include "xi_debug.h"
00020 #include "xi_helpers.h"
00021 #include "xi_err.h"
00022 #include "xi_globals.h"
00023 
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027 
00028 /**
00029  * \brief   Get instance of _communication layer_
00030  *
00031  * \note    Although the interface is of the _communication layer_ should
00032  *          stay the same, some implemantation may differ.
00033  *
00034  * \return  Pointer to the communication layer interface
00035  */
00036 const comm_layer_t* get_comm_layer( void );
00037 
00038 #include "comm_layer.h"
00039 
00040 //-----------------------------------------------------------------------
00041 // HELPER MACROS
00042 //-----------------------------------------------------------------------
00043 
00044 #define XI_FUNCTION_VARIABLES connection_t* conn = 0;\
00045     const comm_layer_t* comm_layer = 0;\
00046     const transport_layer_t* transport_layer = 0;\
00047     const data_layer_t* data_layer = 0;\
00048     char  buffer[ XI_HTTP_MAX_CONTENT_SIZE ];\
00049     const xi_response_t* response = 0;\
00050     int sent = 0;\
00051     int recv = 0;
00052 
00053 #define XI_FUNCTION_PROLOGUE  XI_FUNCTION_VARIABLES\
00054     xi_debug_log_str( "Getting the comm layer...\n" );\
00055     comm_layer = get_comm_layer();\
00056     xi_debug_log_str( "Getting the transport layer...\n" );\
00057     transport_layer = get_http_transport_layer();\
00058     xi_debug_log_str( "Getting the data layer...\n");\
00059     data_layer = get_csv_data_layer();\
00060 
00061 #define XI_FUNCTION_GET_RESPONSE if( data == 0 ) { goto err_handling; }\
00062     xi_debug_log_str( "Connecting to the endpoint...\n" );\
00063     conn = comm_layer->open_connection( XI_HOST, XI_PORT );\
00064     if( conn == 0 ) { goto err_handling; }\
00065     xi_debug_log_str( "Sending data:\n" );\
00066     xi_debug_log_data( data );\
00067     sent = comm_layer->send_data( conn, data, strlen( data ) );\
00068     if( sent == -1 ) { goto err_handling; }\
00069     xi_debug_log_str( "Sent: " );\
00070     xi_debug_log_int( ( int ) sent );\
00071     xi_debug_log_endl();\
00072     xi_debug_log_str( "Reading data...\n" );\
00073     recv = comm_layer->read_data( conn, buffer, XI_HTTP_MAX_CONTENT_SIZE );\
00074     if( recv == -1 ) { goto err_handling; }\
00075     xi_debug_log_str( "Received: " );\
00076     xi_debug_log_int( ( int ) recv );\
00077     xi_debug_log_endl();\
00078     xi_debug_log_str( "Response:\n" );\
00079     xi_debug_log_data( buffer );\
00080     xi_debug_log_endl();\
00081     response = transport_layer->decode_reply(\
00082         data_layer, buffer );\
00083     if( response == 0 ) { goto err_handling; }\
00084 
00085 #define XI_FUNCTION_EPILOGUE xi_debug_log_str( "Closing connection...\n" );\
00086 err_handling:\
00087     if( conn )\
00088     {\
00089         comm_layer->close_connection( conn );\
00090     }\
00091     return response;\
00092 
00093 //-----------------------------------------------------------------------
00094 // HELPER FUNCTIONS
00095 //-----------------------------------------------------------------------
00096 
00097 xi_datapoint_t* xi_set_value_i32( xi_datapoint_t* p, int32_t value )
00098 {
00099     // PRECONDITION
00100     assert( p != 0 );
00101 
00102     p->value.i32_value  = value;
00103     p->value_type       = XI_VALUE_TYPE_I32;
00104 
00105     return p;
00106 }
00107 
00108 xi_datapoint_t* xi_set_value_f32( xi_datapoint_t* p, float value )
00109 {
00110     // PRECONDITION
00111     assert( p != 0 );
00112 
00113     p->value.f32_value  = value;
00114     p->value_type       = XI_VALUE_TYPE_F32;
00115 
00116     return p;
00117 }
00118 
00119 xi_datapoint_t* xi_set_value_str( xi_datapoint_t* p, const char* value )
00120 {
00121     // PRECONDITION
00122     assert( p != 0 );
00123 
00124     int s = xi_str_copy_untiln( p->value.str_value
00125         , XI_VALUE_STRING_MAX_SIZE, value, '\0' );
00126 
00127     XI_CHECK_SIZE( s, XI_VALUE_STRING_MAX_SIZE, XI_DATAPOINT_VALUE_BUFFER_OVERFLOW );
00128 
00129     p->value_type = XI_VALUE_TYPE_STR;
00130 
00131     return p;
00132 
00133 err_handling:
00134     return 0;
00135 }
00136 
00137 void xi_set_network_timeout( uint32_t timeout )
00138 {
00139     xi_globals.network_timeout = timeout;
00140 }
00141 
00142 uint32_t xi_get_network_timeout( void )
00143 {
00144     return xi_globals.network_timeout;
00145 }
00146 
00147 //-----------------------------------------------------------------------
00148 // MAIN LIBRARY FUNCTIONS
00149 //-----------------------------------------------------------------------
00150 
00151 xi_context_t* xi_create_context(
00152       xi_protocol_t protocol, const char* api_key
00153     , int32_t feed_id )
00154 {
00155     // allocate the structure to store new context
00156     xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) );
00157 
00158     XI_CHECK_MEMORY( ret );
00159 
00160     // copy given numeric parameters as is
00161     ret->protocol       = protocol;
00162     ret->feed_id        = feed_id;
00163 
00164     // copy string parameters carefully
00165     if( api_key )
00166     {
00167         // duplicate the string
00168         ret->api_key  = xi_str_dup ( api_key );
00169 
00170         XI_CHECK_MEMORY( ret->api_key );
00171     }
00172     else
00173     {
00174         ret->api_key  = 0;
00175     }
00176 
00177     return ret;
00178 
00179 err_handling:
00180     if( ret )
00181     {
00182         XI_SAFE_FREE( ret );
00183     }
00184 
00185     return 0;
00186 }
00187 
00188 void xi_delete_context( xi_context_t* context )
00189 {
00190     if( context )
00191     {
00192         XI_SAFE_FREE( context->api_key );
00193     }
00194     XI_SAFE_FREE( context );
00195 }
00196 
00197 const xi_response_t* xi_feed_get(
00198           xi_context_t* xi
00199         , xi_feed_t* feed )
00200 {
00201     XI_FUNCTION_PROLOGUE
00202 
00203     const char* data = transport_layer->encode_get_feed(
00204               data_layer
00205             , xi->api_key
00206             , feed );
00207 
00208     if( data == 0 ) { goto err_handling; }
00209 
00210     XI_FUNCTION_GET_RESPONSE
00211 
00212     feed = data_layer->decode_feed( response->http.http_content, feed );
00213     if( feed == 0 ) { goto err_handling; }
00214 
00215     XI_FUNCTION_EPILOGUE
00216 }
00217 
00218 const xi_response_t* xi_feed_update(
00219           xi_context_t* xi
00220         , const xi_feed_t* feed )
00221 {
00222     XI_FUNCTION_PROLOGUE
00223 
00224     const char* data = transport_layer->encode_update_feed(
00225               data_layer
00226             , xi->api_key
00227             , feed );
00228 
00229     if( data == 0 ) { goto err_handling; }
00230 
00231     XI_FUNCTION_GET_RESPONSE
00232 
00233     XI_FUNCTION_EPILOGUE
00234 }
00235 
00236 const xi_response_t* xi_datastream_get(
00237             xi_context_t* xi, int32_t feed_id
00238           , const char * datastream_id, xi_datapoint_t* o )
00239 {
00240     XI_FUNCTION_PROLOGUE
00241 
00242     const char* data = transport_layer->encode_get_datastream(
00243               data_layer
00244             , xi->api_key
00245             , feed_id
00246             , datastream_id );
00247 
00248     if( data == 0 ) { goto err_handling; }
00249 
00250     XI_FUNCTION_GET_RESPONSE
00251 
00252     o = data_layer->decode_datapoint(
00253         response->http.http_content, o );
00254 
00255     if( o == 0 ) { goto err_handling; }
00256 
00257     XI_FUNCTION_EPILOGUE
00258 }
00259 
00260 
00261 const xi_response_t* xi_datastream_create(
00262             xi_context_t* xi, int32_t feed_id
00263           , const char * datastream_id
00264           , const xi_datapoint_value_t* value )
00265 {
00266     XI_FUNCTION_PROLOGUE
00267 
00268     const char* data = transport_layer->encode_create_datastream(
00269               data_layer
00270             , xi->api_key
00271             , feed_id
00272             , datastream_id
00273             , value );
00274 
00275     if( data == 0 ) { goto err_handling; }
00276 
00277     XI_FUNCTION_GET_RESPONSE
00278     XI_FUNCTION_EPILOGUE
00279 }
00280 
00281 const xi_response_t* xi_datastream_update(
00282           xi_context_t* xi, int32_t feed_id
00283         , const char * datastream_id
00284         , const xi_datapoint_value_t* value )
00285 {
00286     XI_FUNCTION_PROLOGUE
00287 
00288     const char* data = transport_layer->encode_update_datastream(
00289               data_layer
00290             , xi->api_key
00291             , feed_id
00292             , datastream_id
00293             , value );
00294 
00295 
00296     if( data == 0 ) { goto err_handling; }
00297 
00298     XI_FUNCTION_GET_RESPONSE
00299 
00300 
00301     XI_FUNCTION_EPILOGUE
00302 }
00303 const xi_response_t* xi_datastream_delete(
00304             xi_context_t* xi, int32_t feed_id
00305           , const char * datastream_id )
00306 {
00307     XI_FUNCTION_PROLOGUE
00308 
00309     const char* data = transport_layer->encode_delete_datastream(
00310               data_layer
00311             , xi->api_key
00312             , feed_id
00313             , datastream_id );
00314 
00315     if( data == 0 ) { goto err_handling; }
00316 
00317     XI_FUNCTION_GET_RESPONSE
00318 
00319     XI_FUNCTION_EPILOGUE
00320 }
00321 
00322 const xi_response_t* xi_datapoint_delete(
00323           const xi_context_t* xi, int feed_id
00324         , const char * datastream_id
00325         , const xi_datapoint_t* o )
00326 {
00327     XI_FUNCTION_PROLOGUE
00328 
00329     const char* data = transport_layer->encode_delete_datapoint(
00330               data_layer
00331             , xi->api_key
00332             , feed_id
00333             , datastream_id
00334             , o );
00335 
00336     if( data == 0 ) { goto err_handling; }
00337 
00338     XI_FUNCTION_GET_RESPONSE
00339     XI_FUNCTION_EPILOGUE
00340 }
00341 
00342 extern const xi_response_t* xi_datapoint_delete_range(
00343             const xi_context_t* xi, int feed_id
00344           , char * datastream_id
00345           , const xi_timestamp_t* start
00346           , const xi_timestamp_t* end )
00347 {
00348     XI_FUNCTION_PROLOGUE
00349 
00350     const char* data = transport_layer->encode_datapoint_delete_range(
00351               data_layer
00352             , xi->api_key
00353             , feed_id
00354             , datastream_id
00355             , start
00356             , end );
00357 
00358     if( data == 0 ) { goto err_handling; }
00359 
00360     XI_FUNCTION_GET_RESPONSE
00361     XI_FUNCTION_EPILOGUE
00362 }
00363 
00364 
00365 #ifdef __cplusplus
00366 }
00367 #endif