TSP: The Transport Sample Protocol



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

tsp_provider.c

Go to the documentation of this file.
00001 
00038 #include "tsp_sys_headers.h"
00039 
00040 #include "tsp_provider.h"
00041 
00042 #include "tsp_session.h"
00043 #include "glue_sserver.h"       
00044 #include "tsp_time.h"   
00045 
00047 static  char** X_argv = 0;
00048 
00050 static  char** X_glu_argv = 0;
00051 static  int X_glu_argc = 0;
00052 
00056 static int X_server_base_number = 0;
00057 
00058 
00059 static int X_tsp_provider_init_ok = FALSE;
00060 
00069 static pthread_mutex_t X_tsp_request_mutex = PTHREAD_MUTEX_INITIALIZER;
00070 
00072 static int X_glu_is_active;
00073 
00074 /* polling time for session garbage collector */
00075 #define TSP_GARBAGE_COLLECTOR_POLL_TIME_US ((int)(5e6))
00076 
00077 static int TSP_cmd_line_parser(int* argc, char** argv[])
00078 {
00079   int i;
00080   int final_argc = 1;
00081   int found_stream_start = FALSE;
00082   int found_stream_stop = FALSE;
00083   int found_server_number_flag = FALSE;
00084   char* p;
00085   int ret = TRUE;
00086 
00087   STRACE_IO(("-->IN"));
00088 
00089   /* FIXME : FUITE */
00090   X_argv = (char**)calloc(*argc, sizeof(char*));
00091   X_glu_argv = (char**)calloc(*argc, sizeof(char*));
00092   X_glu_argc = 0;
00093   TSP_CHECK_ALLOC(X_argv, FALSE);
00094   TSP_CHECK_ALLOC(X_glu_argv, FALSE);
00095   /* Get program name anyway */
00096   X_argv[0] = (*argv)[0];
00097   for( i = 1 ; i < *argc && ret ; i++)
00098     {
00099       /* Is the arg a TSP arg ? */
00100       p = strstr( (*argv)[i], TSP_ARG_PREFIX );
00101       if(p && (p == (*argv)[i] ))
00102         {
00103           /* TSP Arg */
00104           STRACE_INFO(("Tsp ARG : '%s'", (*argv)[i]));
00105 
00106           /* First we must not be looking for a argument */
00107           if(found_server_number_flag)
00108             {
00109               /* Error we are expecting an arguement not a TSP option*/
00110               STRACE_WARNING(("Unexpected %s", (*argv)[i]));
00111               ret = FALSE;
00112             }
00113           /* Look for start flag */
00114           else if(!strcmp(TSP_ARG_STREAM_INIT_START, (*argv)[i]))
00115             {
00116               if(!found_stream_stop && !found_stream_start)
00117                 {
00118                   found_stream_start = TRUE;
00119                   /* Ok the user wants a default stream control, put
00120                      the first dummy element */
00121                   if ( 0 == X_glu_argc )
00122                     {
00123                       X_glu_argv[0] = TSP_ARG_DUMMY_PROG_NAME;
00124                       X_glu_argc = 1;
00125                     }
00126                 }
00127               else
00128                 {
00129                   STRACE_WARNING(("Unexpected "TSP_ARG_STREAM_INIT_START));
00130                   ret = FALSE;
00131                 }
00132             }
00133           else if (!strcmp(TSP_ARG_STREAM_INIT_STOP, (*argv)[i]))
00134             {
00135               if(found_stream_start && !found_stream_stop)              
00136                 {
00137                   found_stream_stop = TRUE;
00138                 }
00139               else
00140                 {
00141                   STRACE_WARNING(("Unexpected "TSP_ARG_STREAM_INIT_STOP));
00142                   ret = FALSE;
00143                 }
00144             }
00145           else if (!strcmp(TSP_ARG_SERVER_NUMBER, (*argv)[i]))
00146             {
00147               found_server_number_flag = TRUE;
00148               if(found_stream_start && !found_stream_stop)              
00149                 {
00150                   STRACE_WARNING(("Unexpected "TSP_ARG_SERVER_NUMBER));
00151                   ret = FALSE;
00152                 }
00153             }
00154           else
00155             {
00156               /* Unkown option */
00157               STRACE_WARNING(("Unknown TSP option : '%s'",(*argv)[i] ))
00158               ret = FALSE;
00159             }
00160         }
00161       else /* Not a TSP arg */
00162         {
00163           /* Are we in the TSP command line ? */
00164           if ( found_stream_start && !found_stream_stop )
00165             {
00166               X_glu_argv[X_glu_argc++] = (*argv)[i];
00167             }
00168           else if(found_server_number_flag)
00169             {
00170               /* Found arg for server number option */
00171               found_server_number_flag = FALSE;
00172               X_server_base_number = atoi((*argv)[i]);
00173               STRACE_INFO(("Server base number = %d", X_server_base_number));
00174             }
00175           else
00176             {         
00177               /* Nop, this arg is for the user */
00178               X_argv[final_argc] = (*argv)[i];
00179               final_argc++;
00180             }
00181         }
00182     } /* for */
00183   
00184   /* Check is the stop was found */
00185   
00186   if( found_stream_start && !found_stream_stop )
00187     {
00188       STRACE_WARNING(("A " TSP_ARG_STREAM_INIT_STOP " flag was expected"));
00189       ret = FALSE;
00190     }
00191 
00192   if( found_server_number_flag )
00193     {
00194       STRACE_WARNING(("An argument was expected after " TSP_ARG_SERVER_NUMBER));
00195       ret = FALSE;
00196     }
00197 
00198   /* swap argc and argv values */
00199   *argc = final_argc;
00200   *argv = X_argv;
00201   
00202   /* Display usage */
00203   if(!ret)
00204     {
00205       STRACE_WARNING((TSP_ARG_PROVIDER_USAGE));
00206     }
00207   else
00208     {
00209       if (! X_glu_argc )
00210         {
00211           STRACE_INFO(("No GLU stream init provided on command line"));
00212         }
00213     }
00214 
00215   /* Memorize GLU type */
00216   if (  GLU_SERVER_TYPE_ACTIVE == GLU_get_server_type() )
00217     X_glu_is_active = TRUE;
00218   else
00219     X_glu_is_active = FALSE;
00220 
00221   STRACE_IO(("-->OUT"));
00222   
00223   return ret;
00224 
00225 
00226 }
00227 
00228 int TSP_provider_is_initialized(void)
00229 {
00230   return  X_tsp_provider_init_ok;
00231 }
00232 
00233 int TSP_provider_get_server_base_number(void)
00234 {
00235   return  X_server_base_number;
00236 }
00237 
00238 
00239 void TSP_provider_request_open(const TSP_request_open_t* req_open,
00240                       TSP_answer_open_t* ans_open)
00241 {
00242   GLU_handle_t glu_h;
00243   char* error_info;
00244   int i;
00245         
00246   TSP_LOCK_MUTEX(&X_tsp_request_mutex,);
00247   STRACE_IO(("-->IN"));
00248 
00249 
00250     /* Fortify calls */
00251   
00252     /*Fortify_EnterScope();*/
00253 
00254    ans_open->version_id = UNDEFINED_VERSION_ID;
00255    ans_open->channel_id = UNDEFINED_CHANNEL_ID;
00256    ans_open->status = TSP_STATUS_ERROR_UNKNOWN;
00257    ans_open->status_str = "";
00258 
00259    if(req_open->argv.TSP_argv_t_len)
00260      {
00261        for( i = 0; i< req_open->argv.TSP_argv_t_len ;i++)
00262          {
00263            STRACE_DEBUG(("arg %d is '%s'", i,  req_open->argv.TSP_argv_t_val[i]));
00264          }
00265      }
00266    else
00267      {
00268           STRACE_DEBUG(("No custom args from consumer"));
00269      }
00270 
00271 
00272    /*  get GLU instance. If a stream init is provided, use it, else, use default */   
00273    if( 0 != req_open->argv.TSP_argv_t_len )
00274      {
00275        glu_h = GLU_get_instance(req_open->argv.TSP_argv_t_len, req_open->argv.TSP_argv_t_val, &error_info);
00276      }
00277    else
00278      {
00279        /* use fallback if provided */
00280        glu_h = GLU_get_instance(X_glu_argc, X_glu_argv, &error_info);
00281      }
00282 
00283    
00284    if(glu_h)
00285      {
00286        if(TSP_add_session(&(ans_open->channel_id), glu_h))
00287          {
00288            if(req_open->version_id <= TSP_VERSION)
00289              {
00290                ans_open->version_id = TSP_VERSION;
00291                ans_open->status = TSP_STATUS_OK;
00292              }
00293            else
00294              {
00295                STRACE_ERROR(("TSP version ERROR. Requested=%d Current=%d",req_open->version_id, TSP_VERSION ));
00296                ans_open->status = TSP_STATUS_ERROR_VERSION;
00297              }
00298          }
00299        else
00300          {
00301            STRACE_ERROR(("TSP_add_session failed"));
00302          }
00303      }
00304    else
00305      {
00306        STRACE_INFO(("Unable to get GLU instance"));
00307         ans_open->status = TSP_STATUS_ERROR_SEE_STRING;
00308         ans_open->status_str = error_info;
00309      }
00310 
00311   STRACE_IO(("-->OUT"));
00312 
00313   TSP_UNLOCK_MUTEX(&X_tsp_request_mutex,);      
00314 
00315 } /* End of TSP_provider_request_open */
00316 
00317 
00318 static void TSP_provider_request_close_priv(channel_id_t channel_id)
00319 {
00320   STRACE_IO(("-->IN"));
00321 
00322   TSP_session_destroy_symbols_table_by_channel(channel_id);
00323   TSP_session_close_session_by_channel(channel_id);
00324 
00325   STRACE_IO(("-->OUT"));
00326 }
00327 
00328 void TSP_provider_request_close(const TSP_request_close_t* req_close)
00329 
00330 {
00331   TSP_LOCK_MUTEX(&X_tsp_request_mutex,);
00332 
00333   STRACE_IO(("-->IN"));
00334 
00335   TSP_provider_request_close_priv(req_close->channel_id);
00336 
00337   STRACE_IO(("-->OUT"));
00338 
00339   TSP_UNLOCK_MUTEX(&X_tsp_request_mutex,);
00340 } /* End of TSP_provider_request_close */
00341 
00342 void  TSP_provider_request_information(TSP_request_information_t* req_info, 
00343                               TSP_answer_sample_t* ans_sample)
00344 {
00345   int ret;
00346   TSP_LOCK_MUTEX(&X_tsp_request_mutex,);
00347   
00348   ans_sample->version_id = TSP_VERSION;
00349   ans_sample->channel_id = req_info->channel_id;
00350   ans_sample->status = TSP_STATUS_ERROR_UNKNOWN;
00351   ans_sample->provider_group_number = 0;
00352   ans_sample->base_frequency = GLU_get_base_frequency();
00353   ans_sample->max_client_number = TSP_MAX_CLIENT_NUMBER;
00354   ans_sample->current_client_number = TSP_session_get_nb_session();
00355   ans_sample->max_period = TSP_MAX_PERIOD;
00356   ans_sample->symbols.TSP_sample_symbol_info_list_t_len = 0;
00357   ans_sample->symbols.TSP_sample_symbol_info_list_t_val = 0;  
00358   
00359   if(req_info->version_id <= TSP_VERSION)
00360     {
00361       
00362       ret = TSP_session_get_sample_symbol_info_list_by_channel(req_info->channel_id,                                                 &(ans_sample->symbols));
00363       if(ret)
00364         {
00365           ans_sample->status = TSP_STATUS_OK;
00366         }
00367       else
00368         {
00369           STRACE_ERROR(("Function TSP_session_get_sample_symbol_info_list_by_channel failed"));
00370         }
00371     
00372   }
00373   else
00374   {
00375     STRACE_ERROR(("TSP version ERROR. Requested=%d Current=%d",req_info->version_id, TSP_VERSION ));
00376     ans_sample->status = TSP_STATUS_ERROR_VERSION;
00377   }
00378                 
00379   STRACE_IO(("-->OUT"));
00380 
00381   TSP_UNLOCK_MUTEX(&X_tsp_request_mutex,);
00382 } /* End of TSP_provider_request_information */
00383 
00384 
00385 void TSP_provider_request_sample_free_call(TSP_answer_sample_t* ans_sample)
00386 {
00387   TSP_session_create_symbols_table_by_channel_free_call(ans_sample);
00388 }
00389 
00390 void  TSP_provider_request_sample(TSP_request_sample_t* req_info, 
00391                          TSP_answer_sample_t* ans_sample)
00392 {
00393   TSP_LOCK_MUTEX(&X_tsp_request_mutex,);        
00394   STRACE_IO(("-->IN"));
00395 
00396   ans_sample->version_id = TSP_VERSION;
00397   ans_sample->channel_id = req_info->channel_id;
00398   ans_sample->status = TSP_STATUS_ERROR_UNKNOWN;
00399   ans_sample->provider_group_number = 0;
00400   ans_sample->base_frequency = GLU_get_base_frequency();
00401   ans_sample->max_client_number = TSP_MAX_CLIENT_NUMBER;
00402   ans_sample->current_client_number = TSP_session_get_nb_session();
00403   ans_sample->max_period = TSP_MAX_PERIOD;
00404   ans_sample->symbols.TSP_sample_symbol_info_list_t_len = 0;
00405   ans_sample->symbols.TSP_sample_symbol_info_list_t_val = 0;
00406   
00407   STRACE_INFO(("Consumer No %d asked for %d symbols",req_info->channel_id,req_info->symbols.TSP_sample_symbol_info_list_t_len  ));
00408   
00409   if(req_info->version_id <= TSP_VERSION)
00410     {
00411       if(TSP_session_get_symbols_global_index_by_channel(req_info->channel_id, &(req_info->symbols) ))
00412         {     
00413           /* The datapool will be created here (if it does not already exist) */
00414           if(TSP_session_create_symbols_table_by_channel(req_info, ans_sample)) 
00415             {
00416               ans_sample->status = TSP_STATUS_OK;
00417               GLU_start(); /* FIXME Y.D : Why start now the thread */
00418             }
00419           else  
00420             {
00421               STRACE_ERROR(("Function TSP_session_create_symbols_table_by_channel failed"));
00422             }        
00423         }
00424       else
00425         {
00426           STRACE_WARNING(("Function TSP_session_get_symbols_global_index_by_channel failed"));
00427           ans_sample->status = TSP_STATUS_ERROR_SYMBOLS;
00428         }
00429     }
00430   else
00431     {
00432       STRACE_WARNING(("TSP version ERROR. Requested=%d Current=%d",req_info->version_id, TSP_VERSION ));
00433       ans_sample->status = TSP_STATUS_ERROR_VERSION;
00434     }
00435 
00436 
00437         
00438   STRACE_IO(("-->OUT"));
00439 
00440   TSP_UNLOCK_MUTEX(&X_tsp_request_mutex,);
00441 } /* End of TSP_provider_request_sample */
00442 
00443 void  TSP_provider_request_sample_init(TSP_request_sample_init_t* req_info, 
00444                                        TSP_answer_sample_init_t* ans_sample)
00445 {  
00446   int start_local_thread;
00447   TSP_LOCK_MUTEX(&X_tsp_request_mutex,);    
00448   STRACE_IO(("-->IN"));
00449     
00450   ans_sample->version_id = UNDEFINED_VERSION_ID;
00451   ans_sample->channel_id = req_info->channel_id;
00452   ans_sample->status = TSP_STATUS_ERROR_UNKNOWN;
00453  
00454   if(req_info->version_id <= TSP_VERSION)
00455     {
00456       ans_sample->version_id = req_info->version_id;
00457       /* If the sample server is a lazy pasive server, we need a thread per session*/
00458       start_local_thread = ( X_glu_is_active ? FALSE : TRUE );
00459       
00460       if(TSP_session_create_data_sender_by_channel(req_info->channel_id, start_local_thread))
00461         {
00462           ans_sample->status = TSP_STATUS_OK;
00463         }
00464       else     
00465         {
00466           STRACE_ERROR(("TSP_data_sender_create failed"));
00467         }
00468     
00469       /* send data address to client */
00470       ans_sample->data_address =
00471         (char*)TSP_session_get_data_address_string_by_channel(req_info->channel_id);
00472   
00473       STRACE_DEBUG(("DATA_ADDRESS = '%s'", ans_sample->data_address));
00474     }
00475   else
00476     {
00477       STRACE_ERROR(("TSP version ERROR. Requested=%d Current=%d",req_info->version_id, TSP_VERSION ));
00478       ans_sample->status = TSP_STATUS_ERROR_VERSION;
00479     }
00480 
00481   STRACE_IO(("-->OUT"));
00482 
00483   TSP_UNLOCK_MUTEX(&X_tsp_request_mutex,);
00484 } /* End of TSP_provider_request_sample_init */
00485 
00486 static void TSP_provider_request_sample_destroy_priv(channel_id_t channel_id)
00487 {
00488   int stop_local_thread = ( X_glu_is_active ? FALSE : TRUE );  
00489   if(!TSP_session_destroy_data_sender_by_channel(channel_id, stop_local_thread))
00490     {
00491       STRACE_ERROR(("TSP_session_destroy_data_sender_by_channel failed"));
00492     }
00493 }
00494 
00495 void  TSP_provider_request_sample_destroy(TSP_request_sample_destroy_t* req_info, 
00496                                           TSP_answer_sample_destroy_t* ans_sample)
00497 {
00498   TSP_LOCK_MUTEX(&X_tsp_request_mutex,);
00499 
00500   ans_sample->version_id = req_info->version_id;
00501   ans_sample->channel_id = req_info->channel_id;
00502   ans_sample->status = TSP_STATUS_OK;
00503  
00504   if(req_info->version_id <= TSP_VERSION)
00505     {      
00506       TSP_provider_request_sample_destroy_priv(req_info->channel_id);
00507     }
00508   else
00509     {
00510       STRACE_ERROR(("TSP version ERROR. Requested=%d Current=%d for session %d",
00511                     req_info->version_id, TSP_VERSION,req_info->channel_id  ));
00512       ans_sample->status = TSP_STATUS_ERROR_VERSION;
00513     }
00514 
00515   TSP_UNLOCK_MUTEX(&X_tsp_request_mutex,);
00516 } /* End of  TSP_provider_request_sample_destroy */
00517 
00518 
00519 void* TSP_provider_garbage_collector_thread(void* dummy)
00520 {
00521    channel_id_t channel_id;
00522 
00523    /* Save memory ! */
00524    pthread_detach(pthread_self());
00525 
00526    while(TRUE)
00527      {
00528        while(TSP_session_get_garbage_session(&channel_id))
00529          {
00530            /* Do what some rude consumer should have done itself */
00531            TSP_provider_request_sample_destroy_priv(channel_id);
00532            TSP_provider_request_close_priv(channel_id);
00533            STRACE_INFO(("Session No %d 'garbage-collected'", channel_id));
00534          }
00535        tsp_usleep(TSP_GARBAGE_COLLECTOR_POLL_TIME_US);
00536      }
00537 
00538    /* never reached */
00539    return (void*)NULL;
00540 }
00541 
00542 
00543 int TSP_provider_private_init(int* argc, char** argv[])
00544 {
00545   int ret = TRUE;
00546   int status;
00547   pthread_t thread;
00548   assert(argc);
00549   assert(argv);
00550   
00551   ret = TSP_cmd_line_parser(argc, argv);
00552   if(ret)
00553      {
00554       /* init sessions */
00555       TSP_session_init();
00556 
00557       /* Initialise GLU server */
00558       ret = GLU_init(X_glu_argc, X_glu_argv);
00559 
00560       /* Launch garbage collection for sessions */
00561       status = pthread_create(&thread, NULL, TSP_provider_garbage_collector_thread,  NULL);
00562       TSP_CHECK_THREAD(status, FALSE);
00563       
00564     }
00565 
00566   if(!ret)
00567     {
00568       STRACE_INFO(("TSP init error"));
00569     }
00570 
00571   X_tsp_provider_init_ok = ret;
00572   
00573   return ret;
00574 } /* End of TSP_provider_private_init */
Framework Home Page.

Beware !! TSP wave is coming...