GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

endpoint.c

Go to the documentation of this file.
00001 /** @file adaptor.c
00002  * Main file for the endpoint adaptor.
00003  * 
00004  * Test adaptor to check the GATEndpoint API. Provides a simple file GATEndpointCPI implementation.
00005  * 
00006  * @date $Date: 2004/05/13 09:52:23 $
00007  * 
00008  * @version $Header: /export/cvs-gridlab/GridLabWeb/WorkPackages/wp-1/Doc/C-Reference/endpoint_8c-source.html,v 1.6 2004/05/13 09:52:23 merzky Exp $
00009  *
00010  *  Copyright (C) Kelly Davis
00011  *  This file is part of the GAT Engine.
00012  *  Contributed by Kelly Davis <kdavis@aei.mpg.de>.
00013  *
00014  *  Use, modification and distribution is subject to the Gridlab Software
00015  *  License. (See accompanying file GLlicense.txt or copy at
00016  *  http://www.gridlab.org/GLlicense.txt)
00017  */
00018 
00019 static const char *rcsid = "$Header: /export/cvs-gridlab/GridLabWeb/WorkPackages/wp-1/Doc/C-Reference/endpoint_8c-source.html,v 1.6 2004/05/13 09:52:23 merzky Exp $";
00020 
00021 /* System Header Files */
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 
00026 /* POSIX Header Files */
00027 #include <unistd.h>
00028 #if !defined(WIN32)
00029 #include <arpa/inet.h>
00030 #include <netdb.h>
00031 #endif
00032 #include <sys/types.h>
00033 #include <sys/socket.h>
00034 #include <netinet/in.h>
00035 
00036 /* GAT Header Files */
00037 #include <GATCPI.h>
00038 
00039 /* Adaptor Header Files */
00040 #include "Common.h"
00041 #include "endpoint.h"
00042 
00043 /* Macros */
00044 #define ENDPOINT_ADAPTOR_PORT 1227
00045 #define __countof(x) (sizeof(x)/sizeof(x[0]))
00046 
00047 /* Structures, unions and enums */
00048 
00049 #if defined(WIN32)
00050 /* Adaptor data */
00051 typedef struct GATEndpointCPIAdaptor_Data 
00052 {
00053   WSADATA wsadata;
00054 } GATEndpointCPIAdaptor_Data;
00055 #endif 
00056 
00057 /* Instance data */ 
00058 typedef struct GATEndpointInstance_Data {
00059   int local_socket;
00060   struct sockaddr_in socketAddress;
00061   int server_port;
00062   int client_port;
00063   GATPipeListener listener;
00064   void *callBackData;
00065 } GATEndpointInstance_Data;
00066 
00067 /* Static function prototypes */
00068 static void 
00069 endpoint_adaptor_EndpointCPI_Destroy(void *data);
00070 
00071 /* instance specific functions */
00072 GATResult 
00073 endpoint_adaptor_EndpointCPI_CreateInstance(void *adaptor_data, 
00074   GATEndpointCPI_Instance *data);
00075 
00076 void 
00077 endpoint_adaptor_EndpointCPI_DestroyInstance(void *adaptor_data, 
00078   GATEndpointCPI_Instance *data);
00079 
00080 GATResult 
00081 endpoint_adaptor_EndpointCPI_CloneInstance(void *adaptor_data, 
00082   GATEndpointCPI_Instance const *data, 
00083   GATEndpointCPI_Instance *new_data);
00084 
00085 GATResult 
00086 endpoint_adaptor_EndpointCPI_EqualsInstance(void *adaptor_data, 
00087   GATEndpointCPI_Instance const *lhs, GATEndpointCPI_Instance const *rhs, 
00088   GATBool *isequal);
00089 
00090 /* Serialisation functions */
00091 static GATResult 
00092 endpoint_adaptor_EndpointCPI_Serialise(void *data, 
00093   GATEndpointCPI_Instance const *instance_data, GATObject stream,
00094   GATBool clear_dirty);
00095   
00096 static GATResult 
00097 endpoint_adaptor_EndpointCPI_DeSerialise(void *data, 
00098   GATObject stream, GATEndpointCPI_Instance *instance_data);
00099 
00100 /* CPI specific API */
00101 static GATResult 
00102 endpoint_adaptor_EndpointCPI_Connect(void *, GATEndpointCPI_Instance const *, 
00103   GATPipe *);
00104   
00105 static GATResult 
00106 endpoint_adaptor_EndpointCPI_Listen(void *, GATEndpointCPI_Instance const *, 
00107   GATPipe *);
00108   
00109 static GATResult 
00110 endpoint_adaptor_EndpointCPI_AddGATPipeListener(void *, GATEndpointCPI_Instance const *, 
00111   GATPipeListener, void *);
00112             
00113 /* Execute a GATEndpoint get_metrics operation */
00114 static GATResult 
00115 endpoint_adaptor_EndpointCPI_GetMetrics(void *data, 
00116   GATEndpointCPI_Instance const *instance_data, GATList_GATMetric *metrics);
00117 
00118 /* Execute a GATEndpoint get_metric_event operation */
00119 static GATResult 
00120 endpoint_adaptor_EndpointCPI_GetMetricEvent(void *data, 
00121   GATEndpointCPI_Instance const *instance_data, GATMetric metric, 
00122     GATMetricEvent *event);
00123     
00124 /* local helper functions */
00125 static GATResult 
00126 endpoint_adaptor_FireConnect(GATContext context, 
00127   GATMonitorable_Impl monitorable, GATObject_const source, char const *name);
00128   
00129 static GATResult 
00130 endpoint_adaptor_FireListen(GATContext context, 
00131   GATMonitorable_Impl monitorable, GATObject_const source, char const *name);
00132   
00133 static GATResult 
00134 endpoint_adaptor_FireAddGATPipeListener(GATMonitorable_Impl monitorable, 
00135   GATObject_const source, char const *name);
00136 
00137 #if defined(WIN32)
00138 /* Adaptor data */
00139 static GATEndpointCPIAdaptor_Data *GATEndpointCPIAdaptor_Data_Create();
00140 static void GATEndpointCPIAdaptor_Data_Destroy(GATEndpointCPIAdaptor_Data *);
00141 #endif // defined(WIN32)
00142 
00143 /* File scope variables */
00144 static GATStaticMetric metric_data[] = {
00145   /* endpoint.connect event */
00146   { 
00147     "endpoint.connect",             /* name */
00148     GATMeasurementType_EventLike,   /* type */
00149     GATType_String,                 /* data type */
00150     "",                             /* unit */
00151     0,                              /* parameter count */
00152     0                               /* parameters */
00153   },
00154   /* endpoint.listen event */
00155   { 
00156     "endpoint.listen",              /* name */
00157     GATMeasurementType_EventLike,   /* type */
00158     GATType_String,                 /* data type */
00159     "",                             /* unit */
00160     0,                              /* parameter count */
00161     0                               /* parameters */
00162   },
00163   /* endpoint.addgatpipelistener event */
00164   { 
00165     "endpoint.addgatpipelistener",  /* name */
00166     GATMeasurementType_EventLike,   /* type */
00167     GATType_String,                 /* data type */
00168     "",                             /* unit */
00169     0,                              /* parameter count */
00170     0                               /* parameters */
00171   }
00172 };
00173 
00174 /* symbolic constants for the metric positions inside the metric_data array */
00175 #define METRIC_FILESTREAM_CONNECT            0
00176 #define METRIC_FILESTREAM_LISTEN             1
00177 #define METRIC_FILESTREAM_ADDGATPIPELISTENER 2
00178 
00179 
00180 /* External functions */
00181 
00182 /** endpoint_adaptor_register
00183  *  Registers all CPIs this adaptor provides.
00184  *  This function is invoked by the loader in the GATEngine when
00185  *  an instance of this adaptor is loaded.  Each instance has its
00186  *  own private configuration table.
00187  *
00188  *  For every CPI provided the adapter has to hand all the corresponding 
00189  *  function pointers to the engine to allow to be called back under certain
00190  *  circumstances. Additionally the adaptor may allocate some private data for
00191  *  every loaded instance. This data is handed back to the adaptor as the first
00192  *  parameter to each of the subsequently called functions.
00193  *
00194  *  @param registry The registry the adaptor should register its CPIs with.
00195  *  @param system_config The system configuration table.
00196  *  @param instance_config The configuration table for this instance.
00197  *  @param token An arbitrary token used by the loader to identify this adaptor 
00198  *        instance
00199  *
00200  *  @return An error code.
00201  */
00202 GATResult 
00203 endpoint_adaptor_register_endpoint(GATContext error_context, 
00204   GATRegistry registry, GATTable_const system_config, 
00205   GATTable_const instance_config, void *token)
00206 {
00207   GAT_USES_STATUS(error_context, "endpoint_adaptor_register_endpoint");
00208   
00209   GATEndpointCPI cpi = NULL;
00210   GATEndpointCPI_Data cpidata;
00211 
00212 #if defined(WIN32)
00213   GATEndpointCPIAdaptor_Data *adaptor_data = GATEndpointCPIAdaptor_Data_Create();
00214 #endif
00215 
00216   GAT_UNUSED_PARAMETER(system_config);
00217   GAT_UNUSED_PARAMETER(instance_config);
00218   
00219   memset(&cpidata, 0, sizeof(GATEndpointCPI_Data));
00220     
00221   /*
00222    *  provide the appropriate callback functions
00223    */
00224 #if defined(WIN32)
00225   if (NULL != adaptor_data)
00226 #endif
00227   {
00228     /* adaptor instance data */
00229 #if defined(WIN32)
00230     cpidata.data = adaptor_data;
00231 #else
00232     cpidata.data = NULL;
00233 #endif
00234     cpidata.destroy = endpoint_adaptor_EndpointCPI_Destroy;
00235     
00236     /*  Lifetime control and basic GATObject functionality support for every
00237     *  object instance created by the client.
00238     */
00239     cpidata.create_instance = endpoint_adaptor_EndpointCPI_CreateInstance;
00240     cpidata.destroy_instance = endpoint_adaptor_EndpointCPI_DestroyInstance;
00241     cpidata.clone_instance = endpoint_adaptor_EndpointCPI_CloneInstance;
00242     cpidata.equals_instance = endpoint_adaptor_EndpointCPI_EqualsInstance;
00243     
00244     /* serialisation support functions */
00245     cpidata.serialise = endpoint_adaptor_EndpointCPI_Serialise;
00246     cpidata.deserialise = endpoint_adaptor_EndpointCPI_DeSerialise;
00247 
00248     /* CPI support */
00249     cpidata.connect = endpoint_adaptor_EndpointCPI_Connect;
00250     cpidata.listen = endpoint_adaptor_EndpointCPI_Listen;
00251     cpidata.addPipeListener = endpoint_adaptor_EndpointCPI_AddGATPipeListener;
00252     
00253     /* monitoring support */
00254     cpidata.get_metrics = endpoint_adaptor_EndpointCPI_GetMetrics;
00255     cpidata.get_metric_event = endpoint_adaptor_EndpointCPI_GetMetricEvent;
00256 
00257     /* Create a GATEndpointCPI object. */
00258     cpi = GATEndpointCPI_Create(GATFILESTREAMCPI_VERSION, &cpidata);
00259     if(NULL != cpi)
00260     {
00261       /* Need to pass preferences to allow matching
00262       * of a user's preferences with what this adaptor does.
00263       */
00264       GATPreferences preferences = GATPreferences_Create();
00265       if(NULL != preferences)
00266       {
00267         GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Name", 
00268           "endpoint_adaptor"));
00269         GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Security", "none"));
00270         GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Local", "true"));
00271         
00272         GAT_CREATE_STATUS(GATRegistry_AddGATEndpointCPI(registry, cpi, token, 
00273           preferences));
00274         
00275         GATPreferences_Destroy(&preferences);
00276       }
00277     }
00278   }
00279 #if defined(WIN32)
00280   else
00281   {
00282     GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00283   }
00284 #endif
00285     
00286   if (GAT_FAILED(GAT_CURRENT_STATUS()))
00287   {
00288 #if defined(WIN32)
00289     if (NULL == cpi)
00290     {
00291       GATEndpointCPIAdaptor_Data_Destroy(adaptor_data);
00292     }
00293     else
00294 #endif
00295     {
00296       GATEndpointCPI_Destroy(&cpi);
00297     }
00298   }
00299   return GAT_RETURN_STATUS();
00300 }
00301 
00302 /* Local functions */
00303 
00304 /** endpoint_adaptor_EndpointCPI_Destroy
00305  *  Destroy the adaptor-provided data object on GATEndpointCPI destruction.
00306  *  When the GATEndpointCPI object created in this adaptor's _register
00307  *  function is destroyed, this function is invoked to allow the
00308  *  adaptor to cleanup.
00309  *
00310  *  @param data Adaptor-provided data object.
00311  */
00312 static void 
00313 endpoint_adaptor_EndpointCPI_Destroy(void *data)
00314 {
00315 #if defined(WIN32)
00316   GATEndpointCPIAdaptor_Data_Destroy((GATEndpointCPIAdaptor_Data *) data);
00317 #endif
00318 }
00319 
00320 /** endpoint_adaptor_EndpointCPI_CreateInstance
00321  *  Create a new CPI object instance.
00322  *  Adaptor implementation of create instance capability.
00323  *
00324  * @param adaptor_data Adaptor-provided data object.
00325  * @param data The pointer to the data structure containing at least 
00326  *        the constructor provided data items and a member instance_data, which 
00327  *        may be used by the adaptor to store CPI instance specific data.
00328  * 
00329  * @return An error code.
00330  */
00331 GATResult 
00332 endpoint_adaptor_EndpointCPI_CreateInstance(void *adaptor_data, 
00333   GATEndpointCPI_Instance *data)
00334 {
00335   GAT_UNUSED_PARAMETER(adaptor_data);
00336   if (NULL != data)
00337   {
00338     GAT_USES_STATUS(data->context, 
00339       "endpoint_adaptor_EndpointCPI_CreateInstance");
00340     if (NULL != data)
00341     {
00342       GATEndpointInstance_Data *gatEndpointInstance_Data = 
00343         (GATEndpointInstance_Data *) malloc(sizeof(GATEndpointInstance_Data));
00344 
00345       if (NULL != gatEndpointInstance_Data)
00346       {
00347         memset(gatEndpointInstance_Data, 0, sizeof(GATEndpointInstance_Data));
00348 
00349         gatEndpointInstance_Data->listener = NULL;
00350         gatEndpointInstance_Data->callBackData = NULL;
00351         gatEndpointInstance_Data->local_socket = socket(AF_INET, SOCK_STREAM, 0);
00352         if (0 <= gatEndpointInstance_Data->local_socket)
00353         {
00354           int bindResult;
00355         
00356           gatEndpointInstance_Data->socketAddress.sin_family = AF_INET;
00357           gatEndpointInstance_Data->socketAddress.sin_addr.s_addr = 
00358             htonl(INADDR_ANY);
00359           gatEndpointInstance_Data->socketAddress.sin_port = 
00360             htons(ENDPOINT_ADAPTOR_PORT);
00361           gatEndpointInstance_Data->server_port = ENDPOINT_ADAPTOR_PORT;
00362           
00363           bindResult = bind(gatEndpointInstance_Data->local_socket, 
00364             (struct sockaddr *)&gatEndpointInstance_Data->socketAddress, 
00365             sizeof(struct sockaddr_in));
00366           if (0 <= bindResult)
00367           {
00368             data->instance_data = (void *) gatEndpointInstance_Data;
00369           }
00370           else
00371           {
00372             GAT_CREATE_STATUS(GAT_FAIL);
00373             close(gatEndpointInstance_Data->local_socket);
00374             free(gatEndpointInstance_Data);
00375           }
00376         }
00377         else
00378         {
00379           GAT_CREATE_STATUS(GAT_FAIL);
00380           free(gatEndpointInstance_Data); 
00381         }
00382       }
00383       else
00384       {
00385         GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00386       }
00387     }
00388     
00389     return GAT_RETURN_STATUS();
00390   }
00391   return GAT_INVALID_HANDLE;
00392 }
00393 
00394 /** endpoint_adaptor_EndpointCPI_DestroyInstance
00395  *  Destroy a CPI object instance.
00396  *  Adaptor implementation of destroy instance capability.
00397  *
00398  * @param data Adaptor-provided data object.
00399  * @param instance_data The instance data of the CPI object to destroy.
00400  */
00401 void
00402 endpoint_adaptor_EndpointCPI_DestroyInstance(void *adaptor_data, 
00403   GATEndpointCPI_Instance *data)
00404 {
00405   GAT_UNUSED_PARAMETER(adaptor_data);
00406   
00407   if( (NULL != data) && (NULL != data->instance_data) )
00408   {
00409     GATEndpointInstance_Data *gatEndpointInstance_Data;
00410     
00411     gatEndpointInstance_Data = (GATEndpointInstance_Data *) data->instance_data;
00412     
00413     close( gatEndpointInstance_Data->local_socket );
00414     free( gatEndpointInstance_Data );
00415   }
00416 }
00417 
00418 /** endpoint_adaptor_EndpointCPI_CloneInstance
00419  *  Clone a CPI object instance.
00420  *  Adaptor implementation of the clone instance capability.
00421  *
00422  * @param data Adaptor-provided data object.
00423  * @param instance_data The instance data of this CPI object
00424  * @param new_instance_data The pointer to the variable, where the instance 
00425  *      data of the cloned CPI object is to be returned to.
00426  * 
00427  * @return An error code.
00428  */
00429 GATResult 
00430 endpoint_adaptor_EndpointCPI_CloneInstance(void *adaptor_data, 
00431   GATEndpointCPI_Instance const *instance_data, 
00432   GATEndpointCPI_Instance *new_instance_data)
00433 {
00434   GAT_UNUSED_PARAMETER(adaptor_data);
00435   if (NULL != instance_data)
00436   {
00437     GAT_USES_STATUS(instance_data->context, 
00438       "endpoint_adaptor_EndpointCPI_CloneInstance");
00439     
00440     if (NULL != new_instance_data)
00441     {
00442       if (NULL != instance_data->instance_data)
00443       {
00444         GATEndpointInstance_Data *newInstance_Data = 
00445           (GATEndpointInstance_Data *)malloc(sizeof(GATEndpointInstance_Data));
00446           
00447         if (NULL != newInstance_Data)
00448         {
00449           struct GATEndpointInstance_Data *oldInstance_Data = 
00450             (GATEndpointInstance_Data *) instance_data->instance_data;
00451       
00452           memset(newInstance_Data, 0, sizeof(GATEndpointInstance_Data));
00453             
00454           newInstance_Data->listener = oldInstance_Data->listener;
00455           newInstance_Data->local_socket = oldInstance_Data->local_socket;
00456           newInstance_Data->callBackData = oldInstance_Data->callBackData;
00457 
00458           memcpy (&newInstance_Data->socketAddress,
00459             &oldInstance_Data->socketAddress, sizeof(struct sockaddr_in));
00460       
00461           new_instance_data->instance_data = newInstance_Data;
00462         }
00463         else
00464         {
00465           GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00466         }
00467       }
00468       else
00469       {
00470         new_instance_data->instance_data = NULL;
00471         GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00472       }
00473     }
00474     else
00475     {
00476       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00477     }
00478     
00479     return GAT_RETURN_STATUS();
00480   }
00481   return GAT_INVALID_HANDLE;
00482 }
00483 
00484 /** endpoint_adaptor_EndpointCPI_EqualsInstance
00485  *  Clone a CPI object instance.
00486  *  Adaptor implementation of the clone instance capability.
00487  *
00488  * @param data Adaptor-provided data object.
00489  * @param lhs The instance data of the left CPI object.
00490  * @param lhs The instance data of the right CPI object.
00491  * @param isequal The pointer to the variable, where the result is to be 
00492  *        returned to.
00493  *
00494  * @return An error code.
00495  */
00496 GATResult 
00497 endpoint_adaptor_EndpointCPI_EqualsInstance(void *data, 
00498   GATEndpointCPI_Instance const *lhs, GATEndpointCPI_Instance const *rhs, 
00499   GATBool *isequal)
00500 {
00501   GATResult retval = GAT_INVALID_HANDLE;
00502   
00503   GAT_UNUSED_PARAMETER(data);
00504   
00505   if ( (NULL != isequal) && (NULL != lhs) && (NULL != rhs) )
00506   {
00507     GATEndpointInstance_Data *lhsGATEndpointInstance_Data;
00508     GATEndpointInstance_Data *rhsGATEndpointInstance_Data;
00509     
00510     lhsGATEndpointInstance_Data = (GATEndpointInstance_Data *) lhs->instance_data;
00511     rhsGATEndpointInstance_Data = (GATEndpointInstance_Data *) rhs->instance_data;
00512     
00513     if( (NULL != lhsGATEndpointInstance_Data) && (NULL != rhsGATEndpointInstance_Data) )
00514     {
00515       *isequal = GATFalse;
00516       retval = GAT_SUCCESS;
00517       if (lhsGATEndpointInstance_Data->local_socket == 
00518           rhsGATEndpointInstance_Data->local_socket)
00519       {
00520         *isequal = GATFalse;
00521         retval = GAT_SUCCESS;
00522         if (lhsGATEndpointInstance_Data->socketAddress.sin_port == 
00523             rhsGATEndpointInstance_Data->socketAddress.sin_port)
00524         {
00525           *isequal = GATFalse;
00526           retval = GAT_SUCCESS;
00527           if (lhsGATEndpointInstance_Data->socketAddress.sin_family == 
00528               rhsGATEndpointInstance_Data->socketAddress.sin_family)
00529           {
00530             *isequal = GATFalse;
00531             retval = GAT_SUCCESS;
00532             if (lhsGATEndpointInstance_Data->listener == 
00533                 rhsGATEndpointInstance_Data->listener)
00534             {
00535               *isequal = GATFalse;
00536               retval = GAT_SUCCESS;
00537               if (lhsGATEndpointInstance_Data->callBackData == 
00538                   rhsGATEndpointInstance_Data->callBackData)
00539               {
00540                 *isequal = GATTrue;
00541                 retval = GAT_SUCCESS;
00542               }
00543             }
00544           }
00545         }
00546       }
00547     }
00548     else
00549     {
00550       *isequal = GATFalse;
00551       retval = GAT_SUCCESS;
00552       if (NULL == lhsGATEndpointInstance_Data && 
00553          NULL == rhsGATEndpointInstance_Data)
00554       {
00555         *isequal = GATTrue;
00556         retval = GAT_SUCCESS;
00557       }
00558     }
00559   }
00560   return retval;
00561 }
00562 
00563 
00564 /* Serialization functions */
00565 
00566 /** endpoint_adaptor_EndpointCPI_Serialise
00567  *
00568  *  The function endpoint_adaptor_EndpointCPI_Serialise is called by the 
00569  *  GAT engine, whenever the client requested a Serialise operation on the 
00570  *  corresponding GATendpoint object. The function should serialise into the 
00571  *  given stream all the instance specific data of the object.
00572  *
00573  *  @param cpi The GATEndpoint CPI
00574  *  @param data Adaptor-provided data object.
00575  *  @param instance_data The instance data of this CPI object.
00576  *  @param stream The GATSTream object to use for serialisation of the instance data.
00577  *  @param clear_dirty This flag defines, whether the dirty flag of saved dependent objects is to be cleared.
00578  *
00579  *  @return An error code
00580  */
00581 static GATResult 
00582 endpoint_adaptor_EndpointCPI_Serialise(void *data, 
00583   GATEndpointCPI_Instance const *instance_data, GATObject stream,
00584   GATBool clear_dirty)
00585 {
00586   GAT_UNUSED_PARAMETER(data);
00587   GAT_UNUSED_PARAMETER(stream);
00588   if (NULL != instance_data)
00589   {
00590     GAT_USES_STATUS(instance_data->context, 
00591       "endpoint_adaptor_EndpointCPI_Serialise");
00592 
00593     /* this adaptor has to serialise the server port used (the nodename is 
00594        serialised by the engine) */
00595     GATEndpointInstance_Data *gatEndpointInstance_Data = 
00596       (GATEndpointInstance_Data *)instance_data->instance_data;
00597 
00598     GAT_CREATE_STATUS(GATuint32_Serialise(gatEndpointInstance_Data->server_port, 
00599       stream));
00600 
00601     return GAT_RETURN_STATUS();
00602   }
00603   return GAT_INVALID_HANDLE;
00604 }
00605 
00606 /** endpoint_adaptor_EndpointCPI_DeSerialise
00607  *
00608  *  The function endpoint_adaptor_EndpointCPI_DeSerialise is called by 
00609  *  the GATEngine, whenever the client requested a DeSerialise operation for
00610  *  a GATEndpoint object. The function should deserialise all the instance 
00611  *  specific data of the object from the given stream.
00612  *
00613  *  @param cpi The GATEndpoint CPI
00614  *  @param data Adaptor-provided data object.
00615  *  @param stream The GATSTream object to use for de-serialisation of the 
00616  *        instance data.
00617  *  @param instance_data The instance data of this CPI object.
00618  *
00619  *  @return An error code
00620  */
00621 static GATResult 
00622 endpoint_adaptor_EndpointCPI_DeSerialise(void *data, 
00623   GATObject stream, GATEndpointCPI_Instance *instance_data)
00624 {
00625   GAT_UNUSED_PARAMETER(data);
00626   if (NULL != instance_data)
00627   {
00628     GAT_USES_STATUS(instance_data->context, 
00629       "endpoint_adaptor_EndpointCPI_DeSerialise");
00630     
00631     GATEndpointInstance_Data *gatEndpointInstance_Data = 
00632       (GATEndpointInstance_Data *) malloc(sizeof(GATEndpointInstance_Data));
00633     if (NULL != gatEndpointInstance_Data)
00634     {
00635       GATuint32 port = 0;
00636  
00637       memset(gatEndpointInstance_Data, 0, sizeof(GATEndpointInstance_Data));
00638       GAT_CREATE_STATUS(GATuint32_DeSerialise(stream, &port));
00639       if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00640       {
00641         gatEndpointInstance_Data->server_port = port;
00642         gatEndpointInstance_Data->local_socket = socket(AF_INET, SOCK_STREAM, 0);
00643         if (0 <= gatEndpointInstance_Data->local_socket)
00644         {
00645           int bindResult;
00646         
00647           gatEndpointInstance_Data->socketAddress.sin_family = AF_INET;
00648           gatEndpointInstance_Data->socketAddress.sin_addr.s_addr = 
00649             htonl(INADDR_ANY);
00650           gatEndpointInstance_Data->socketAddress.sin_port = 0;
00651           
00652           bindResult = bind(gatEndpointInstance_Data->local_socket, 
00653             (struct sockaddr *)&gatEndpointInstance_Data->socketAddress, 
00654             sizeof(struct sockaddr_in));
00655           if (0 <= bindResult)
00656           {
00657             /* get the port number back (needed later on) */
00658             struct sockaddr_in client_addr;
00659             int len = sizeof(struct sockaddr_in);
00660             
00661             memset(&client_addr, 0, sizeof(struct sockaddr_in));
00662             getsockname(gatEndpointInstance_Data->local_socket, 
00663               (struct sockaddr *)&client_addr, &len);
00664             gatEndpointInstance_Data->client_port = ntohs(client_addr.sin_port);
00665             instance_data->instance_data = gatEndpointInstance_Data;
00666           }
00667           else
00668           {
00669             GAT_CREATE_STATUS(GAT_FAIL);
00670             close(gatEndpointInstance_Data->local_socket);
00671             free(gatEndpointInstance_Data);
00672           }
00673         }
00674         else
00675         {
00676           GAT_CREATE_STATUS(GAT_FAIL);
00677           free(gatEndpointInstance_Data); 
00678           instance_data->instance_data = NULL;
00679         }
00680       }
00681       else
00682       {
00683         free(gatEndpointInstance_Data);
00684         instance_data->instance_data = NULL;
00685       }
00686     }
00687     else
00688     {
00689       GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00690     }
00691     
00692     return GAT_RETURN_STATUS();
00693   }
00694   
00695   return GAT_INVALID_HANDLE;
00696 }
00697 
00698 /* CPI support */
00699 
00700 /** endpoint_adaptor_EndpointCPI_Connect
00701  * This function connects to this endpoint's server instance.
00702  * This is the adaptor implementation of the connect capability.
00703  *
00704  * @param data Adaptor-provided data object.
00705  * @param instance_data Instance data of the CPI object
00706  * @param peep The created GATPipe
00707  * @return An error code.
00708  */
00709 static GATResult 
00710 endpoint_adaptor_EndpointCPI_Connect(void *data, 
00711   GATEndpointCPI_Instance const *instance_data, GATPipe *peep)
00712 {
00713   GAT_UNUSED_PARAMETER(data);
00714   if (NULL != instance_data)
00715   {
00716     GAT_USES_STATUS(instance_data->context, 
00717       "endpoint_adaptor_EndpointCPI_Connect");
00718     
00719     if (NULL != instance_data && NULL != peep)
00720     {
00721       GATPreferences preferences;
00722       
00723       preferences = GATPreferences_Create();
00724       if (NULL != preferences)
00725       {
00726         GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Name", 
00727           "pipe_adaptor"));
00728         GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Security", "none"));
00729         GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Local", "true"));
00730 
00731         if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00732         {
00733           GATEndpointInstance_Data *gatEndpointInstance_Data = 
00734             (GATEndpointInstance_Data *)instance_data->instance_data;
00735             
00736           if (NULL != gatEndpointInstance_Data && 
00737               0 != gatEndpointInstance_Data->local_socket)
00738           {
00739             struct sockaddr_in serverAddress;
00740             struct hostent *hostend = NULL;
00741             
00742             memset(&serverAddress, 0, sizeof(serverAddress));
00743             serverAddress.sin_family = AF_INET;
00744             hostend = gethostbyname(instance_data->nodename);
00745             serverAddress.sin_addr = *((struct in_addr *)hostend->h_addr);
00746             serverAddress.sin_port = htons(gatEndpointInstance_Data->server_port);
00747 
00748             if (INADDR_NONE != serverAddress.sin_addr.s_addr)
00749             {
00750               int connectReturn = connect(gatEndpointInstance_Data->local_socket, 
00751                 (struct sockaddr *) &serverAddress, sizeof(serverAddress));
00752 
00753               if (0 <= connectReturn)
00754               {
00755                 GATPipe newGATPipe = NULL;
00756                 GATPipeAdaptorInfo gatPipeAdaptorInfo;
00757                 
00758                 gatPipeAdaptorInfo.isClientInfo = GATTrue;
00759                 gatPipeAdaptorInfo.clientSocket = gatEndpointInstance_Data->local_socket;
00760                 
00761                 newGATPipe = GATPipe_Create(instance_data->context, preferences, 
00762                   &gatPipeAdaptorInfo);
00763 
00764                 if (NULL != newGATPipe)
00765                 {
00766                   *peep = newGATPipe;
00767                   GAT_CREATE_STATUS(endpoint_adaptor_FireConnect(
00768                     instance_data->context, instance_data->monitorable, 
00769                     instance_data->source, "connect"));
00770                 }
00771                 else
00772                 {
00773                   GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00774                 }
00775               }
00776               else
00777               {
00778                 GAT_CREATE_STATUS(GAT_FAIL);
00779               }
00780             }
00781           }
00782           else
00783           {
00784             GAT_CREATE_STATUS(GAT_FAIL);
00785           }
00786         }
00787         GATPreferences_Destroy(&preferences);
00788       }
00789       else
00790       {
00791         GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00792       }    
00793     }
00794     return GAT_RETURN_STATUS();
00795   }
00796   return GAT_INVALID_HANDLE;
00797 }
00798 
00799 /** endpoint_adaptor_EndpointCPI_Listen
00800  * This function listens for connections to this endpoint's server.
00801  * This is the adaptor implementation of the listen capability.
00802  *
00803  * @param data Adaptor-provided data object.
00804  * @param instance_data Instance data of the CPI object
00805  * @param peep The created GATPipe
00806  * @return An error code. 
00807  */
00808 static 
00809 GATResult endpoint_adaptor_EndpointCPI_Listen(void *data, 
00810   GATEndpointCPI_Instance const *instance_data, GATPipe *peep)
00811 {
00812   GAT_USES_STATUS(instance_data->context, "endpoint_adaptor_EndpointCPI_Listen");
00813   GAT_UNUSED_PARAMETER(data);
00814   
00815   if (NULL != instance_data && NULL != peep)
00816   {
00817     if (NULL != instance_data->instance_data)
00818     {
00819       int listenReturn = -1;
00820       GATEndpointInstance_Data *gatEndpointInstance_Data =
00821         (GATEndpointInstance_Data *) instance_data->instance_data;
00822     
00823       listenReturn = listen (gatEndpointInstance_Data->local_socket, 1);
00824       if (0 == listenReturn)
00825       {
00826         int length = sizeof(gatEndpointInstance_Data->socketAddress);
00827         int clientSocket = 0;
00828         
00829         clientSocket = accept(gatEndpointInstance_Data->local_socket, 
00830           (struct sockaddr *) &(gatEndpointInstance_Data->socketAddress), 
00831           &length);
00832           
00833         if (-1 != clientSocket)
00834         {
00835           GATPreferences preferences = GATPreferences_Create();
00836           if (NULL != preferences)
00837           {
00838             GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Name", 
00839               "pipe_adaptor"));
00840             GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Security", "none"));
00841             GAT_CREATE_STATUS(GATPreferences_Add(preferences, "Local", "true"));
00842 
00843             if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00844             {
00845               GATPipe newGATPipe;
00846               GATPipeAdaptorInfo gatPipeAdaptorInfo;
00847             
00848               gatPipeAdaptorInfo.isClientInfo = GATFalse;
00849               gatPipeAdaptorInfo.clientSocket = clientSocket;            
00850             
00851               newGATPipe = GATPipe_Create (instance_data->context, preferences, 
00852                 (void *) &gatPipeAdaptorInfo);
00853               if (NULL != newGATPipe)
00854               {
00855                 *peep = newGATPipe;
00856 
00857                 GAT_CREATE_STATUS(endpoint_adaptor_FireListen(
00858                   instance_data->context, 
00859                   instance_data->monitorable, instance_data->source, "listen"));
00860                 if (NULL != gatEndpointInstance_Data->listener)
00861                 {
00862                   /* Temporary resting place for this code!!! */
00863                   GAT_CREATE_STATUS(gatEndpointInstance_Data->listener(
00864                     gatEndpointInstance_Data->callBackData, newGATPipe));
00865                 }
00866               }
00867               else
00868               {
00869                 GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00870               }
00871             }
00872           
00873             GATPreferences_Destroy(&preferences);
00874           }
00875           else
00876           {
00877             GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00878           }
00879         }
00880       }
00881       else
00882       {
00883         GAT_CREATE_STATUS(GAT_FAIL);
00884       }
00885     }
00886     else
00887     {
00888       GAT_CREATE_STATUS(GAT_INVALID_STATE);
00889     }
00890   }
00891   else
00892   {
00893     GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00894   }
00895   
00896   return GAT_RETURN_STATUS();
00897 }
00898 
00899 /** endpoint_adaptor_EndpointCPI_AddGATPipeListener
00900  * This function registers the passed listener to listen for the connection
00901  * of clients to this endpoint server. This is the adaptor implementation
00902  * of the AddGATPipeListener functionality.
00903  *
00904  * @param data Adaptor-provided data object.
00905  * @param instance_data Instance data of the CPI object
00906  * @param peepListener GATPipeListener object which handles incoming connections
00907  * @param listenerData Call back data
00908  * @return An error code.
00909  */  
00910 static GATResult 
00911 endpoint_adaptor_EndpointCPI_AddGATPipeListener(void *data, 
00912   GATEndpointCPI_Instance const *instance_data, GATPipeListener listener, 
00913   void *callBackData)
00914 {
00915   GATResult retval = GAT_INVALID_PARAMETER;
00916   
00917   GAT_UNUSED_PARAMETER(data);
00918   
00919   if( (NULL != instance_data) && (NULL != listener) )
00920   {
00921     if( NULL != instance_data->instance_data )
00922     {
00923       GATEndpointInstance_Data *gatEndpointInstance_Data;
00924       gatEndpointInstance_Data = (GATEndpointInstance_Data *) instance_data->instance_data;
00925     
00926       gatEndpointInstance_Data->listener = listener;
00927       gatEndpointInstance_Data->callBackData = callBackData;
00928     
00929       retval = GAT_SUCCESS;
00930     
00931       endpoint_adaptor_FireAddGATPipeListener(instance_data->monitorable, 
00932         instance_data->source, "addgatpipelistener");
00933     }
00934     else
00935     {
00936       retval = GAT_INVALID_STATE;
00937     }
00938   }
00939   
00940   return retval;
00941 }
00942 
00943 
00944 /* Monitoring support */ 
00945 
00946 /** endpoint_adaptor_EndpointCPI_GetMetrics
00947  *
00948  *  The function endpoint_adaptor_EndpointCPI_GetMetrics should return a 
00949  *  list of GATMetric objects supported by this adaptor. I.e. the adaptor is 
00950  *  capable to fire GATMetricEvents for the returned metrics. This list should 
00951  *  include all the supported metrics, event like and continuous ones.
00952  *
00953  *  @param data Adaptor-provided data object.
00954  *  @param instance_data Instance data for the CPI provider object.
00955  *  @param metrics The pointer to the variable, which receives the returned 
00956  *        list of metrics.
00957  *
00958  *  @return An error code.
00959  */
00960 static GATResult 
00961 endpoint_adaptor_EndpointCPI_GetMetrics(void *data, 
00962   GATEndpointCPI_Instance const *instance_data, GATList_GATMetric *metrics)
00963 {
00964   GAT_UNUSED_PARAMETER(data);
00965   GAT_UNUSED_PARAMETER(instance_data);
00966   
00967   return GATMetric_CreateListOfMetrics(metric_data, __countof(metric_data), metrics);
00968 }
00969 
00970 /** endpoint_adaptor_EndpointCPI_GetMetricEvent
00971  *
00972  *  The function endpoint_adaptor_EndpointCPI_GetMetricEvent should 
00973  *  return the GATMetricEvent associated with the given continuous metric. This 
00974  *  function gets called for continuous metrics only, since returning the 
00975  *  metric event object to the caller is th only way for the client to get 
00976  *  access to it.
00977  *
00978  *  @param data Adaptor-provided data object.
00979  *  @param instance_data Instance data for the CPI provider object.
00980  *  @param metric The metric instance describing the metric event to return.
00981  *        This metric should be equivalent to one of the metrics returned by
00982  *        our own GetMetrics CPI function (see above). If this is another
00983  *        (not known to us metric), an error should be returned.
00984  *  @param event The pointer to the variable, which receives the metric event 
00985  *        to return.
00986  *
00987  *  @return An error code.
00988  */
00989 static GATResult 
00990 endpoint_adaptor_EndpointCPI_GetMetricEvent(void *data, 
00991   GATEndpointCPI_Instance const *instance_data, GATMetric metric, 
00992   GATMetricEvent *event)
00993 {
00994   /* this adaptor supports no continuous metrics */
00995   GAT_UNUSED_PARAMETER(data);
00996   GAT_UNUSED_PARAMETER(instance_data);
00997   GAT_UNUSED_PARAMETER(metric);
00998   GAT_UNUSED_PARAMETER(event);
00999   
01000   return GAT_SUCCESS;
01001 }
01002 
01003 
01004 /** endpoint_adaptor_FireConnect
01005  *
01006  *  The function endpoint_adaptor_FireConnect fires a 
01007  *  'endpoint connect' event to all registered metric listeners.
01008  */
01009 static GATResult 
01010 endpoint_adaptor_FireConnect(GATContext context, 
01011   GATMonitorable_Impl monitorable, GATObject_const source, char const *name)
01012 {
01013   GAT_USES_STATUS(context, "endpoint_adaptor_FireConnect");
01014   
01015   if (NULL != monitorable && NULL != source && NULL != name)
01016   {
01017     GATMetric metric = NULL;
01018     GAT_CREATE_STATUS(GATMetric_CreateMetric(
01019       &metric_data[METRIC_FILESTREAM_CONNECT], &metric));
01020 
01021     if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
01022     {
01023       GATMetricEvent event = GATMetricEvent_Create_EventLike(source, metric, 
01024         (void *)name, (GATuint32)(strlen(name) + 1));
01025         
01026       if (NULL != event)
01027       {
01028         GAT_CREATE_STATUS(GATMonitorable_Impl_FireEvent(monitorable, metric, 
01029           event));
01030         GATMetricEvent_Destroy(&event);
01031       }
01032       else
01033       {
01034         GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
01035       }
01036       
01037       GATMetric_Destroy(&metric);
01038     }
01039   }
01040   else
01041   {
01042     GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
01043   }
01044   return GAT_RETURN_STATUS();
01045 }
01046 
01047 /** endpoint_adaptor_FireListen
01048  *
01049  *  The function endpoint_adaptor_FireWriteEvent fires a 
01050  *  'endpoint listen' event to all registered metric listeners.
01051  */
01052 static GATResult 
01053 endpoint_adaptor_FireListen(GATContext context, 
01054   GATMonitorable_Impl monitorable, GATObject_const source, char const *name)
01055 {
01056   GATResult retval = GAT_INVALID_PARAMETER;
01057   if (NULL != monitorable && NULL != source && NULL != name)
01058   {
01059     GATMetric metric = NULL;
01060     
01061     retval = GATMetric_CreateMetric(&metric_data[METRIC_FILESTREAM_LISTEN], &metric);
01062     if (GAT_SUCCESS == retval)
01063     {
01064       GATMetricEvent event = GATMetricEvent_Create_EventLike(source, metric, 
01065         (void *)name, (GATuint32)(strlen(name) + 1));
01066         
01067       if (NULL != event)
01068       {
01069         retval = GATMonitorable_Impl_FireEvent(monitorable, metric, event);
01070       }
01071       else
01072       {
01073         retval = GAT_MEMORYFAILURE;
01074       }
01075       
01076       GATMetricEvent_Destroy(&event);
01077       GATMetric_Destroy(&metric);
01078     }
01079   }
01080   return retval;
01081 }
01082 
01083 /** endpoint_adaptor_FireAddGATPipeListener
01084  *
01085  *  The function endpoint_adaptor_FireSeekEvent fires a 
01086  *  'endpoint add gat pipe listener' event to all registered metric listeners.
01087  */
01088 static GATResult 
01089 endpoint_adaptor_FireAddGATPipeListener(GATMonitorable_Impl monitorable, 
01090   GATObject_const source, char const *name)
01091 {
01092   GATResult retval = GAT_INVALID_PARAMETER;
01093   if (NULL != monitorable && NULL != source && NULL != name)
01094   {
01095     GATMetric metric = NULL;
01096     
01097     retval = GATMetric_CreateMetric(&metric_data[METRIC_FILESTREAM_ADDGATPIPELISTENER], &metric);
01098     if (GAT_SUCCESS == retval)
01099     {
01100       GATMetricEvent event = GATMetricEvent_Create_EventLike(source, metric, 
01101         (void *)name, (GATuint32)(strlen(name) + 1));
01102         
01103       if (NULL != event)
01104       {
01105         retval = GATMonitorable_Impl_FireEvent(monitorable, metric, event);
01106       }
01107       else
01108       {
01109         retval = GAT_MEMORYFAILURE;
01110       }
01111       
01112       GATMetricEvent_Destroy(&event);
01113       GATMetric_Destroy(&metric);
01114     }
01115   }
01116   return retval;
01117 }
01118 
01119 #if defined(WIN32)
01120 /* Adaptor instance specific functions */
01121 
01122 /** GATEndpointCPIAdaptor_Data_Create
01123  *  This helper creates an instance of a GATEndpointCPIAdaptor_Data object.
01124  *
01125  *  @return The newly created and initialized GATEndpointCPIAdaptor_Data object.
01126  */
01127 static GATEndpointCPIAdaptor_Data *GATEndpointCPIAdaptor_Data_Create()
01128 {
01129   GATEndpointCPIAdaptor_Data *data = 
01130     (GATEndpointCPIAdaptor_Data *)malloc(sizeof(GATEndpointCPIAdaptor_Data));
01131   if (NULL != data)
01132   {
01133     int result = WSAStartup(MAKEWORD(2, 2), &data->wsadata);
01134     if (0 != result) {
01135       free(data);
01136       data = NULL;
01137     }
01138     if (LOBYTE(data->wsadata.wVersion) != 2 || 
01139         HIBYTE(data->wsadata.wVersion) != 2) 
01140     {
01141       WSACleanup();
01142       free(data); 
01143       data = NULL;
01144     }
01145   }
01146   return data;
01147 }
01148 
01149 /** GATEndpointCPIAdaptor_Data_Destroy
01150  *  This helper destroys an instance of a GATEndpointCPIAdaptor_Data object.
01151  *
01152  *  @param The GATEndpointCPIAdaptor_Data object to destroy
01153  */
01154 static void 
01155 GATEndpointCPIAdaptor_Data_Destroy(GATEndpointCPIAdaptor_Data *data)
01156 {
01157   if (NULL != data)
01158   {
01159     WSACleanup();
01160     free(data);
01161   }
01162 }
01163 #endif // defined(WIN32)
01164