test
Fork of mbed-libxively-6eca970 by
src/libxively/comm_layers/mbed/mbed_comm.cpp@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 mbed_comm.cpp |
xively | 0:82702e998d3f | 6 | * \author Olgierd Humenczuk |
xively | 0:82702e998d3f | 7 | * \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] |
xively | 0:82702e998d3f | 8 | */ |
xively | 0:82702e998d3f | 9 | |
xively | 0:82702e998d3f | 10 | #include <stdio.h> |
xively | 0:82702e998d3f | 11 | #include <string.h> |
xively | 0:82702e998d3f | 12 | #include <stdint.h> |
xively | 0:82702e998d3f | 13 | #include <assert.h> |
xively | 0:82702e998d3f | 14 | |
xively | 0:82702e998d3f | 15 | #include "mbed_comm.h" |
xively | 0:82702e998d3f | 16 | #include "comm_layer.h" |
xively | 0:82702e998d3f | 17 | #include "xi_helpers.h" |
xively | 0:82702e998d3f | 18 | #include "xi_allocator.h" |
xively | 0:82702e998d3f | 19 | #include "mbed_comm_layer_data_specific.h" |
xively | 0:82702e998d3f | 20 | #include "xi_err.h" |
xively | 0:82702e998d3f | 21 | #include "xi_macros.h" |
xively | 0:82702e998d3f | 22 | #include "xi_printf.h" |
xively | 0:82702e998d3f | 23 | #include "xi_globals.h" |
xively | 0:82702e998d3f | 24 | |
xively | 0:82702e998d3f | 25 | extern "C" { |
xively | 0:82702e998d3f | 26 | |
xively | 0:82702e998d3f | 27 | connection_t* mbed_open_connection( const char* address, int32_t port ) |
xively | 0:82702e998d3f | 28 | { |
xively | 0:82702e998d3f | 29 | // PRECONDITIONS |
xively | 0:82702e998d3f | 30 | assert( address != 0 ); |
xively | 0:82702e998d3f | 31 | |
xively | 0:82702e998d3f | 32 | // variables |
xively | 0:82702e998d3f | 33 | mbed_comm_layer_data_specific_t* pos_comm_data = 0; |
xively | 0:82702e998d3f | 34 | connection_t* conn = 0; |
xively | 0:82702e998d3f | 35 | |
xively | 0:82702e998d3f | 36 | // allocation of the socket connector |
xively | 0:82702e998d3f | 37 | TCPSocketConnection* socket_ptr = new TCPSocketConnection(); |
xively | 0:82702e998d3f | 38 | XI_CHECK_MEMORY( socket_ptr ); |
xively | 0:82702e998d3f | 39 | |
xively | 0:82702e998d3f | 40 | // set the timeout for blocking operations |
xively | 0:82702e998d3f | 41 | socket_ptr->set_blocking( true, xi_globals.network_timeout ); |
xively | 0:82702e998d3f | 42 | |
xively | 0:82702e998d3f | 43 | // allocate memory for the mbed data specific structure |
xively | 0:82702e998d3f | 44 | pos_comm_data = ( mbed_comm_layer_data_specific_t* ) |
xively | 0:82702e998d3f | 45 | xi_alloc( sizeof( mbed_comm_layer_data_specific_t ) ); |
xively | 0:82702e998d3f | 46 | XI_CHECK_MEMORY( pos_comm_data ); |
xively | 0:82702e998d3f | 47 | |
xively | 0:82702e998d3f | 48 | // allocate memory for the connection layer |
xively | 0:82702e998d3f | 49 | conn = ( connection_t* ) xi_alloc( |
xively | 0:82702e998d3f | 50 | sizeof( connection_t ) ); |
xively | 0:82702e998d3f | 51 | XI_CHECK_MEMORY( conn ); |
xively | 0:82702e998d3f | 52 | |
xively | 0:82702e998d3f | 53 | // clean the memory before the usage |
xively | 0:82702e998d3f | 54 | memset( conn, 0, sizeof( connection_t ) ); |
xively | 0:82702e998d3f | 55 | |
xively | 0:82702e998d3f | 56 | // make copy of an address |
xively | 0:82702e998d3f | 57 | conn->address = xi_str_dup( address ); |
xively | 0:82702e998d3f | 58 | conn->port = port; |
xively | 0:82702e998d3f | 59 | |
xively | 0:82702e998d3f | 60 | XI_CHECK_MEMORY( conn->address ); |
xively | 0:82702e998d3f | 61 | |
xively | 0:82702e998d3f | 62 | { // to prevent the skip initializtion warning |
xively | 0:82702e998d3f | 63 | pos_comm_data->socket_ptr = socket_ptr; |
xively | 0:82702e998d3f | 64 | |
xively | 0:82702e998d3f | 65 | // assign the layer specific data |
xively | 0:82702e998d3f | 66 | conn->layer_specific = pos_comm_data; |
xively | 0:82702e998d3f | 67 | |
xively | 0:82702e998d3f | 68 | // try to connect |
xively | 0:82702e998d3f | 69 | int s = pos_comm_data->socket_ptr->connect( address, port ); |
xively | 0:82702e998d3f | 70 | |
xively | 0:82702e998d3f | 71 | // check if not failed |
xively | 0:82702e998d3f | 72 | if( s == -1 ) |
xively | 0:82702e998d3f | 73 | { |
xively | 0:82702e998d3f | 74 | xi_set_err( XI_SOCKET_CONNECTION_ERROR ); |
xively | 0:82702e998d3f | 75 | goto err_handling; |
xively | 0:82702e998d3f | 76 | } |
xively | 0:82702e998d3f | 77 | } |
xively | 0:82702e998d3f | 78 | |
xively | 0:82702e998d3f | 79 | // POSTCONDITIONS |
xively | 0:82702e998d3f | 80 | assert( conn != 0 ); |
xively | 0:82702e998d3f | 81 | assert( pos_comm_data->socket_ptr != 0 ); |
xively | 0:82702e998d3f | 82 | |
xively | 0:82702e998d3f | 83 | return conn; |
xively | 0:82702e998d3f | 84 | |
xively | 0:82702e998d3f | 85 | // cleanup the memory |
xively | 0:82702e998d3f | 86 | err_handling: |
xively | 0:82702e998d3f | 87 | // safely destroy the object |
xively | 0:82702e998d3f | 88 | if ( pos_comm_data && pos_comm_data->socket_ptr ) |
xively | 0:82702e998d3f | 89 | { |
xively | 0:82702e998d3f | 90 | delete pos_comm_data->socket_ptr; |
xively | 0:82702e998d3f | 91 | pos_comm_data->socket_ptr = 0; |
xively | 0:82702e998d3f | 92 | } |
xively | 0:82702e998d3f | 93 | if( pos_comm_data ) { XI_SAFE_FREE( pos_comm_data ); } |
xively | 0:82702e998d3f | 94 | if( conn ) { XI_SAFE_FREE( conn->address ); } |
xively | 0:82702e998d3f | 95 | XI_SAFE_FREE( conn ); |
xively | 0:82702e998d3f | 96 | |
xively | 0:82702e998d3f | 97 | return 0; |
xively | 0:82702e998d3f | 98 | } |
xively | 0:82702e998d3f | 99 | |
xively | 0:82702e998d3f | 100 | int mbed_send_data( connection_t* conn, const char* data, size_t size ) |
xively | 0:82702e998d3f | 101 | { |
xively | 0:82702e998d3f | 102 | // PRECONDITIONS |
xively | 0:82702e998d3f | 103 | assert( conn != 0 ); |
xively | 0:82702e998d3f | 104 | assert( conn->layer_specific != 0 ); |
xively | 0:82702e998d3f | 105 | assert( data != 0 ); |
xively | 0:82702e998d3f | 106 | assert( size != 0 ); |
xively | 0:82702e998d3f | 107 | |
xively | 0:82702e998d3f | 108 | // extract the layer specific data |
xively | 0:82702e998d3f | 109 | mbed_comm_layer_data_specific_t* pos_comm_data |
xively | 0:82702e998d3f | 110 | = ( mbed_comm_layer_data_specific_t* ) conn->layer_specific; |
xively | 0:82702e998d3f | 111 | |
xively | 0:82702e998d3f | 112 | // Why not const char* ??? |
xively | 0:82702e998d3f | 113 | int bytes_written = pos_comm_data->socket_ptr->send_all( ( char* ) data, size ); |
xively | 0:82702e998d3f | 114 | |
xively | 0:82702e998d3f | 115 | if( bytes_written == - 1 ) |
xively | 0:82702e998d3f | 116 | { |
xively | 0:82702e998d3f | 117 | xi_set_err( XI_SOCKET_WRITE_ERROR ); |
xively | 0:82702e998d3f | 118 | } |
xively | 0:82702e998d3f | 119 | |
xively | 0:82702e998d3f | 120 | // store the value |
xively | 0:82702e998d3f | 121 | conn->bytes_sent += bytes_written; |
xively | 0:82702e998d3f | 122 | |
xively | 0:82702e998d3f | 123 | return bytes_written; |
xively | 0:82702e998d3f | 124 | } |
xively | 0:82702e998d3f | 125 | |
xively | 0:82702e998d3f | 126 | int mbed_read_data( connection_t* conn, char* buffer, size_t buffer_size ) |
xively | 0:82702e998d3f | 127 | { |
xively | 0:82702e998d3f | 128 | // PRECONDITIONS |
xively | 0:82702e998d3f | 129 | assert( conn != 0 ); |
xively | 0:82702e998d3f | 130 | assert( conn->layer_specific != 0 ); |
xively | 0:82702e998d3f | 131 | assert( buffer != 0 ); |
xively | 0:82702e998d3f | 132 | assert( buffer_size != 0 ); |
xively | 0:82702e998d3f | 133 | |
xively | 0:82702e998d3f | 134 | // extract the layer specific data |
xively | 0:82702e998d3f | 135 | mbed_comm_layer_data_specific_t* pos_comm_data |
xively | 0:82702e998d3f | 136 | = ( mbed_comm_layer_data_specific_t* ) conn->layer_specific; |
xively | 0:82702e998d3f | 137 | |
xively | 0:82702e998d3f | 138 | memset( buffer, 0, buffer_size ); |
xively | 0:82702e998d3f | 139 | pos_comm_data->socket_ptr->set_blocking(true, 10); |
xively | 0:82702e998d3f | 140 | int bytes_read = pos_comm_data->socket_ptr->receive( buffer, buffer_size ); |
xively | 0:82702e998d3f | 141 | |
xively | 0:82702e998d3f | 142 | if( bytes_read == -1 ) |
xively | 0:82702e998d3f | 143 | { |
xively | 0:82702e998d3f | 144 | xi_set_err( XI_SOCKET_READ_ERROR ); |
xively | 0:82702e998d3f | 145 | } |
xively | 0:82702e998d3f | 146 | |
xively | 0:82702e998d3f | 147 | // store the value |
xively | 0:82702e998d3f | 148 | conn->bytes_received += bytes_read; |
xively | 0:82702e998d3f | 149 | |
xively | 0:82702e998d3f | 150 | return bytes_read; |
xively | 0:82702e998d3f | 151 | } |
xively | 0:82702e998d3f | 152 | |
xively | 0:82702e998d3f | 153 | void mbed_close_connection( connection_t* conn ) |
xively | 0:82702e998d3f | 154 | { |
xively | 0:82702e998d3f | 155 | // PRECONDITIONS |
xively | 0:82702e998d3f | 156 | assert( conn != 0 ); |
xively | 0:82702e998d3f | 157 | assert( conn->layer_specific != 0 ); |
xively | 0:82702e998d3f | 158 | |
xively | 0:82702e998d3f | 159 | // extract the layer specific data |
xively | 0:82702e998d3f | 160 | mbed_comm_layer_data_specific_t* pos_comm_data |
xively | 0:82702e998d3f | 161 | = ( mbed_comm_layer_data_specific_t* ) conn->layer_specific; |
xively | 0:82702e998d3f | 162 | |
xively | 0:82702e998d3f | 163 | // close the connection & the socket |
xively | 0:82702e998d3f | 164 | if( pos_comm_data->socket_ptr->close() == -1 ) |
xively | 0:82702e998d3f | 165 | { |
xively | 0:82702e998d3f | 166 | xi_set_err( XI_SOCKET_CLOSE_ERROR ); |
xively | 0:82702e998d3f | 167 | goto err_handling; |
xively | 0:82702e998d3f | 168 | } |
xively | 0:82702e998d3f | 169 | |
xively | 0:82702e998d3f | 170 | // cleanup the memory |
xively | 0:82702e998d3f | 171 | err_handling: |
xively | 0:82702e998d3f | 172 | // safely destroy the object |
xively | 0:82702e998d3f | 173 | if ( pos_comm_data && pos_comm_data->socket_ptr ) |
xively | 0:82702e998d3f | 174 | { |
xively | 0:82702e998d3f | 175 | delete pos_comm_data->socket_ptr; |
xively | 0:82702e998d3f | 176 | pos_comm_data->socket_ptr = 0; |
xively | 0:82702e998d3f | 177 | } |
xively | 0:82702e998d3f | 178 | if( conn ) { XI_SAFE_FREE( conn->address ); } |
xively | 0:82702e998d3f | 179 | if( conn ) { XI_SAFE_FREE( conn->layer_specific ); } |
xively | 0:82702e998d3f | 180 | XI_SAFE_FREE( conn ); |
xively | 0:82702e998d3f | 181 | return; |
xively | 0:82702e998d3f | 182 | } |
xively | 0:82702e998d3f | 183 | |
xively | 0:82702e998d3f | 184 | } |