void xi_delete_context( xi_context_t* context )
{
    if( context )
    {
        XI_SAFE_FREE( context->api_key );
    }
    XI_SAFE_FREE( context );
}
layer_state_t posix_asynch_io_layer_on_close( layer_connectivity_t* context )
{
    // prepare return value
    layer_state_t ret = LAYER_STATE_OK;

    //
    posix_asynch_data_t* posix_asynch_data = ( posix_asynch_data_t* ) context->self->user_data;

    if( shutdown( posix_asynch_data->socket_fd, SHUT_RDWR ) == -1 )
    {
        xi_set_err( XI_SOCKET_SHUTDOWN_ERROR );
        close( posix_asynch_data->socket_fd ); // just in case
        ret = LAYER_STATE_ERROR;
        goto err_handling;
    }

    // close the connection & the socket
    if( close( posix_asynch_data->socket_fd ) == -1 )
    {
        xi_set_err( XI_SOCKET_CLOSE_ERROR );
        ret = LAYER_STATE_ERROR;
        goto err_handling;
    }

err_handling:
    // cleanup the memory
    if( posix_asynch_data ) { XI_SAFE_FREE( posix_asynch_data ); }

    return ret;
}
Esempio n. 3
0
void xi_delete_context( xi_context_t* context )
{
    assert( context != 0 && "context must not be null!" );

    switch( context->protocol )
    {
        case XI_HTTP:
            destroy_and_disconnect_layers( &( context->layer_chain ), CONNECTION_SCHEME_LENGTH( CONNECTION_SCHEME_1 ) );
            break;
        default:
            assert( 0 && "not yet implemented!" );
            break;
    }

    XI_SAFE_FREE( context->api_key );
    XI_SAFE_FREE( context );
}
xi_context_t* xi_create_context(
      xi_protocol_t protocol, const char* api_key
    , int32_t feed_id )
{
    // allocate the structure to store new context
    xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) );

    XI_CHECK_MEMORY( ret );

    // copy given numeric parameters as is
    ret->protocol       = protocol;
    ret->feed_id        = feed_id;

    // copy string parameters carefully
    if( api_key )
    {
        // duplicate the string
        ret->api_key  = xi_str_dup( api_key );

        XI_CHECK_MEMORY( ret->api_key );
    }
    else
    {
        ret->api_key  = 0;
    }

    return ret;

err_handling:
    if( ret )
    {
        XI_SAFE_FREE( ret );
    }

    return 0;
}
Esempio n. 5
0
xi_context_t* xi_create_context(
      xi_protocol_t protocol, const char* api_key
    , xi_feed_id_t feed_id )
{
    // allocate the structure to store new context
    xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) );

    XI_CHECK_MEMORY( ret );

    // copy given numeric parameters as is
    ret->protocol       = protocol;
    ret->feed_id        = feed_id;

    // copy string parameters carefully
    if( api_key )
    {
        // duplicate the string
        ret->api_key  = xi_str_dup( api_key );

        XI_CHECK_MEMORY( ret->api_key );
    }
    else
    {
        ret->api_key  = 0;
    }

    switch( protocol )
    {
        case XI_HTTP:
            {
                // @TODO make a configurable pool of these
                // static structures allocated statically
                static http_layer_data_t    http_layer_data;
                static csv_layer_data_t     csv_layer_data;
                static xi_response_t        xi_response;


                // clean the structures
                memset( &http_layer_data, 0, sizeof( http_layer_data_t ) );
                memset( &csv_layer_data, 0, sizeof( csv_layer_data_t ) );
                memset( &xi_response, 0, sizeof( xi_response_t ) );

                // the response pointer
                http_layer_data.response    = &xi_response;
                csv_layer_data.response     = &xi_response;

                // prepare user data description
                void* user_datas[] = { 0, ( void* ) &http_layer_data, ( void* ) &csv_layer_data };

                // create and connect layers store the information in layer_chain member
                ret->layer_chain = create_and_connect_layers( CONNECTION_SCHEME_1, user_datas, CONNECTION_SCHEME_LENGTH( CONNECTION_SCHEME_1 ) );
            }
            break;
        default:
            goto err_handling;
    }


    return ret;

err_handling:
    if( ret )
    {
        if( ret->api_key )
        {
            XI_SAFE_FREE( ret->api_key );
        }

        XI_SAFE_FREE( ret );
    }

    return 0;
}
layer_state_t posix_asynch_io_layer_connect(
      layer_connectivity_t* context
    , const void* data
    , const layer_hint_t hint )
{
    XI_UNUSED( hint );

    static uint16_t cs = 0; // local coroutine prereserved state

    xi_connection_data_t* connection_data   = ( xi_connection_data_t* ) data;
    layer_t* layer                          = ( layer_t* ) context->self;
    posix_asynch_data_t* posix_asynch_data  = ( posix_asynch_data_t* ) layer->user_data;

    BEGIN_CORO( cs )

    xi_debug_format( "Connecting layer [%d] to the endpoint", layer->layer_type_id );

    // socket specific data
    struct sockaddr_in name;
    struct hostent* hostinfo;

    // get the hostaddress
    hostinfo = gethostbyname( connection_data->address );

    // if null it means that the address has not been founded
    if( hostinfo == NULL )
    {
        xi_debug_logger( "Getting Host by name [failed]" );
        xi_set_err( XI_SOCKET_GETHOSTBYNAME_ERROR );
        goto err_handling;
    }

    xi_debug_logger( "Getting Host by name [ok]" );

    // set the address and the port for further connection attempt
    memset( &name, 0, sizeof( struct sockaddr_in ) );
    name.sin_family     = AF_INET;
    name.sin_addr       = *( ( struct in_addr* ) hostinfo->h_addr );
    name.sin_port       = htons( connection_data->port );

    xi_debug_logger( "Connecting to the endpoint..." );

    if( connect( posix_asynch_data->socket_fd, ( struct sockaddr* ) &name, sizeof( struct sockaddr ) ) == -1 )
    {
        if( errno != EINPROGRESS )
        {
            xi_debug_printf( "errno: %d", errno );
            xi_debug_logger( "Connecting to the endpoint [failed]" );
            xi_set_err( XI_SOCKET_CONNECTION_ERROR );
            goto err_handling;
        }
        else
        {
            YIELD( cs, LAYER_STATE_WANT_WRITE ); // return here whenever we can write
        }
    }

    EXIT( cs, LAYER_STATE_OK );

err_handling:
    // cleanup the memory
    if( posix_asynch_data )     { close( posix_asynch_data->socket_fd ); }
    if( layer->user_data )      { XI_SAFE_FREE( layer->user_data ); }

    EXIT( cs, LAYER_STATE_ERROR );

    END_CORO()
}
layer_state_t posix_asynch_io_layer_init(
      layer_connectivity_t* context
    , const void* data
    , const layer_hint_t hint )
{
    XI_UNUSED( hint );
    XI_UNUSED( data );

    // PRECONDITIONS
    assert( context != 0 );

    xi_debug_logger( "[posix_io_layer_init]" );

    layer_t* layer                              = ( layer_t* ) context->self;
    posix_asynch_data_t* posix_asynch_data      = xi_alloc( sizeof( posix_asynch_data_t ) );

    XI_CHECK_MEMORY( posix_asynch_data );

    layer->user_data                            = ( void* ) posix_asynch_data;

    xi_debug_logger( "Creating socket..." );

    posix_asynch_data->socket_fd                = socket( AF_INET, SOCK_STREAM, 0 );

    if( posix_asynch_data->socket_fd == -1 )
    {
        xi_debug_logger( "Socket creation [failed]" );
        xi_set_err( XI_SOCKET_INITIALIZATION_ERROR );
        return 0;
    }

    xi_debug_logger( "Setting socket non blocking behaviour..." );

    int flags = fcntl( posix_asynch_data->socket_fd, F_GETFL, 0 );

    if( flags == -1 )
    {
        xi_debug_logger( "Socket non blocking behaviour [failed]" );
        xi_set_err( XI_SOCKET_INITIALIZATION_ERROR );
        goto err_handling;
    }

    if( fcntl( posix_asynch_data->socket_fd, F_SETFL, flags | O_NONBLOCK ) == -1 )
    {
        xi_debug_logger( "Socket non blocking behaviour [failed]" );
        xi_set_err( XI_SOCKET_INITIALIZATION_ERROR );
        goto err_handling;
    }

    xi_debug_logger( "Socket creation [ok]" );

    // POSTCONDITIONS
    assert( layer->user_data != 0 );
    assert( posix_asynch_data->socket_fd != -1 );

    return LAYER_STATE_OK;

err_handling:
    // cleanup the memory
    if( posix_asynch_data )     { close( posix_asynch_data->socket_fd ); }
    if( layer->user_data )      { XI_SAFE_FREE( layer->user_data ); }

    return LAYER_STATE_ERROR;
}