TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

tsp_data_receiver.c

Go to the documentation of this file.
00001 
00038 #include "tsp_sys_headers.h"
00039 #include <rpc/types.h>
00040 #include <rpc/xdr.h>
00041 
00042 #include "tsp_data_receiver.h"
00043 
00044 #include "tsp_datastruct.h"
00045 
00046 #include "tsp_group.h"
00047 #include "tsp_group_data.h"
00048 
00049 #include "tsp_stream_receiver.h"
00050 
00051 #define TSP_SIZEOF_ENCODED_DOUBLE RNDUP(sizeof(double))
00052 
00053 
00054 
00055 struct TSP_struct_data_receiver_t
00056 {
00057   TSP_stream_receiver_t stream_receiver;
00058     
00059   char* buf;
00060 
00061   TSP_sample_callback_t read_callback;
00062 
00063   void* user_data;
00064 };
00065 
00066 typedef struct TSP_struct_data_receiver_t TSP_struct_data_receiver_t;
00067 
00068 static int TSP_data_receiver_double_decoder(void* out_double,  char* in_buf)
00069 {
00070 #ifndef TSP_NO_XDR_ENCODE
00071 
00072   XDR xhandle;
00073   xdrmem_create(&xhandle, in_buf, TSP_SIZEOF_ENCODED_DOUBLE, XDR_DECODE);
00074   if( xdr_double(&xhandle, (double*)out_double) != TRUE)
00075     {
00076       STRACE_ERROR(("Function xdr_double failed"));
00077       return FALSE;
00078     }
00079   else
00080     {
00081       return TRUE;
00082     }
00083 
00084 #else
00085   
00086   *(uint64_t*)out_double = TSP_DECODE_DOUBLE_TO_UINT64(in_buf);   
00087   
00088   return TRUE;
00089 
00090 #endif
00091 
00092 }
00093 
00094 static void TSP_data_receiver_process_receiver_error(TSP_sample_ringbuf_t* sample_fifo)
00095 {
00096 
00097   int ret = TRUE;
00098   TSP_sample_t* sample;
00099 
00100   STRACE_IO(("-->IN"));
00101   
00102   sample = RINGBUF_PTR_PUTBYADDR(sample_fifo);
00103   assert(sample);
00104   sample->time = -1;
00105   sample->user_value = -1;      
00106   sample->provider_global_index = TSP_DUMMY_PROVIDER_GLOBAL_INDEX_RECEIVER_ERROR;
00107   RINGBUF_PTR_PUTBYADDR_COMMIT(sample_fifo);
00108     
00109   STRACE_IO(("-->OUT"));
00110 
00111 }
00112 
00113 static int TSP_data_receiver_process_reserved_group_id(int group_index, TSP_sample_ringbuf_t* sample_fifo)
00114 {
00115 
00116   int ret = TRUE;
00117   TSP_sample_t* sample;
00118 
00119   STRACE_IO(("-->IN"));
00120   
00121 
00122   sample = RINGBUF_PTR_PUTBYADDR(sample_fifo);
00123   assert(sample);
00124   sample->time = -1;
00125   sample->user_value = -1;      
00126   switch(group_index)
00127     {
00128       /* received EOF */
00129     case TSP_RESERVED_GROUP_EOF: 
00130         sample->provider_global_index = TSP_DUMMY_PROVIDER_GLOBAL_INDEX_EOF;
00131         break;
00132 
00133     case TSP_RESERVED_GROUP_RECONF: 
00134         sample->provider_global_index = TSP_DUMMY_PROVIDER_GLOBAL_INDEX_RECONF;
00135         break;
00136 
00137     case TSP_RESERVED_GROUP_GLU_DATA_LOST: 
00138         sample->provider_global_index = TSP_DUMMY_PROVIDER_GLOBAL_INDEX_GLU_DATA_LOST;
00139         break;
00140 
00141     case TSP_RESERVED_GROUP_CONSUMER_DATA_LOST: 
00142         sample->provider_global_index = TSP_DUMMY_PROVIDER_GLOBAL_INDEX_CONSUMER_DATA_LOST;
00143         break;
00144     
00145     default:     
00146       STRACE_ERROR(("Group id % in not a reserved group", group_index));
00147       ret = FALSE;
00148     }
00149   
00150   if(ret)
00151     {
00152       RINGBUF_PTR_PUTBYADDR_COMMIT(sample_fifo);
00153     }
00154   
00155   STRACE_IO(("-->OUT"));
00156 
00157   return ret;
00158 
00159 }
00160 
00161 TSP_data_receiver_t TSP_data_receiver_create(const char* data_address, TSP_sample_callback_t callback, void* user_data)
00162 {
00163     
00164   TSP_struct_data_receiver_t* receiver;
00165     
00166   STRACE_IO(("-->IN"));
00167 
00168 
00169   receiver = (TSP_struct_data_receiver_t*)calloc(1, sizeof(TSP_struct_data_receiver_t));
00170   TSP_CHECK_ALLOC(receiver, 0);
00171 
00172   /* Allocate buffer for reception*/
00173   receiver->buf = (char*)calloc(TSP_DATA_RECEIVER_BUFFER_SIZE, sizeof(char));
00174   TSP_CHECK_ALLOC(receiver->buf, 0);
00175     
00176   receiver->read_callback = callback;
00177   receiver->user_data = user_data; 
00178   receiver->stream_receiver = TSP_stream_receiver_create(data_address);
00179   if( 0 == receiver->stream_receiver)
00180     {
00181       /* FIXME : bof...*/
00182       STRACE_ERROR(("TSP_stream_receiver_create failed")); 
00183       free(receiver->buf);receiver->buf = 0;
00184       free(receiver);
00185       receiver = 0;
00186     
00187     }
00188     
00189         
00190   STRACE_IO(("-->OUT"));
00191 
00192     
00193   return receiver;
00194 
00195 }
00196 
00197 int TSP_data_receiver_receive(TSP_data_receiver_t _receiver,
00198                               TSP_groups_t _groups,
00199                               TSP_sample_ringbuf_t* sample_fifo,
00200                               int* fifo_full) 
00201 {
00202     
00203   TSP_struct_data_receiver_t*  receiver = ( TSP_struct_data_receiver_t*) _receiver;
00204   TSP_group_t* groups =  ((TSP_group_table_t*)_groups)->groups;
00205   int nb_groups = ((TSP_group_table_t*)_groups)->table_len;
00206   int max_group_len = ((TSP_group_table_t*)_groups)->max_group_len;
00207   int group_index = 0;
00208   time_stamp_t time_stamp = 0;
00209   int ret = FALSE;
00210   int* buf_int;  
00211   TSP_sample_t* sample;
00212   TSP_sample_t sample_buf;
00213   int receiver_stopped;
00214 
00215   *fifo_full = FALSE;
00216   sample = &sample_buf;
00217 
00218 
00219   /* We read data if there enough room in ringbuf to store data, else, do nothing ; 
00220      we want the biggest group to have enough room, so we use max_group_len
00221      which the size of the biggest group and we compare with room left in ringbuf*/
00222   if( RINGBUF_PTR_ITEMS_LEFT(sample_fifo) > max_group_len )
00223     {
00224       
00225       /* OK, enough room. receive group size and time_stamp*/
00226       buf_int = (int*)(receiver->buf);
00227       ret = TSP_stream_receiver_receive(receiver->stream_receiver,
00228                                         (char*)buf_int,
00229                                         sizeof(int)*2);
00230       /* Check if the receiver was not stopped */
00231       receiver_stopped = TSP_stream_receiver_is_stopped(receiver->stream_receiver);
00232 
00233       if(ret && !receiver_stopped)
00234         {
00235           int buf_len;
00236           time_stamp = TSP_DECODE_INT(buf_int[0]);
00237           group_index = TSP_DECODE_INT(buf_int[1]);
00238 
00239           /* Check if the group_index looks real */
00240           if ((group_index < nb_groups) && (group_index >= 0) )
00241             {
00242             
00243               /*receive all doubles*/
00244               ret = TSP_stream_receiver_receive(receiver->stream_receiver,
00245                                                 receiver->buf,
00246                                                 groups[group_index].sizeof_encoded_group);    
00247 
00248               /* Check if the receiver was not stopped */
00249               receiver_stopped = TSP_stream_receiver_is_stopped(receiver->stream_receiver);
00250                                            
00251               if(ret && !receiver_stopped)
00252                 {
00253                   char* in_buf = receiver->buf;
00254                   int rank;     
00255               
00256                   /*printf("V=%f\n", *buf_double);*/
00257                   for( rank = 0 ; rank < groups[group_index].group_len ; rank++)
00258                     {
00259 
00260                       
00261                       /*--------------*/
00262                       if(! (receiver->read_callback) )
00263                         {
00264                           sample = RINGBUF_PTR_PUTBYADDR(sample_fifo);
00265                           assert(sample); /* can not be full, by design */
00266                         }
00267                       /*--------------*/
00268 
00269                       /* Call registered function to decode data */
00270                       ret = (groups[group_index].items[rank].data_decoder)(&(sample->user_value),in_buf);
00271                       if(!ret)
00272                         {
00273                           STRACE_ERROR(("decoder function failed"));
00274                           break;
00275                         }
00276                      
00277                       /* add time stamp */
00278                       sample->time = time_stamp;
00279                       sample->provider_global_index = groups[group_index].items[rank].provider_global_index;
00280 
00281                       /* FIXME : Implement error code returned by callback */
00282                       if(! (receiver->read_callback) )
00283                         {
00284                           /*(sample_fifo)->put = ((sample_fifo)->put + 1) % (sample_fifo)->size ;*/
00285                           RINGBUF_PTR_PUTBYADDR_COMMIT(sample_fifo);
00286                         }
00287                       else
00288                         {
00289                           (receiver->read_callback)(sample, receiver->user_data);
00290                         }
00291 
00292                       /* Goto next symbol */
00293                       in_buf += groups[group_index].items[rank].sizeof_encoded_item;
00294                      
00295                     }
00296                 }
00297               else
00298                 {
00299                   if(!receiver_stopped)
00300                     {
00301                       STRACE_WARNING(("Unable to receive samples"));
00302                       /* Add in fifo a message to report the incident via the read_sample API*/
00303                       TSP_data_receiver_process_receiver_error(sample_fifo);
00304                     }
00305                 }
00306         
00307             }
00308           else
00309             {
00310               /* Hum...Strange groupe index, may be it is a reserved on */
00311               ret = TSP_data_receiver_process_reserved_group_id(group_index, sample_fifo);
00312               if(!ret)
00313                 {
00314                   STRACE_ERROR(("The received group id is corrupted. This should not happen..."));
00315                   assert(0);
00316                   TSP_data_receiver_process_receiver_error(sample_fifo);
00317                 }
00318             }
00319       
00320         }
00321       else
00322         {
00323           if(!receiver_stopped)
00324             {             
00325               STRACE_WARNING(("Unable to receive group size and time stamp"));
00326               /* Add in fifo a message to report the incident via the read sample API*/
00327               TSP_data_receiver_process_receiver_error(sample_fifo);
00328             }
00329         }
00330     }
00331   else
00332     {
00333       if(!TSP_stream_receiver_is_stopped(receiver->stream_receiver))
00334         {       
00335           *fifo_full = TRUE;
00336           ret = TRUE;
00337         }
00338     }
00339     
00340 
00341 
00342   return ret;    
00343 }
00344 
00345 void TSP_data_receiver_stop(TSP_data_receiver_t _receiver)
00346 {
00347 
00348    TSP_struct_data_receiver_t*  receiver = ( TSP_struct_data_receiver_t*) _receiver;
00349 
00350    STRACE_IO(("-->IN"));
00351 
00352    TSP_stream_receiver_stop(receiver->stream_receiver);
00353 
00354    STRACE_IO(("-->OUT"));
00355 }
00356 
00357 void TSP_data_receiver_prepare_stop(TSP_data_receiver_t _receiver)
00358 {
00359    
00360    TSP_struct_data_receiver_t*  receiver = ( TSP_struct_data_receiver_t*) _receiver;
00361 
00362    STRACE_IO(("-->IN"));
00363 
00364    TSP_stream_receiver_prepare_stop(receiver->stream_receiver);
00365 
00366    STRACE_IO(("-->OUT"));
00367 }
00368 
00369 
00370 void TSP_data_receiver_destroy(TSP_data_receiver_t _receiver)
00371 {
00372    
00373    TSP_struct_data_receiver_t*  receiver = ( TSP_struct_data_receiver_t*) _receiver;
00374 
00375    STRACE_IO(("-->IN"));
00376    
00377    TSP_stream_receiver_destroy(receiver->stream_receiver);
00378    free(receiver->buf); receiver->buf = 0;
00379    free(receiver); 
00380 
00381    STRACE_IO(("-->OUT"));
00382 }
00383 
00384 
00385 TSP_data_decoder_t TSP_data_receiver_get_double_decoder(void)
00386 {
00387   return TSP_data_receiver_double_decoder;
00388 }
00389 
00390 int TSP_data_receiver_get_double_encoded_size(void)
00391 {
00392   return TSP_SIZEOF_ENCODED_DOUBLE;
00393 }
00394 
00395  
00396             
00397               
00398                               
00399             
Framework Home Page.

Beware !! TSP wave is coming...