layer_state_t contiki_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( "[contiki_io_layer_init]" ); layer_t* layer = ( layer_t* ) context->self; contiki_data_t* s = &contiki_state; s->state = CLOSED; s->process = NULL; layer->user_data = ( void* ) s; xi_debug_logger( "Creating psocket..." ); xi_debug_logger( "Psocket creation [ok]" ); // POSTCONDITIONS assert( layer->user_data != 0 ); return LAYER_STATE_OK; }
layer_state_t dummy_io_layer_connect( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { XI_UNUSED( context ); XI_UNUSED( data ); XI_UNUSED( hint ); return LAYER_STATE_OK; }
int main( int argc, const char* argv[] ) { #ifdef XI_NOB_ENABLED XI_UNUSED( argc ); XI_UNUSED( argv ); #else if( argc < REQUIRED_ARGS ) { print_usage(); exit( 0 ); } // create the xi library context xi_context_t* xi_context = xi_create_context( XI_HTTP, argv[ 1 ] , atoi( argv[ 2 ] ) ); // check if everything works if( xi_context == 0 ) { return -1; } // create feed xi_feed_t f; memset( &f, 0, sizeof( xi_feed_t ) ); xi_feed_get_all( xi_context, &f ); printf( "\n" ); for( size_t i = 0; i < f.datastream_count; ++i ) { xi_datastream_t* d = &f.datastreams[ i ]; printf( "datasream_id: %s ", d->datastream_id ); for( size_t j = 0; j < d->datapoint_count; ++j ) { xi_datapoint_t* p = &d->datapoints[ j ]; print_datapoint( p ); } } // destroy the context cause we don't need it anymore xi_delete_context( xi_context ); #endif return 0; }
const xi_response_t* xi_datastream_get( xi_context_t* xi, xi_feed_id_t feed_id , const char * datastream_id, xi_datapoint_t* o ) { XI_UNUSED( feed_id ); layer_t* io_layer = connect_to_endpoint( xi->layer_chain.bottom, XI_HOST, XI_PORT ); if( io_layer == 0 ) { // we are in trouble return 0; } // extract the input layer layer_t* input_layer = xi->layer_chain.top; // clean the response before writing to it memset( ( ( csv_layer_data_t* ) input_layer->user_data )->response, 0, sizeof( xi_response_t ) ); // create the input parameter http_layer_input_t http_layer_input = { HTTP_LAYER_INPUT_DATASTREAM_GET , xi , 0 , { ( struct xi_get_datastream_t ) { datastream_id, o } } };
layer_state_t posix_asynch_io_layer_data_ready( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { posix_asynch_data_t* posix_asynch_data = ( posix_asynch_data_t* ) context->self->user_data; const const_data_descriptor_t* buffer = ( const const_data_descriptor_t* ) data; XI_UNUSED( hint ); if( buffer != 0 && buffer->data_size > 0 ) { int len = write( posix_asynch_data->socket_fd, buffer->data_ptr, buffer->data_size ); if( len < 0 ) { int errval = errno; if( errval == EAGAIN ) // that can happen { return LAYER_STATE_WANT_WRITE; } xi_debug_printf( "error reading: errno = %d \n", errval ); return LAYER_STATE_ERROR; } if( len < buffer->data_size ) { return LAYER_STATE_ERROR; } } return hint == LAYER_HINT_MORE_DATA ? LAYER_STATE_WANT_WRITE : LAYER_STATE_OK; }
layer_state_t contiki_io_layer_data_ready( layer_connectivity_t* context , const void* data , const layer_hint_t hint) { contiki_data_t* s = (contiki_data_t*) context->self->user_data; const const_data_descriptor_t* buffer = ( const const_data_descriptor_t* ) data; XI_UNUSED(hint); s->process = PROCESS_CURRENT(); if (s->state == WRITTING) { return LAYER_STATE_WANT_WRITE; } else if (s->state == WRITE_END) { s->state = CONNECTED; return LAYER_STATE_OK; } else if (s->state == ERROR) { return LAYER_STATE_ERROR; } else if (s->state == CONNECTED) { if (buffer != NULL && buffer->data_size > 0) { s->out_buf = (uint8_t *)buffer->data_ptr; s->out_len = buffer->data_size; //s->out_buf[s->out_len] = 0; //xprintf("%s\n", s->out_buf); s->state = WRITTING; handle_output(s); return LAYER_STATE_WANT_WRITE; } return LAYER_STATE_OK; } return LAYER_STATE_ERROR; }
const xi_response_t* xi_datastream_get( xi_context_t* xi, xi_feed_id_t feed_id , const char * datastream_id, xi_datapoint_t* o ) { XI_UNUSED( feed_id ); // we shall need it later layer_state_t state = LAYER_STATE_OK; // extract the input layer layer_t* input_layer = xi->layer_chain.top; layer_t* io_layer = xi->layer_chain.bottom; { // init & connect state = CALL_ON_SELF_INIT( io_layer, 0, LAYER_HINT_NONE ); if( state != LAYER_STATE_OK ) { return 0; } xi_connection_data_t conn_data = { XI_HOST, XI_PORT }; state = CALL_ON_SELF_CONNECT( io_layer, ( void *) &conn_data, LAYER_HINT_NONE ); if( state != LAYER_STATE_OK ) { return 0; } } // clean the response before writing to it memset( ( ( csv_layer_data_t* ) input_layer->user_data )->response, 0, sizeof( xi_response_t ) ); // create the input parameter http_layer_input_t http_layer_input = { HTTP_LAYER_INPUT_DATASTREAM_GET , xi , 0 , { ( struct xi_get_datastream_t ) { datastream_id, o } } };
layer_state_t contiki_io_layer_close( layer_connectivity_t* context ) { contiki_data_t* s = ( contiki_data_t* ) context->self->user_data; XI_UNUSED(s); return CALL_ON_SELF_ON_CLOSE(context->self); }
layer_state_t posix_asynch_io_layer_close( layer_connectivity_t* context ) { posix_asynch_data_t* posix_asynch_data = ( posix_asynch_data_t* ) context->self->user_data; XI_UNUSED( posix_asynch_data ); return LAYER_STATE_OK; }
layer_state_t contiki_io_layer_connect( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { XI_UNUSED( hint ); uip_ipaddr_t *ip; resolv_status_t dns_status; xi_connection_data_t* connection_data; layer_t* layer = ( layer_t* ) context->self; contiki_data_t* s = (contiki_data_t* ) layer->user_data; struct uip_conn *c; s->process = PROCESS_CURRENT(); if (s->state == CONNECTED) { xi_debug_logger( "Connecting to the endpoint [ok]" ); return LAYER_STATE_OK; } else if (s->state == CONNECTING) { return LAYER_STATE_WANT_WRITE; } else if (s->state == CLOSED) { connection_data = ( xi_connection_data_t* ) data; dns_status = resolv_lookup(connection_data->address, &ip); if (dns_status != RESOLV_STATUS_CACHED) { if (dns_status == RESOLV_STATUS_NOT_FOUND || dns_status == RESOLV_STATUS_ERROR) { xi_debug_logger( "Getting Host by name [failed]" ); xi_set_err( XI_SOCKET_GETHOSTBYNAME_ERROR ); return LAYER_STATE_ERROR; } if (dns_status != RESOLV_STATUS_RESOLVING) { resolv_query(connection_data->address); } return LAYER_STATE_WANT_WRITE; /* no IP, cannot go further */ } xi_debug_logger( "Getting Host by name [ok]" ); xi_debug_logger( "Connecting to the endpoint..." ); c = uip_connect(ip, uip_htons(connection_data->port)); if(c == NULL) { xi_debug_logger( "Connecting to the endpoint [failed]" ); xi_set_err( XI_SOCKET_CONNECTION_ERROR ); return LAYER_STATE_ERROR; } s->state = CONNECTING; c->appstate.p = &xively_process; c->appstate.state = s; tcpip_poll_tcp(c); return LAYER_STATE_WANT_WRITE; } return LAYER_STATE_ERROR; }
layer_state_t posix_asynch_io_layer_on_data_ready( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { //xi_debug_logger( "[posix_asynch_io_layer_on_data_ready]" ); posix_asynch_data_t* posix_asynch_data = ( posix_asynch_data_t* ) context->self->user_data; XI_UNUSED( hint ); data_descriptor_t* buffer = 0; if( data ) { buffer = ( data_descriptor_t* ) data; } else { static char data_buffer[ 32 ]; memset( data_buffer, 0, sizeof( data_buffer ) ); static data_descriptor_t buffer_descriptor = { data_buffer, sizeof( data_buffer ), 0, 0 }; buffer = &buffer_descriptor; } layer_state_t state = LAYER_STATE_OK; memset( buffer->data_ptr, 0, buffer->data_size ); int len = read( posix_asynch_data->socket_fd, buffer->data_ptr, buffer->data_size - 1 ); if( len < 0 ) { int errval = errno; if( errval == EAGAIN ) // that can happen { return LAYER_STATE_WANT_READ; } xi_debug_printf( "error reading: errno = %d \n", errval ); return LAYER_STATE_ERROR; } buffer->real_size = len; buffer->data_ptr[ buffer->real_size ] = '\0'; // put guard buffer->curr_pos = 0; state = CALL_ON_NEXT_ON_DATA_READY( context->self, ( void* ) buffer, LAYER_HINT_MORE_DATA ); return state; }
int main( int argc, const char* argv[] ) { #ifdef XI_NOB_ENABLED XI_UNUSED( argc ); XI_UNUSED( argv ); #else if( argc < 4 ) { print_usage(); exit( 0 ); } // create the xi library context xi_context_t* xi_context = xi_create_context( XI_HTTP, argv[ 1 ] , atoi( argv[ 2 ] ) ); // check if everything works if( xi_context == 0 ) { return -1; } xi_datapoint_t ret; xi_datastream_get( xi_context , atoi( argv[ 2 ] ), argv[ 3 ], &ret ); printf( "timestamp = %ld.%ld, value = %d\n" , ret.timestamp.timestamp, ret.timestamp.micro , ret.value.i32_value ); // destroy the context cause we don't need it anymore xi_delete_context( xi_context ); #endif return 0; }
layer_state_t contiki_io_layer_on_data_ready( layer_connectivity_t* context , const void* data , const layer_hint_t hint) { contiki_data_t* s = (contiki_data_t*) context->self->user_data; data_descriptor_t* buffer = 0; layer_state_t state; XI_UNUSED(hint); s->process = PROCESS_CURRENT(); if (data) { buffer = ( data_descriptor_t* ) data; } else { buffer = &s->buffer_descriptor; } if (s->state == READ_END) { buffer->data_ptr = (char *)uip_appdata; buffer->real_size = uip_datalen(); buffer->data_size = uip_datalen() + 1; buffer->data_ptr[buffer->real_size] = '\0'; // put guard buffer->curr_pos = 0; state = CALL_ON_NEXT_ON_DATA_READY( context->self, ( void* ) buffer, LAYER_HINT_MORE_DATA ); if (state == LAYER_STATE_WANT_READ) { s->state = READING; return LAYER_STATE_WANT_READ; } s->state = CONNECTED; return LAYER_STATE_OK; } else if (s->state == READING) { return LAYER_STATE_WANT_READ; } else if (s->state == CONNECTED) { s->state = READING; return LAYER_STATE_WANT_READ; } return LAYER_STATE_ERROR; /* error, come here */ }
layer_state_t dummy_io_layer_on_close( layer_connectivity_t* context ) { XI_UNUSED( context ); return LAYER_STATE_OK; }
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; }
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() }
int main( int argc, const char* argv[] ) { #ifdef XI_NOB_ENABLED XI_UNUSED( argc ); XI_UNUSED( argv ); #else if( argc < REQUIRED_ARGS ) { print_usage(); exit( 0 ); } // create the xi library context xi_context_t* xi_context = xi_create_context( XI_HTTP, argv[ 1 ] , atoi( argv[ 2 ] ) ); // check if everything works if( xi_context == 0 ) { return -1; } // remember the count for pairs size_t pairs_count = ( argc - REQUIRED_ARGS ) / 2; // create feed xi_feed_t f; memset( &f, 0, sizeof( xi_feed_t ) ); // set datastream count f.feed_id = atoi( argv[ 2 ] ); f.datastream_count = pairs_count; // for each pair for( size_t i = 0; i < pairs_count; i++ ) { // get the datastream pointer xi_datastream_t* d = &f.datastreams[ i ]; // set the datapoint count d->datapoint_count = 1; int size = sizeof( d->datastream_id ); int s = xi_str_copy_untiln( d->datastream_id, size , argv[ REQUIRED_ARGS + ( i * 2 ) ], '\0' ); if( s >= size ) { printf( "datastream id too long: %s\n", argv[ REQUIRED_ARGS + ( i * 2 ) ] ); } // get the datpoint counter xi_datapoint_t* p = &d->datapoints[ 0 ]; // set the datapoint xi_set_value_i32( p, atoi( argv[ REQUIRED_ARGS + ( i * 2 ) + 1 ] ) ); } for( int i = 0; i < 20; ++i ) { xi_feed_update( xi_context, &f ); } // destroy the context cause we don't need it anymore xi_delete_context( xi_context ); #endif return 0; }