TSP: The Transport Sample Protocol



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

tsp_consumer.c

Go to the documentation of this file.
00001 
00038 #include "tsp_sys_headers.h"
00039 
00040 #include "tsp_consumer.h"
00041 #include "tsp_client.h"
00042 #include "tsp_group.h"
00043 #include "tsp_data_receiver.h"
00044 #include "tsp_sample_ringbuf.h"
00045 #include "tsp_datastruct.h"
00046 
00047 
00048 /* Pool time for network data read (µs) */
00049 #define TSP_RECEIVER_THREAD_WAIT_FIFO_FULL (2e5)
00050 
00054 #define TSP_CHECK_SESSION(session, ret) \
00055         { \
00056                 if (0 == session) \
00057                 {  \
00058                         STRACE_ERROR(("The session object is NULL !")) \
00059                         return (ret); \
00060                 } \
00061                 if( UNDEFINED_CHANNEL_ID == session->channel_id) \
00062                 {  \
00063                         STRACE_ERROR(("No Channel Id available, the session need to be opened first !")) \
00064                         return (ret); \
00065                 } \
00066         }
00067 
00068 
00069 /*-----------------------------------------------------------------*/
00071 static  char** X_argv = 0;
00072 static  int X_argc = 0;
00073 
00075 static TSP_argv_t X_tsp_argv;
00076 
00078 static int X_tsp_init_ok = FALSE;
00079 /*-----------------------------------------------------------------*/
00080 
00085 struct TSP_otsp_t 
00086 {
00087     
00091   TSP_server_t* server;
00092   
00099   TSP_otsp_server_info_t server_info; 
00100   
00105   channel_id_t channel_id;
00106         
00111   TSP_consumer_information_t information;
00112   
00116   TSP_consumer_symbol_requested_list_t requested_sym;
00117 
00124   TSP_groups_t groups;
00125   
00131   TSP_data_receiver_t receiver;
00132   
00136   TSP_sample_ringbuf_t* sample_fifo;
00137   
00143   pthread_t thread_receiver;
00144 
00145 
00147   int data_link_broken; 
00148 
00149   
00150   
00151 };
00152 
00153 typedef struct TSP_otsp_t TSP_otsp_t;
00154 
00155 /*-------------------------------------------------------------------*/
00156 
00157 static void TSP_consumer_delete_information(TSP_otsp_t* otsp)
00158 {
00159   int i;
00160 
00161   STRACE_IO(("-->IN"));
00162 
00163   for(i = 0 ; i< otsp->information.symbols.len ; i++)
00164     {
00165       free(otsp->information.symbols.val[i].name);
00166       otsp->information.symbols.val[i].name = 0;
00167     }
00168   free(otsp->information.symbols.val);
00169   otsp->information.symbols.val = 0;
00170   
00171   STRACE_IO(("-->OUT"));
00172 
00173 }
00174 
00175 static void TSP_consumer_delete_requested_symbol(TSP_otsp_t* otsp)
00176 {
00177   int i;
00178 
00179   STRACE_IO(("-->IN"));
00180 
00181     if(otsp->requested_sym.val)
00182     {
00183       for (i = 0 ;  i < otsp->requested_sym.len ; i++)
00184         {
00185           /* free strdup */
00186           free(otsp->requested_sym.val[i].name);
00187           otsp->requested_sym.val[i].name = 0;
00188       
00189         }
00190       free(otsp->requested_sym.val);
00191       otsp->requested_sym.val = 0;
00192     }
00193 
00194   STRACE_IO(("-->OUT"));
00195 
00196 }
00197 
00198 
00205 static TSP_otsp_t* TSP_new_object_tsp(  TSP_server_t server,
00206                                         TSP_server_info_string_t server_info)
00207 {
00208   TSP_otsp_t* obj;
00209         
00210   STRACE_IO(("-->IN"));
00211 
00212         
00213   obj = (TSP_otsp_t*)calloc(1, sizeof(TSP_otsp_t) );
00214         
00215   if(0 == obj)
00216     { 
00217       printf("ERROR : calloc error\n");
00218       return 0;
00219     }
00220         
00221   obj->server = server;
00222   strncpy(obj->server_info.info, server_info, STRING_SIZE_SERVER_INFO);
00223         
00224   /* Init */
00225   obj->channel_id = UNDEFINED_CHANNEL_ID;
00226         
00227   obj->information.symbols.len = 0;
00228   obj->information.symbols.val = 0;
00229   obj->requested_sym.len = 0;
00230   obj->requested_sym.val = 0;
00231   obj->groups = 0;
00232   obj->receiver = 0;
00233   obj->sample_fifo = NULL;
00234   obj->data_link_broken=FALSE;
00235         
00236   STRACE_IO(("-->OUT"));
00237 
00238         
00239   return obj;
00240 }
00241 
00242 
00243 static void TSP_delete_object_tsp(TSP_otsp_t* o)
00244 {
00245   STRACE_IO(("-->IN"));
00246 
00247   TSP_consumer_delete_information(o);
00248   TSP_consumer_delete_requested_symbol(o);
00249   TSP_group_delete_group_table(o->groups); o->groups = 0;
00250   free(o);
00251         
00252   STRACE_IO(("-->OUT"));
00253 
00254 }
00255 
00256 static  void TSP_print_object_tsp(TSP_otsp_t* o)
00257 {
00258         
00259   STRACE_IO(("-->IN"));
00260   STRACE_INFO(("----------------------------------------------"));
00261   STRACE_INFO(("SERVER_INFO->INFO='%s'\n", o->server_info.info));
00262   STRACE_INFO(("----------------------------------------------"));
00263   STRACE_IO(("-->OUT"));
00264 
00265 }
00266 
00267 /*-------------------------------------------------------------------*/
00268 
00269 int TSP_consumer_init(int* argc, char** argv[])
00270 {
00271   int i;
00272   int final_argc = 1;
00273   int found_stream_start = FALSE;
00274   int found_stream_stop = FALSE;
00275   char* p;
00276   int ret = TRUE;
00277 
00278   STRACE_IO(("-->IN"));
00279 
00280   X_argv = (char**)calloc(*argc, sizeof(char*));
00281   X_tsp_argv.TSP_argv_t_val = (char**)calloc(*argc, sizeof(char*));
00282   X_tsp_argv.TSP_argv_t_len = 0;
00283   TSP_CHECK_ALLOC(X_argv, FALSE);
00284   TSP_CHECK_ALLOC(X_tsp_argv.TSP_argv_t_val, FALSE);
00285   /* Get program name anyway */
00286   X_argv[0] = (*argv)[0];
00287   for( i = 1 ; i < *argc && ret ; i++)
00288     {
00289       /* Is the arg a TSP arg ? */
00290       p = strstr( (*argv)[i], TSP_ARG_PREFIX );
00291       if(p && (p == (*argv)[i] ))
00292         {
00293           
00294           /* TSP Arg */
00295           STRACE_INFO(("Tsp ARG : '%s'", (*argv)[i]));
00296           
00297 
00298           /* Look for start flag */
00299           if(!strcmp(TSP_ARG_STREAM_INIT_START, (*argv)[i]))
00300             {
00301               if(!found_stream_stop && !found_stream_start)
00302                 {
00303                   found_stream_start = TRUE;
00304                   /* Ok the user wants a default stream control, put
00305                      the first dummy element */
00306                   if ( 0 == X_tsp_argv.TSP_argv_t_len )
00307                     {
00308                       X_tsp_argv.TSP_argv_t_val[0] = TSP_ARG_DUMMY_PROG_NAME;
00309                       X_tsp_argv.TSP_argv_t_len = 1;
00310                     }
00311                 }
00312               else
00313                 {
00314                   STRACE_WARNING(("Unexpected "TSP_ARG_STREAM_INIT_START));
00315                   ret = FALSE;
00316                 }
00317             }
00318           else if (!strcmp(TSP_ARG_STREAM_INIT_STOP, (*argv)[i]))
00319             {
00320               if(found_stream_start && !found_stream_stop)              
00321                 {
00322                   found_stream_stop = TRUE;
00323                 }
00324               else
00325                 {
00326                   STRACE_WARNING(("Unexpected "TSP_ARG_STREAM_INIT_STOP));
00327                   ret = FALSE;
00328                 }
00329             }
00330           else
00331             {
00332               /* Unkown option */
00333               STRACE_WARNING(("Unknown TSP option : '%s'",(*argv)[i] ))
00334               ret = FALSE;
00335             }
00336         }
00337       else /* Not a TSP arg */
00338         {
00339           /* Are we in the TSP command line ? */
00340           if ( found_stream_start && !found_stream_stop )
00341             {
00342               X_tsp_argv.TSP_argv_t_val[X_tsp_argv.TSP_argv_t_len++] = (*argv)[i];
00343             }
00344           else
00345             {
00346               /* Nop, this arg is for the user */
00347               X_argv[final_argc] = (*argv)[i];
00348               final_argc++;
00349             }
00350         }
00351     } /* for */
00352   
00353   /* Check is the stop was found */
00354   
00355   if( found_stream_start && !found_stream_stop )
00356     {
00357       STRACE_WARNING(("A " TSP_ARG_STREAM_INIT_STOP " flag was expected"));
00358       ret = FALSE;
00359     }
00360 
00361   /* swap argc and argv values */
00362   *argc = final_argc;
00363   *argv = X_argv;
00364 
00365   STRACE_IO(("-->OUT"));
00366 
00367   X_tsp_init_ok = ret;
00368   
00369   /* Display usage */
00370   if(!ret)
00371     {
00372       STRACE_WARNING((TSP_ARG_CONSUMER_USAGE));
00373     }
00374 
00375   return ret;
00376   
00377 }
00378 
00379 
00380 
00381 void TSP_consumer_end(void)
00382 {       
00383 
00384   STRACE_IO(("-->IN"));
00385   
00386   /* This is the end my friend ... the end ...*/
00387 
00388   /* Some day, we will find stuff to do here ;) */
00389 
00390    /* By the way. do ->NOT<- free X_tsp_argv and X_argv,
00391      the main code may be using them... */
00392 
00393   STRACE_INFO(("End..."));
00394 
00395   STRACE_IO(("-->OUT"));
00396 }
00397 
00398 TSP_provider_t* TSP_consumer_connect_url(const char*  url)
00399 {       
00400   TSP_provider_t *provider = NULL;
00401   TSP_server_t server;
00402   TSP_server_info_string_t server_info;
00403 
00404   int i, servernumber;
00405   char url_tok[2*MAXHOSTNAMELEN], url_lkup[2*MAXHOSTNAMELEN];
00406   char *protocol, *hostname, *servername, *p;
00407 
00409   protocol = NULL;
00410   hostname = NULL;
00411   servername = NULL;
00412   servernumber = -1;
00413 
00414   if(!url)
00415     url = "";
00416 
00417   bzero(url_tok, sizeof(url_tok));
00418   strcpy(url_tok, url);
00419     
00420   protocol = url_tok;
00421   p = strstr(url_tok, "://");
00422   if(!p)
00423     {
00424       /* set p to hostname field, if any */
00425       p = strstr(url_tok, "//");
00426       if(p) p += 2;
00427       else p = url_tok; /* may start of string be the hostname ?! */
00428 
00429       /* no protocol specified, use default */
00430       protocol = strdup(TSP_RPC_PROTOCOL);
00431    }
00432   else
00433     {
00434       /* protocol should be OK (start of URL), set p to hostname field */
00435       if(p == url_tok) protocol = strdup(TSP_RPC_PROTOCOL);
00436       *p = '\0';
00437       p += 3;
00438     }
00439 
00440   hostname = p;
00441   p = strstr(hostname, "/");
00442   if(p == hostname)
00443     {
00444       /* no hostname provided, use default & set p to server name field */
00445       hostname = strdup("localhost");
00446       p += 1;
00447     }
00448   else if(!p)
00449     {
00450       /* end of string ... hostname should be OK, set p to the end */
00451       p = hostname + strlen(hostname);
00452     }
00453   else
00454     {
00455       /* hostname is OK, set p to server name field */
00456       *p = '\0';
00457       p += 1;
00458     }
00459 
00460   servername = p;
00461   p = strstr(servername, ":");
00462   if(!p)
00463     {
00464       /* servername should be OK (or 0 length), set p to number field */
00465       p = servername + strlen(servername);
00466     }
00467   else
00468     {
00469       /* servername is OK, set p to number field */
00470       *p = '\0';
00471       p += 1;
00472     }
00473 
00474   if(*p)
00475     {
00476       servernumber = atoi(p);
00477       if(errno == EINVAL)
00478         servernumber = -1;
00479     }
00480 
00481 
00483   if( servernumber >= 0 )
00484     {
00485       sprintf(url_lkup, TSP_URL_FORMAT, protocol, hostname, servername, servernumber);
00486       STRACE_INFO(("Trying to connect to <%s>", url_lkup ));
00487 
00488       /* Is server name/number alive on given host on that protocol ?*/ 
00489       if(TSP_remote_open_server(  protocol,
00490                                   hostname,
00491                                   servername,
00492                                   servernumber, 
00493                                   &server,
00494                                   server_info))
00495         {
00496           /* yes, got it !!! */
00497           sprintf(url_lkup, TSP_URL_FORMAT, protocol, hostname, server_info, servernumber);
00498           return (TSP_provider_t*)TSP_new_object_tsp(server, url_lkup);
00499         }
00500       
00501       STRACE_ERROR(("No TSP provider on URL <%s>", url_lkup));
00502       return NULL;
00503     }
00504 else
00505     {
00507       int server_max_number = TSP_get_server_max_number();
00508        
00509       for(i = 0; i < server_max_number; i++)
00510         {
00511           sprintf(url_lkup, TSP_URL_FORMAT, protocol, hostname, servername, i);
00512           provider = TSP_consumer_connect_url(url_lkup);
00513           if(provider)
00514             return provider;
00515         }
00516       STRACE_ERROR(("No TSP provider based on URL <%s>", url));
00517       return NULL;
00518       
00519     }
00520 
00521   STRACE_ERROR(("Cannot parse such URL %s", url));
00522   return NULL;
00523 }
00524 
00525 void TSP_consumer_disconnect_one(TSP_provider_t provider)
00526 {       
00527   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00528 
00529   STRACE_IO(("-->IN"));
00530   
00531   TSP_remote_close_server(otsp->server);
00532   TSP_delete_object_tsp(otsp);
00533         
00534   STRACE_IO(("-->OUT"));
00535 
00536 }
00537 
00538 
00539 
00540 /*--- Connect/Disconnect All & Get Connected name deprecated ... ---*/
00541 
00542 void TSP_consumer_connect_all(const char*  host_name, TSP_provider_t** providers, int* nb_providers)
00543 {       
00544         
00545   int i;
00546 
00547   /* Get max number of provider allowed on any host */
00548   int server_max_number = TSP_get_server_max_number();
00549 
00550   fprintf(stderr, "\n\007This function is now deprecated, use TSP_consumer_connect_url instead\007\n");
00551 
00552   STRACE_IO(("-->IN"));
00553         
00554   *nb_providers = 0;
00555         
00556   if( server_max_number > 0 )
00557     {
00558       *providers = (TSP_provider_t*)calloc(server_max_number,sizeof(TSP_provider_t));
00559       TSP_CHECK_ALLOC(providers,);
00560                 
00561       /* Iterate on all providers, and try to contact them */
00562       for(i = 0 ; i < server_max_number ; i++)
00563         {
00564           TSP_server_t server;
00565           TSP_server_info_string_t server_info;
00566 
00567           STRACE_DEBUG(("Trying to open server No %d", i));
00568 
00569           /* Is server number 'i' alive ?*/ 
00570           if(TSP_remote_open_server(  TSP_RPC_PROTOCOL,
00571                                       host_name,
00572                                       "",
00573                                       i, 
00574                                       &server,
00575                                       server_info))
00576             {
00577                           
00578               (*providers)[*nb_providers] = TSP_new_object_tsp(server, server_info);
00579               if( 0 == (*providers)[*nb_providers])
00580                 {
00581                   STRACE_ERROR(("TSP_new_object_tsp failedfor No=%d", i));
00582                   (*nb_providers) = 0;
00583                   return;
00584 
00585                 }
00586               (*nb_providers)++;
00587                                 
00588             }
00589           else
00590             {
00591               STRACE_DEBUG(("unable to open server No %d for target '%s'", i, host_name));
00592             }
00593                                 
00594         }
00595     }
00596   else
00597     {
00598       STRACE_ERROR(("Unable to get server max number"));
00599     }
00600 
00601   STRACE_INFO(("%d server opened", *nb_providers));
00602   STRACE_IO(("-->OUT"));
00603 
00604 }
00605 
00606 
00607 void TSP_consumer_disconnect_all(TSP_provider_t providers[])
00608 {       
00609   int server_max_number;
00610   int i;
00611         
00612   STRACE_IO(("-->IN"));
00613 
00614   fprintf(stderr, "\n\007This function is now deprecated, use TSP_consumer_disconnect_one instead\007\n");
00615 
00616   server_max_number = TSP_get_server_max_number();
00617   if( server_max_number > 0 )
00618     {
00619                 
00620       for(i = 0 ; i < server_max_number ; i++)
00621         {
00622           if(providers[i])
00623             {
00624               TSP_consumer_disconnect_one(providers[i]);
00625               providers[i] = 0;
00626             }
00627                                 
00628         }
00629     }
00630   else
00631     {
00632       STRACE_ERROR(("Unable to get server max number"));
00633     }
00634   
00635   free(providers);
00636         
00637   STRACE_IO(("-->OUT"));
00638 
00639 }
00640 
00641 /*--- End of deprecated functions ---*/
00642 
00643 const char* TSP_consumer_get_connected_name(TSP_provider_t provider)                      
00644 {
00645   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00646         
00647   return(otsp->server_info.info);
00648 }
00649 
00650 
00651 int TSP_consumer_request_open(TSP_provider_t provider, int custom_argc, char* custom_argv[])
00652 {
00653         
00654   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00655   TSP_request_open_t req_open;
00656   TSP_answer_open_t* ans_open = 0;
00657   int ret = FALSE;
00658         
00659   STRACE_IO(("-->IN"));
00660   assert(X_tsp_init_ok);
00661         
00662   req_open.version_id = TSP_VERSION;
00663 
00664   /* Default argv to command line (may be empty) */
00665   req_open.argv = X_tsp_argv;
00666 
00667   /* Does the user want a specific argv  value ? */
00668   if( ( 0 != custom_argc)  && custom_argv)
00669     {
00670       /* Check if a command line exists and trace a warning */
00671       if( 0 != X_tsp_argv.TSP_argv_t_len )
00672         {
00673           STRACE_WARNING(("Overiding command line stream initialisation by custom stream initialisation")); 
00674         }
00675       req_open.argv.TSP_argv_t_val = custom_argv;
00676       req_open.argv.TSP_argv_t_len = custom_argc;
00677     }
00678 
00679         
00680   if(0 != otsp)
00681     {
00682       ans_open = TSP_request_open(&req_open, otsp->server);
00683       if( NULL != ans_open)
00684         {
00685 
00686           switch (ans_open->status)
00687             {
00688             case TSP_STATUS_OK :
00689               otsp->channel_id = ans_open->channel_id;
00690               ret = TRUE;
00691               break;
00692             case TSP_STATUS_ERROR_SEE_STRING :
00693               STRACE_WARNING(("Provider error : %s", ans_open->status_str));
00694               break;
00695             case TSP_STATUS_ERROR_UNKNOWN :
00696               STRACE_WARNING(("Provider unknown error"));
00697               break;
00698             case TSP_STATUS_ERROR_VERSION :
00699               STRACE_WARNING(("Provider version error"));
00700               break;
00701             default:
00702               STRACE_ERROR(("The provider sent an unreferenced error. It looks like a bug."));
00703               break;
00704             }
00705         }
00706       else
00707         {
00708           STRACE_ERROR(("Unable to communicate with the provider"));
00709 
00710         }
00711                 
00712     }
00713   else
00714     {
00715       STRACE_ERROR(("This provider need to be remote_opened first"));
00716 
00717     }
00718         
00719   STRACE_IO(("-->OUT"));
00720 
00721         
00722   return ret;
00723         
00724 }
00725 
00726 int TSP_consumer_request_close(TSP_provider_t provider)
00727 {
00728   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00729   TSP_request_close_t req_close;
00730   int ret = FALSE;
00731         
00732   STRACE_IO(("-->IN"));
00733 
00734         
00735   TSP_CHECK_SESSION(otsp, FALSE);
00736         
00737   req_close.version_id = TSP_VERSION;
00738   req_close.channel_id = otsp->channel_id;
00739         
00740   STRACE_DEBUG(("Trying to close channel_id=%u", otsp->channel_id));
00741 
00742         
00743   ret = TSP_request_close(&req_close, otsp->server);
00744   if( FALSE == ret)
00745     {
00746       STRACE_DEBUG(("Unable to close channel_id=%u", otsp->channel_id));
00747 
00748     }
00749   else
00750     {
00751       STRACE_DEBUG(("channel_id=%u is closed", otsp->channel_id));
00752 
00753     }
00754 
00755   STRACE_IO(("-->OUT"));
00756 
00757         
00758   return ret;
00759         
00760 }
00761 
00762 
00763 
00764 int TSP_consumer_request_information(TSP_provider_t provider)
00765 {
00766         
00767   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00768   TSP_request_information_t req_info;
00769   TSP_answer_sample_t* ans_sample = 0;
00770   int ret = FALSE;
00771         
00772   STRACE_IO(("-->IN"));
00773 
00774         
00775   TSP_CHECK_SESSION(otsp, FALSE);
00776 
00777   /* Delete allocation of any previous call */
00778   TSP_consumer_delete_information(otsp);
00779         
00780   req_info.version_id = TSP_VERSION;
00781   req_info.channel_id = otsp->channel_id;
00782         
00783   /* Ask the provider for informations */
00784   ans_sample = TSP_request_information(&req_info, otsp->server);
00785     
00786   if( NULL != ans_sample)
00787     {
00788       
00789       switch (ans_sample->status)
00790         {
00791         case TSP_STATUS_OK :
00792           ret = TRUE;
00793           break;
00794         case TSP_STATUS_ERROR_UNKNOWN :
00795           STRACE_WARNING(("Provider unknown error"));
00796           break;
00797         case TSP_STATUS_ERROR_VERSION :
00798           STRACE_WARNING(("Provider version error"));
00799           break;
00800         default:
00801           STRACE_ERROR(("The provider sent an unreferenced error. It looks like a bug."));
00802           break;
00803         }
00804     }
00805 
00806   /* Save all thoses sample data in memory */
00807   if( TRUE == ret )
00808     {
00809       unsigned int symbols_number =
00810         ans_sample->symbols.TSP_sample_symbol_info_list_t_len;
00811       unsigned int i;
00812         
00813 
00814       otsp->information.base_frequency = ans_sample->base_frequency;
00815       otsp->information.max_period = ans_sample->max_period;
00816       otsp->information.max_client_number = ans_sample->max_client_number;
00817       otsp->information.current_client_number = ans_sample->current_client_number;
00818                         
00819       STRACE_DEBUG(("Total number of symbols found = %d",symbols_number));
00820       STRACE_INFO(("Provider base frequency = %f Hz", ans_sample->base_frequency));
00821 
00822       /* allocate memory to store those symbols */
00823       otsp->information.symbols.len = symbols_number;
00824       if(symbols_number > 0)
00825         {
00826           otsp->information.symbols.val = 
00827             (TSP_consumer_symbol_info_t* )calloc(symbols_number,sizeof(TSP_consumer_symbol_info_t));
00828           TSP_CHECK_ALLOC(otsp->information.symbols.val, FALSE);
00829                 
00830           for(i = 0 ; i< symbols_number ; i++)
00831             {           
00832               otsp->information.symbols.val[i].index =
00833                 ans_sample->symbols.TSP_sample_symbol_info_list_t_val[i].provider_global_index;
00834               otsp->information.symbols.val[i].name =
00835                 strdup(ans_sample->symbols.TSP_sample_symbol_info_list_t_val[i].name);                          
00836               TSP_CHECK_ALLOC(otsp->information.symbols.val[i].name, FALSE);                    
00837             }
00838         }
00839     }
00840   else
00841     {
00842       STRACE_ERROR(("Unable to communicate with the provider"));
00843 
00844     }
00845                 
00846         
00847   STRACE_IO(("-->OUT"));
00848 
00849         
00850   return ret;
00851         
00852 }
00853 
00854 
00855 const TSP_consumer_information_t*  TSP_consumer_get_information(TSP_provider_t provider)
00856 {
00857         
00858   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00859         
00860   STRACE_IO(("-->IN"));
00861 
00862         
00863   TSP_CHECK_SESSION(otsp, 0);
00864         
00865   STRACE_IO(("-->OUT"));
00866 
00867         
00868   return &(otsp->information);
00869         
00870 
00871 }
00872 
00873 static int TSP_consumer_store_requested_symbols(TSP_consumer_symbol_requested_list_t* stored_sym,
00874                                                 TSP_sample_symbol_info_list_t* new_sym)
00875 {
00876 
00877   int i;
00878   if(stored_sym->val)
00879     {
00880       for (i = 0 ;  i < stored_sym->len ; i++)
00881         {
00882           /* free strdup */
00883           free(stored_sym->val[i].name);
00884         }
00885       free(stored_sym->val);
00886     }
00887   stored_sym->len = new_sym->TSP_sample_symbol_info_list_t_len; 
00888   stored_sym->val = 
00889     (TSP_consumer_symbol_requested_t* )calloc(stored_sym->len,
00890                                               sizeof(TSP_consumer_symbol_requested_t));
00891   TSP_CHECK_ALLOC(stored_sym->val, FALSE);
00892                 
00893   /* For each requested symbol, we store it */
00894   for(i = 0 ; i< stored_sym->len ; i++)
00895     {           
00896       /* FIXME : ajouter les autres valeurs */
00897       stored_sym->val[i].name = strdup(new_sym->TSP_sample_symbol_info_list_t_val[i].name);
00898       TSP_CHECK_ALLOC(stored_sym->val[i].name, FALSE);
00899       stored_sym->val[i].index = new_sym->TSP_sample_symbol_info_list_t_val[i].provider_global_index;
00900       stored_sym->val[i].phase = new_sym->TSP_sample_symbol_info_list_t_val[i].phase;
00901       stored_sym->val[i].period = new_sym->TSP_sample_symbol_info_list_t_val[i].period;
00902     }
00903   return TRUE;
00904 }
00905 
00906 
00907 int TSP_consumer_request_sample(TSP_provider_t provider, TSP_consumer_symbol_requested_list_t* symbols)
00908 {
00909         
00910   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
00911   int ret = FALSE;
00912   TSP_answer_sample_t* ans_sample = 0;
00913   TSP_request_sample_t req_sample;
00914   int i;
00915         
00916   STRACE_IO(("-->IN"));
00917 
00918         
00919   TSP_CHECK_SESSION(otsp, FALSE);
00920         
00921   req_sample.version_id = TSP_VERSION;
00922   req_sample.channel_id = otsp->channel_id;
00923   req_sample.symbols.TSP_sample_symbol_info_list_t_len = symbols->len;
00924   req_sample.symbols.TSP_sample_symbol_info_list_t_val = 
00925     (TSP_sample_symbol_info_t*)calloc(symbols->len, sizeof(TSP_sample_symbol_info_t));
00926   TSP_CHECK_ALLOC(req_sample.symbols.TSP_sample_symbol_info_list_t_val, FALSE);
00927 
00928   for(i = 0 ; i <  symbols->len ; i++)
00929     {
00930 
00931       req_sample.symbols.TSP_sample_symbol_info_list_t_val[i].provider_global_index = -1;
00932       req_sample.symbols.TSP_sample_symbol_info_list_t_val[i].period = symbols->val[i].period;
00933       req_sample.symbols.TSP_sample_symbol_info_list_t_val[i].phase = symbols->val[i].phase;
00934       req_sample.symbols.TSP_sample_symbol_info_list_t_val[i].name = symbols->val[i].name;
00935     }
00936         
00937   /* Get the computed ans_sample from the provider */
00938   ans_sample = TSP_request_sample(&req_sample, otsp->server);
00939 
00940   /*free allocated request sample symbol list */
00941   free(req_sample.symbols.TSP_sample_symbol_info_list_t_val);  
00942        
00943   if( 0 != ans_sample)
00944     {      
00945       
00946       switch (ans_sample->status)
00947         {
00948         case TSP_STATUS_OK :
00949           ret = TRUE;
00950           break;
00951         case TSP_STATUS_ERROR_UNKNOWN :
00952           STRACE_WARNING(("Provider unknown error"));
00953           break;
00954         case TSP_STATUS_ERROR_VERSION :
00955           STRACE_WARNING(("Provider version error"));
00956           break;
00957         case TSP_STATUS_ERROR_SYMBOLS :
00958           STRACE_WARNING(("Provider symbols error"));
00959           break;
00960         default:
00961           STRACE_ERROR(("The provider sent an unreferenced error. It looks like a bug."));
00962           break;
00963         }
00964 
00965 
00966       /*-------------------------------------------------*/
00967       /* Create group table and store requested symbols */
00968       /*-------------------------------------------------*/
00969       if(ret)
00970         {
00971           STRACE_INFO(("Total groupe number = %d", ans_sample->provider_group_number));
00972           /* Create group table but delete any previous allocation*/
00973           TSP_group_delete_group_table(otsp->groups);
00974           otsp->groups = TSP_group_create_group_table(&(ans_sample->symbols), ans_sample->provider_group_number);
00975           if( 0 != otsp->groups)
00976             {
00977               ret = TSP_consumer_store_requested_symbols(&otsp->requested_sym,&ans_sample->symbols);
00978             }
00979           else
00980             {
00981               STRACE_ERROR(("Function TSP_group_create_group_table failed"));
00982 
00983             }
00984         }
00985     }
00986   else
00987     {
00988       STRACE_ERROR(("Unable to communicate with the provider"));
00989 
00990     }
00991     
00992         
00993   STRACE_IO(("-->OUT"));
00994 
00995         
00996   return ret;
00997 }
00998 
00999 const TSP_consumer_symbol_requested_list_t* TSP_consumer_get_requested_sample(TSP_provider_t provider)
01000 {
01001         
01002   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
01003         
01004   STRACE_IO(("-->IN"));
01005         
01006   TSP_CHECK_SESSION(otsp, 0);
01007         
01008   STRACE_IO(("-->OUT"));
01009   
01010   if(otsp->requested_sym.val)
01011     return &(otsp->requested_sym);
01012   else
01013     {
01014       STRACE_ERROR(("TSP_consumer_request_sample must be called first"));
01015       return 0;
01016     }
01017 }
01018 
01019 static void* TSP_request_provider_thread_receiver(void* arg)
01020 {
01021     
01022   TSP_otsp_t* otsp = (TSP_otsp_t*)arg;
01023   int is_fifo_full;  
01024                     
01025   STRACE_IO(("-->IN"));
01026   STRACE_INFO(("Receiver thread started. Id=%u", pthread_self())); 
01027 
01028   while(TRUE)
01029     {
01030       if(TSP_data_receiver_receive(otsp->receiver, otsp->groups, otsp->sample_fifo, &is_fifo_full))
01031         {
01032           /* Fifo is full, wait for user thread to free room for new data */
01033           if(is_fifo_full)
01034             {
01035               tsp_usleep(TSP_RECEIVER_THREAD_WAIT_FIFO_FULL);      
01036             }
01037         }
01038       else
01039         {
01040           STRACE_INFO(("function TSP_data_receiver_receive returned FALSE. End of Thread"));
01041           break;
01042         }
01043  
01044     }
01045   
01046   STRACE_IO(("-->OUT"));
01047   return (void*)NULL;
01048 }
01049 
01050 int TSP_consumer_request_sample_init(TSP_provider_t provider, TSP_sample_callback_t callback, void* user_data)
01051 {
01052         
01053   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
01054   int ret = FALSE;
01055   TSP_answer_sample_init_t* ans_sample = 0;
01056   TSP_request_sample_init_t req_sample;
01057         
01058   STRACE_IO(("-->IN"));
01059   
01060   
01061   TSP_CHECK_SESSION(otsp, FALSE);
01062   
01063   req_sample.version_id = TSP_VERSION;
01064   req_sample.channel_id = otsp->channel_id;
01065   
01066   ans_sample = TSP_request_sample_init(&req_sample, otsp->server);
01067   
01068   if( ans_sample)
01069     {
01070       STRACE_DEBUG(("data_address = '%s'", ans_sample->data_address));
01071       
01072       /* Create the data receiver */
01073       otsp->receiver = TSP_data_receiver_create(ans_sample->data_address, callback, user_data);
01074       
01075       if(otsp->receiver)
01076         {
01077           int status;
01078 
01079           /* Create receiver fifo */
01080           RINGBUF_PTR_INIT(TSP_sample_ringbuf_t,
01081                            otsp->sample_fifo,
01082                            TSP_sample_t,
01083                            0,
01084                            RINGBUF_SZ(TSP_CONSUMER_RINGBUF_SIZE) )
01085                     
01086             
01087           /* Begin to receive */
01088           status = pthread_create(&(otsp->thread_receiver), 
01089                                   NULL,
01090                                   TSP_request_provider_thread_receiver,
01091                                   otsp);
01092           
01093           TSP_CHECK_THREAD(status, FALSE);
01094           ret = TRUE;
01095           
01096         }
01097       else
01098         {
01099           STRACE_ERROR(("Unable to create data receiver"));
01100           
01101         }
01102     }
01103   else
01104     {
01105       STRACE_ERROR(("Unable to communicate with the provider"));
01106     }
01107   
01108   STRACE_IO(("-->OUT"));
01109 
01110         
01111   return ret;
01112 }
01113 
01114 int TSP_consumer_request_sample_destroy(TSP_provider_t provider)
01115 {
01116         
01117   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
01118   int ret = FALSE;
01119   TSP_answer_sample_destroy_t* ans_sample = 0;
01120   TSP_request_sample_destroy_t req_sample;
01121         
01122   STRACE_IO(("-->IN"));
01123   
01124   
01125   TSP_CHECK_SESSION(otsp, FALSE);
01126   
01127   req_sample.version_id = TSP_VERSION;
01128   req_sample.channel_id = otsp->channel_id;  
01129   
01130   /* turn all alarms off, coz the provider is going to break its socket */
01131   TSP_data_receiver_prepare_stop(otsp->receiver);
01132 
01133   /* break the provider socket !  */
01134   ans_sample = TSP_request_sample_destroy(&req_sample, otsp->server);  
01135   if(ans_sample)    
01136     {
01137       switch (ans_sample->status)
01138         {
01139         case TSP_STATUS_OK :
01140           ret = TRUE;
01141           break;
01142         case TSP_STATUS_ERROR_UNKNOWN :
01143           STRACE_WARNING(("Provider unknown error"));
01144           break;
01145         case TSP_STATUS_ERROR_VERSION :
01146           STRACE_WARNING(("Provider version error"));
01147           break;
01148         default:
01149           STRACE_ERROR(("The provider sent an unreferenced error. It looks like a bug."));
01150           break;
01151         }
01152     }
01153   else
01154     {
01155       ret = FALSE;
01156       STRACE_WARNING(("Unable to communicate with the provider"));            
01157     }
01158   
01159     /* Destroy our socket */
01160   TSP_data_receiver_stop(otsp->receiver);
01161   
01162   /* Wait for receiver thread to end */
01163   pthread_join(otsp->thread_receiver, NULL);
01164 
01165   /* OK, the thread is stopped. We can desallocate */
01166   TSP_data_receiver_destroy(otsp->receiver);
01167 
01168   /*Destroy ringbuf*/
01169   RINGBUF_PTR_DESTROY(otsp->sample_fifo);
01170   
01171   STRACE_IO(("-->OUT"));
01172         
01173   return ret;
01174 }
01175 
01176 
01177 int TSP_consumer_read_sample(TSP_provider_t provider, TSP_sample_t* sample, int* new_sample)
01178 {
01179 
01180   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
01181   int ret = TRUE;
01182     
01183   assert(otsp->sample_fifo!=0);
01184 
01185   *new_sample =  !(RINGBUF_PTR_ISEMPTY(otsp->sample_fifo)) ;
01186   if (*new_sample)
01187     {
01188       RINGBUF_PTR_NOCHECK_GET(otsp->sample_fifo ,(*sample));
01189 
01190       /* end of stream ? */
01191       if ( sample->provider_global_index < 0 )
01192         {
01193           ret = FALSE;
01194           
01195           /* GIGAFIXME : We need some kind of get_last_error to read
01196              these values thrue the consumer API */
01197           STRACE_INFO(("Received status message %X",  sample->provider_global_index));
01198           switch(sample->provider_global_index)
01199             {
01200             case TSP_DUMMY_PROVIDER_GLOBAL_INDEX_EOF :
01201               STRACE_INFO (("status message EOF"));
01202               /* FIXME : get last error à gerer ? */
01203               break;
01204             case TSP_DUMMY_PROVIDER_GLOBAL_INDEX_RECONF :
01205               STRACE_INFO (("status message RECONF"));
01206               /* FIXME : get last error à gerer ? */
01207               break;
01208             case TSP_DUMMY_PROVIDER_GLOBAL_INDEX_RECEIVER_ERROR :
01209               STRACE_WARNING (("status message RECEIVER ERROR"));
01210               /* FIXME : get last error à gerer ? */
01211               break;
01212             case TSP_DUMMY_PROVIDER_GLOBAL_INDEX_GLU_DATA_LOST :
01213               STRACE_WARNING (("status message GLU DATA LOST. Some data were lost by the GLU on the provider side. "
01214                                "is the provider too slow ?"));
01215               /* FIXME : get last error à gerer ? */
01216               break;
01217             case TSP_DUMMY_PROVIDER_GLOBAL_INDEX_CONSUMER_DATA_LOST :
01218               STRACE_WARNING (("status message CONSUMER DATA LOST. Some data were lost for this consumer"
01219                                " on the provider side. Is the consumer too slow, or"
01220                                " the network overloaded ?"));
01221               /* FIXME : get last error à gerer ? */
01222               break;
01223             default:
01224               STRACE_ERROR (("Unknown status message"));
01225               /* FIXME : get last error à gerer ? */
01226             }
01227         }
01228     }
01229       
01230   return ret;
01231 }
01232 
01233 TSP_groups_t TSP_test_get_groups(TSP_provider_t provider)
01234 {
01235   TSP_otsp_t* otsp = (TSP_otsp_t*)provider;
01236   
01237   return otsp->groups;
01238 }
01239 
Framework Home Page.

Beware !! TSP wave is coming...