test
Fork of mbed-libxively-6eca970 by
src/libxively/comm_layers/mbed/mbed_comm.cpp
- Committer:
- xively
- Date:
- 2013-06-26
- Revision:
- 0:82702e998d3f
File content as of revision 0:82702e998d3f:
// 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; } }