test
Fork of mbed-libxively-6eca970 by
Diff: src/libxively/comm_layers/mbed/mbed_comm.cpp
- Revision:
- 0:82702e998d3f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libxively/comm_layers/mbed/mbed_comm.cpp Wed Jun 26 10:40:43 2013 +0000 @@ -0,0 +1,184 @@ +// Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved. +// This is part of Xively C library, it is under the BSD 3-Clause license. + +/** + * \file mbed_comm.cpp + * \author Olgierd Humenczuk + * \brief Implements mbed _communication layer_ abstraction interface using [TCPSocketConnection](http://mbed.org/users/mbed_official/code/Socket/docs/tip/classTCPSocketConnection.html) [see comm_layer.h] + */ + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <assert.h> + +#include "mbed_comm.h" +#include "comm_layer.h" +#include "xi_helpers.h" +#include "xi_allocator.h" +#include "mbed_comm_layer_data_specific.h" +#include "xi_err.h" +#include "xi_macros.h" +#include "xi_printf.h" +#include "xi_globals.h" + +extern "C" { + +connection_t* mbed_open_connection( const char* address, int32_t port ) +{ + // PRECONDITIONS + assert( address != 0 ); + + // variables + mbed_comm_layer_data_specific_t* pos_comm_data = 0; + connection_t* conn = 0; + + // allocation of the socket connector + TCPSocketConnection* socket_ptr = new TCPSocketConnection(); + XI_CHECK_MEMORY( socket_ptr ); + + // set the timeout for blocking operations + socket_ptr->set_blocking( true, xi_globals.network_timeout ); + + // allocate memory for the mbed data specific structure + pos_comm_data = ( mbed_comm_layer_data_specific_t* ) + xi_alloc( sizeof( mbed_comm_layer_data_specific_t ) ); + XI_CHECK_MEMORY( pos_comm_data ); + + // allocate memory for the connection layer + conn = ( connection_t* ) xi_alloc( + sizeof( connection_t ) ); + XI_CHECK_MEMORY( conn ); + + // clean the memory before the usage + memset( conn, 0, sizeof( connection_t ) ); + + // make copy of an address + conn->address = xi_str_dup( address ); + conn->port = port; + + XI_CHECK_MEMORY( conn->address ); + + { // to prevent the skip initializtion warning + pos_comm_data->socket_ptr = socket_ptr; + + // assign the layer specific data + conn->layer_specific = pos_comm_data; + + // try to connect + int s = pos_comm_data->socket_ptr->connect( address, port ); + + // check if not failed + if( s == -1 ) + { + xi_set_err( XI_SOCKET_CONNECTION_ERROR ); + goto err_handling; + } + } + + // POSTCONDITIONS + assert( conn != 0 ); + assert( pos_comm_data->socket_ptr != 0 ); + + return conn; + + // cleanup the memory +err_handling: + // safely destroy the object + if ( pos_comm_data && pos_comm_data->socket_ptr ) + { + delete pos_comm_data->socket_ptr; + pos_comm_data->socket_ptr = 0; + } + if( pos_comm_data ) { XI_SAFE_FREE( pos_comm_data ); } + if( conn ) { XI_SAFE_FREE( conn->address ); } + XI_SAFE_FREE( conn ); + + return 0; +} + +int mbed_send_data( connection_t* conn, const char* data, size_t size ) +{ + // PRECONDITIONS + assert( conn != 0 ); + assert( conn->layer_specific != 0 ); + assert( data != 0 ); + assert( size != 0 ); + + // extract the layer specific data + mbed_comm_layer_data_specific_t* pos_comm_data + = ( mbed_comm_layer_data_specific_t* ) conn->layer_specific; + + // Why not const char* ??? + int bytes_written = pos_comm_data->socket_ptr->send_all( ( char* ) data, size ); + + if( bytes_written == - 1 ) + { + xi_set_err( XI_SOCKET_WRITE_ERROR ); + } + + // store the value + conn->bytes_sent += bytes_written; + + return bytes_written; +} + +int mbed_read_data( connection_t* conn, char* buffer, size_t buffer_size ) +{ + // PRECONDITIONS + assert( conn != 0 ); + assert( conn->layer_specific != 0 ); + assert( buffer != 0 ); + assert( buffer_size != 0 ); + + // extract the layer specific data + mbed_comm_layer_data_specific_t* pos_comm_data + = ( mbed_comm_layer_data_specific_t* ) conn->layer_specific; + + memset( buffer, 0, buffer_size ); + pos_comm_data->socket_ptr->set_blocking(true, 10); + int bytes_read = pos_comm_data->socket_ptr->receive( buffer, buffer_size ); + + if( bytes_read == -1 ) + { + xi_set_err( XI_SOCKET_READ_ERROR ); + } + + // store the value + conn->bytes_received += bytes_read; + + return bytes_read; +} + +void mbed_close_connection( connection_t* conn ) +{ + // PRECONDITIONS + assert( conn != 0 ); + assert( conn->layer_specific != 0 ); + + // extract the layer specific data + mbed_comm_layer_data_specific_t* pos_comm_data + = ( mbed_comm_layer_data_specific_t* ) conn->layer_specific; + + // close the connection & the socket + if( pos_comm_data->socket_ptr->close() == -1 ) + { + xi_set_err( XI_SOCKET_CLOSE_ERROR ); + goto err_handling; + } + + // cleanup the memory +err_handling: + // safely destroy the object + if ( pos_comm_data && pos_comm_data->socket_ptr ) + { + delete pos_comm_data->socket_ptr; + pos_comm_data->socket_ptr = 0; + } + if( conn ) { XI_SAFE_FREE( conn->address ); } + if( conn ) { XI_SAFE_FREE( conn->layer_specific ); } + XI_SAFE_FREE( conn ); + return; +} + +}