TSP: The Transport Sample Protocol



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

gdisp_consumers.c

Go to the documentation of this file.
00001 
00043 /*
00044  * System includes.
00045  */
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <assert.h>
00049 #include <string.h>
00050 #include <time.h>
00051 #include <sys/time.h>
00052 #include <unistd.h>
00053 
00054 
00055 /*
00056  * GDISP+ includes.
00057  */
00058 #include "gdisp_kernel.h"
00059 #include "gdisp_prototypes.h"
00060 
00061 
00062 
00063 /*
00064  --------------------------------------------------------------------
00065                              STATIC ROUTINES
00066  --------------------------------------------------------------------
00067 */
00068 
00069 
00070 /*
00071  * Function in order to sort providers alphabetically' when inserting
00072  * them into the double-linked list in the kernel.
00073  */
00074 static gint
00075 gdisp_sortProviderByName(gconstpointer data1,
00076                          gconstpointer data2)
00077 {
00078 
00079   Provider_T *provider1 = (Provider_T*)data1,
00080              *provider2 = (Provider_T*)data2;
00081 
00082   return (strcmp(provider1->pUrl->str,provider2->pUrl->str));
00083 
00084 }
00085 
00086 
00087 /*
00088  * Manage a new provider -> read information and add symbols.
00089  */
00090 static int
00091 gdisp_insertProvider ( Kernel_T *kernel,
00092                        gchar    *url )
00093 {
00094 
00095   GString        *messageString    = (GString*)NULL;
00096 
00097   static guint     providerIdentity = 0;
00098   TSP_provider_t  *provider        = NULL;
00099   gint            symbolCpt        = 0;
00100 
00101   Provider_T     *newProvider      = (Provider_T*)NULL;
00102   gint            requestStatus    = 0;
00103 
00104   const TSP_consumer_information_t *providerInfo =
00105                                   (const TSP_consumer_information_t*)NULL;
00106 
00107   /*
00108    * Try to connect to the URL.
00109    */
00110   provider = TSP_consumer_connect_url(url);
00111 
00112   if (provider != (TSP_provider_t*)NULL) {
00113 
00114     /*
00115      * Store all available information for this provider.
00116      */
00117     
00118     /*
00119      * Allocate memory for this new provider.
00120      * Set up its status to 'FROM_SCRATCH'.
00121      */
00122     newProvider = (Provider_T*)g_malloc0(sizeof(Provider_T));
00123     assert(newProvider);
00124     
00125     newProvider->pStatus = GD_FROM_SCRATCH;
00126     
00127     
00128     /*
00129      * Now store the handle, get back the name.
00130      * Set up its status to 'SESSION_CLOSED'.
00131      * Insert it into the kernel provider list.
00132      */
00133     newProvider->pHandle   = provider;
00134     newProvider->pIdentity = providerIdentity++;
00135     newProvider->pUrl      =
00136       g_string_new(TSP_consumer_get_connected_name(newProvider->pHandle));
00137     assert(newProvider->pUrl);
00138     
00139     newProvider->pStatus = GD_SESSION_CLOSED;
00140     
00141     kernel->providerList = g_list_insert_sorted(kernel->providerList,
00142                                                 (gpointer)newProvider,
00143                                                 gdisp_sortProviderByName);
00144     assert(kernel->providerList);
00145     
00146     
00147     /*
00148      * Ask the provider for a new consumer session.
00149      * Set up its status to 'SESSION_OPENED'.
00150      */
00151     requestStatus = TSP_consumer_request_open(newProvider->pHandle,
00152                                               (gint)NULL,
00153                                               (gchar**)NULL);
00154     if (requestStatus == TRUE) {
00155       
00156       /*
00157        * Now the session is opened, get back all available information.
00158        * Keep the current status, since symbols are not requested here.
00159        */
00160       requestStatus = TSP_consumer_request_information(newProvider->pHandle);
00161       if (requestStatus == TRUE) {
00162         
00163         /* Do not free 'providerInfo' structure */
00164         providerInfo = TSP_consumer_get_information(newProvider->pHandle);
00165         assert(providerInfo);
00166 
00167         newProvider->pBaseFrequency       = providerInfo->base_frequency;
00168         newProvider->pMaxPeriod           = providerInfo->max_period;
00169         newProvider->pMaxClientNumber     = providerInfo->max_client_number;
00170         newProvider->pCurrentClientNumber =
00171                                         providerInfo->current_client_number;
00172         newProvider->pSymbolNumber        = providerInfo->symbols.len;
00173 
00174         if (newProvider->pSymbolNumber > 0) {
00175 
00176           newProvider->pSymbolList = (Symbol_T*)
00177             g_malloc0(newProvider->pSymbolNumber * sizeof(Symbol_T));
00178           assert(newProvider->pSymbolList);
00179 
00180         }
00181 
00182         for (symbolCpt=0; symbolCpt<newProvider->pSymbolNumber; symbolCpt++) {
00183 
00184           /*
00185            * I do not duplicate the name, because I want to save up memory.
00186            * So what I do is good if I do not call
00187            * 'TSP_consumer_request_information' again, because this routine
00188            * releases (via "free") the "name" variable.
00189            */
00190           newProvider->pSymbolList[symbolCpt].sInfo.name   =
00191                                   providerInfo->symbols.val[symbolCpt].name;
00192           newProvider->pSymbolList[symbolCpt].sInfo.index  =
00193                                   providerInfo->symbols.val[symbolCpt].index;
00194 
00195           /* Default is : at maximum frequency without offset */
00196           newProvider->pSymbolList[symbolCpt].sInfo.period = 1;
00197           newProvider->pSymbolList[symbolCpt].sInfo.phase  = 0;
00198           newProvider->pSymbolList[symbolCpt].sHasChanged  = FALSE;
00199 
00200         } /* symbolCpt */
00201 
00202         /*
00203          * Session is now opened towards provider.
00204          */
00205         newProvider->pStatus = GD_SESSION_OPENED;
00206 
00207         messageString = g_string_new((gchar*)NULL);
00208         g_string_sprintf(messageString,
00209                          "Session opened on <%s>",
00210                          newProvider->pUrl->str);
00211         kernel->outputFunc(kernel,messageString,GD_MESSAGE);
00212 
00213 
00214       } /* requestStatus == TRUE (TSP_consumer_request_information) */
00215 
00216       else {
00217 
00218         messageString = g_string_new((gchar*)NULL);
00219         g_string_sprintf(messageString,"Cannot get back information from");
00220         kernel->outputFunc(kernel,messageString,GD_ERROR);
00221 
00222         messageString = g_string_new((gchar*)NULL);
00223         g_string_sprintf(messageString,
00224                          "<%s> provider. Session is closed.",
00225                          newProvider->pUrl->str);
00226         kernel->outputFunc(kernel,messageString,GD_ERROR);
00227 
00228       }
00229 
00230     } /* requestStatus == TRUE (TSP_consumer_request_open) */
00231 
00232     else {
00233 
00234       messageString = g_string_new((gchar*)NULL);
00235       g_string_sprintf(messageString,"Cannot open a session towards");
00236       kernel->outputFunc(kernel,messageString,GD_ERROR);
00237 
00238       messageString = g_string_new((gchar*)NULL);
00239       g_string_sprintf(messageString,
00240                        "<%s> provider. Aborting.",
00241                        newProvider->pUrl->str);
00242       kernel->outputFunc(kernel,messageString,GD_ERROR);
00243 
00244     }
00245     
00246   } /* End if available provider */
00247 
00248 
00249   return (provider == NULL ? -1 : 0);
00250 
00251 }
00252 
00253 
00254 /*
00255  * Insert possible providers on a host.
00256  */
00257 static void
00258 gdisp_insertHostProviders ( Kernel_T *kernel,
00259                             Host_T   *host )
00260 {
00261   GString        *messageString    = (GString*)NULL;
00262   gchar          *hostUrl          = (gchar*) NULL;
00263   gint            providerCpt      = 0;
00264   gint            providersFound   = 0;
00265 
00266   /*
00267    * Look for and insert providers on the given host.
00268    */
00269   hostUrl = g_malloc0(strlen(host->hName->str) + 10);
00270   for (providerCpt=0; providerCpt<TSP_MAX_SERVER_NUMBER; providerCpt++) {
00271 
00272     sprintf(hostUrl, "//%s/:%d", host->hName->str, providerCpt);
00273 
00274     if (gdisp_insertProvider(kernel,hostUrl) == 0) {
00275       providersFound++;
00276     }
00277 
00278   }
00279   g_free(hostUrl);
00280 
00281   /*
00282    * Report the number of providers that have been found.
00283    */
00284   messageString = g_string_new((gchar*)NULL);
00285   if (providersFound == 0) {
00286 
00287     g_string_sprintf(messageString,
00288                      "No TSP provider found on host %s.",
00289                      host->hName->str);
00290 
00291   }
00292   else {
00293 
00294     g_string_sprintf(messageString,
00295                      "%d TSP provider(s) found on host %s.",
00296                      providersFound,
00297                      host->hName->str);
00298 
00299   }
00300 
00301   kernel->outputFunc(kernel,messageString,GD_WARNING);
00302 
00303 }
00304 
00305 
00306 /*
00307  --------------------------------------------------------------------
00308                              PUBLIC ROUTINES
00309  --------------------------------------------------------------------
00310 */
00311 
00312 
00313 /*
00314  * GDISP+ is a TSP consumer.
00315  * Initialize here the consummation management.
00316  *  - retreive all available providers on a given URLs/hosts.
00317  *  - ...
00318  */
00319 void
00320 gdisp_consumingInit (Kernel_T *kernel)
00321 {
00322 
00323 #define _HOST_NAME_MAX_LEN_ 256
00324   gchar           localHostName[_HOST_NAME_MAX_LEN_];
00325   gint            hostStatus       = 0;
00326   GList          *hostList         = (GList*)NULL;
00327   GList          *urlList          = (GList*)NULL;
00328   gint            urlsFound        = 0;
00329   GString        *messageString    = (GString*)NULL;
00330 
00331   /*
00332    * Few checking...
00333    */
00334   assert(kernel);
00335 
00336 
00337 
00338   /* --------------------- TSP INITIALISATION ---------------------- */
00339 
00340   /*
00341    * Initialisation for TSP library.
00342    * This function removes the arguments it knows from the argument list,
00343    * leaving anything it does not recognize for GDISP application to parse
00344    * or ignore. 
00345    */
00346   hostStatus = TSP_consumer_init(&kernel->argCounter,
00347                                  &kernel->argTable);
00348 
00349   if (hostStatus == FALSE) {
00350 
00351     messageString = g_string_new((gchar*)NULL);
00352     g_string_sprintf(messageString,"TSP Initialisation failed.");
00353     kernel->outputFunc(kernel,messageString,GD_ERROR);
00354 
00355     return;
00356 
00357   }
00358 
00359 
00360   /* ------------------------ URL LIST ------------------------- */
00361 
00362   /*
00363    * Insert all URLs.
00364    */
00365   urlList = g_list_first(kernel->urlList);
00366   while (urlList != (GList*)NULL) {
00367 
00368     if (gdisp_insertProvider(kernel,
00369                              (gchar*)urlList->data) == 0) {
00370       urlsFound++;
00371     }
00372 
00373     urlList = g_list_next(urlList);
00374 
00375   }
00376 
00377   /* ------------------------ HOST LIST ------------------------- */
00378 
00379   /*
00380    * Get back local host and insert it if no URL found.
00381    */
00382   if (urlsFound == 0) {
00383 
00384     hostStatus    = gethostname(localHostName,_HOST_NAME_MAX_LEN_);
00385     messageString = g_string_new((gchar*)NULL);
00386     
00387     if (hostStatus == -1) {
00388       
00389       g_string_sprintf(messageString,"Local host is UNKNOWN.");
00390       kernel->outputFunc(kernel,messageString,GD_ERROR);
00391       
00392     }
00393     else {
00394       
00395       g_string_sprintf(messageString,
00396                        "Local host is '%s'.",
00397                        localHostName);
00398       kernel->outputFunc(kernel,messageString,GD_MESSAGE);
00399       
00400       gdisp_addHost(kernel,localHostName);
00401 
00402     }
00403   }
00404 
00405   /*
00406    * Insert all hosts.
00407    */
00408   hostList = g_list_first(kernel->hostList);
00409   while (hostList != (GList*)NULL) {
00410 
00411     gdisp_insertHostProviders (kernel,
00412                                (Host_T*)hostList->data);
00413 
00414     hostList = g_list_next(hostList);
00415 
00416   }
00417 }
00418 
00419 
00420 /*
00421  * Return the number of available providers in the provider list.
00422  */
00423 guint
00424 gdisp_getProviderNumber (Kernel_T *kernel)
00425 {
00426 
00427   assert(kernel);
00428 
00429   if (kernel->providerList != (GList*)NULL) {
00430 
00431     return g_list_length(kernel->providerList);
00432 
00433   }
00434   else {
00435 
00436     return 0;
00437 
00438   }
00439 
00440 }
00441 
00442 
00443 /*
00444  * GDISP+ is a TSP consumer.
00445  * Close everything related to consummation.
00446  */
00447 void
00448 gdisp_consumingEnd (Kernel_T *kernel)
00449 {
00450 
00451   GList      *providerItem =      (GList*)NULL;
00452   Provider_T *provider     = (Provider_T*)NULL;
00453 
00454   assert(kernel);
00455 
00456 
00457   /*
00458    * Release all providers.
00459    */
00460   providerItem = g_list_first(kernel->providerList);
00461   while (providerItem != (GList*)NULL) {
00462 
00463     provider = (Provider_T*)providerItem->data;
00464 
00465     g_free(provider->pSymbolList);
00466 
00467     if (provider->pSampleList.len != 0)
00468       free(provider->pSampleList.val);
00469 
00470     g_free(provider);
00471 
00472     providerItem = g_list_next(providerItem);
00473 
00474   }
00475 
00476   g_list_free(kernel->providerList);
00477   kernel->providerList = (GList*)NULL;
00478 
00479 
00480   /*
00481    * Destroy all hosts & URLs.
00482    */
00483   gdisp_destroyHosts(kernel);
00484   gdisp_destroyUrls (kernel);
00485 
00486 
00487   /*
00488    * Leave consumming services.
00489    */
00490   TSP_consumer_end();
00491 
00492 }
00493 
Framework Home Page.

Beware !! TSP wave is coming...