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.

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?

UserRevisionLine numberNew 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 }