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