Arman Habibi / mbed-libxively-6eca970

Fork of mbed-libxively-6eca970 by Xively Official

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( xi_context_t* xi, const xi_feed_t* feed )
00219 {
00220     XI_FUNCTION_PROLOGUE
00221 
00222     const char* data = transport_layer->encode_update_feed(
00223               data_layer
00224             , xi->api_key
00225             , feed );
00226 
00227     if( data == 0 ) { goto err_handling; }
00228 
00229     XI_FUNCTION_GET_RESPONSE
00230 
00231     XI_FUNCTION_EPILOGUE
00232 }
00233 
00234 const xi_response_t* xi_datastream_get(
00235             xi_context_t* xi, int32_t feed_id
00236           , const char * datastream_id, xi_datapoint_t* o )
00237 {
00238     XI_FUNCTION_PROLOGUE
00239 
00240     const char* data = transport_layer->encode_get_datastream(
00241               data_layer
00242             , xi->api_key
00243             , feed_id
00244             , datastream_id );
00245 
00246     if( data == 0 ) { goto err_handling; }
00247 
00248     XI_FUNCTION_GET_RESPONSE
00249 
00250     o = data_layer->decode_datapoint(
00251         response->http.http_content, o );
00252 
00253     if( o == 0 ) { goto err_handling; }
00254 
00255     XI_FUNCTION_EPILOGUE
00256 }
00257 
00258 
00259 const xi_response_t* xi_datastream_create(
00260             xi_context_t* xi, int32_t feed_id
00261           , const char * datastream_id
00262           , const xi_datapoint_t* datapoint )
00263 {
00264     XI_FUNCTION_PROLOGUE
00265 
00266     const char* data = transport_layer->encode_create_datastream(
00267               data_layer
00268             , xi->api_key
00269             , feed_id
00270             , datastream_id
00271             , datapoint );
00272 
00273     if( data == 0 ) { goto err_handling; }
00274 
00275     XI_FUNCTION_GET_RESPONSE
00276     XI_FUNCTION_EPILOGUE
00277 }
00278 
00279 const xi_response_t* xi_datastream_update(
00280           xi_context_t* xi, int32_t feed_id
00281         , const char * datastream_id
00282         , const xi_datapoint_t* datapoint )
00283 {
00284     XI_FUNCTION_PROLOGUE
00285 
00286     const char* data = transport_layer->encode_update_datastream(
00287               data_layer
00288             , xi->api_key
00289             , feed_id
00290             , datastream_id
00291             , datapoint );
00292 
00293 
00294     if( data == 0 ) { goto err_handling; }
00295 
00296     XI_FUNCTION_GET_RESPONSE
00297 
00298 
00299     XI_FUNCTION_EPILOGUE
00300 }
00301 const xi_response_t* xi_datastream_delete(
00302             xi_context_t* xi, int32_t feed_id
00303           , const char * datastream_id )
00304 {
00305     XI_FUNCTION_PROLOGUE
00306 
00307     const char* data = transport_layer->encode_delete_datastream(
00308               data_layer
00309             , xi->api_key
00310             , feed_id
00311             , datastream_id );
00312 
00313     if( data == 0 ) { goto err_handling; }
00314 
00315     XI_FUNCTION_GET_RESPONSE
00316 
00317     XI_FUNCTION_EPILOGUE
00318 }
00319 
00320 const xi_response_t* xi_datapoint_delete(
00321           const xi_context_t* xi, int feed_id
00322         , const char * datastream_id
00323         , const xi_datapoint_t* o )
00324 {
00325     XI_FUNCTION_PROLOGUE
00326 
00327     const char* data = transport_layer->encode_delete_datapoint(
00328               data_layer
00329             , xi->api_key
00330             , feed_id
00331             , datastream_id
00332             , o );
00333 
00334     if( data == 0 ) { goto err_handling; }
00335 
00336     XI_FUNCTION_GET_RESPONSE
00337     XI_FUNCTION_EPILOGUE
00338 }
00339 
00340 extern const xi_response_t* xi_datapoint_delete_range(
00341             const xi_context_t* xi, int feed_id
00342           , const char * datastream_id
00343           , const xi_timestamp_t* start
00344           , const xi_timestamp_t* end )
00345 {
00346     XI_FUNCTION_PROLOGUE
00347 
00348     const char* data = transport_layer->encode_datapoint_delete_range(
00349               data_layer
00350             , xi->api_key
00351             , feed_id
00352             , datastream_id
00353             , start
00354             , end );
00355 
00356     if( data == 0 ) { goto err_handling; }
00357 
00358     XI_FUNCTION_GET_RESPONSE
00359     XI_FUNCTION_EPILOGUE
00360 }
00361 
00362 
00363 #ifdef __cplusplus
00364 }
00365 #endif