/*================================================================================= * DD SYSTEM base package * DD_Server DD_Client library * DD_comm.h * V. 6.0 * Changes listing: * Feb 27 1995 - V 1.0 * 13 Apr. 2002 - changed for NetCDF 3.3 * 03 Oct. 2002 - v.4.0 Fedorov, communication ideology is changed * Oct 31, 2002 - V.4.1 Fedorov, UserName, UserHost and UserID transferred into DD_Access.h * May 7, 2003 - V.4.2 Fedorov, The Cash structure is changed (flag of open file ) * June 17, 2003 - V.4.3 Fedorov, The Maximal Packet Size is changed * Nov 18, 2004 - V.4.4 Fedorov, Some changes * Aug 17, 2005 - V.4.5 Fedorov, Cach Time constant is changed * Jun 17, 2007 - V.4.6 Fedorov, New requestes and external executables * Aug 01, 2007 - V.4.7 Fedorov, Cache length = 20, New DD_Var_t structure * Sep 20, 2007 - V.5.0 Fedorov, Update Time Info library now in the separate file * Sep 23, 2007 - V.5.1 Fedorov, New interface of SetTime * Sep 25, 2007 - V.5.2 Fedorov, Individual minimal gap * Oct 08, 2007 - V.5.3 Budnik, php createVI.php * Jan 25, 2008 - V.5.3.1 Budnik, min data gap = 1 day!!!! * May 22, 2008 - V.5.4 Fedorov, DD_Var_t has a LockStartTime value * May 27, 2008 - V.5.5 Fedorov, Maximal tracnsmition buffer * Sep 19, 2008 - V.5.6 MAXVARLENGTH=64 REQUESTLENGTH 184 * Dec 15, 2012 - V.6.0 New multiparam Get_MultiData() function *===================================================================================*/ #include #include #include #include #include #include #include #include "DD_Access.h" #ifdef SOLARIS #include #include #include /* internet stile addres */ #include #include #include #endif /* SOLARIS */ #ifdef HPUX #include #include #include #include #include #include #endif #ifdef OSF1 #include #include #include #include #endif /* OSF1 */ #ifdef LINUX #include #include #include #include #include #endif /* LINUX */ #ifdef SUNOS #include #include #include #include #include #endif /* SUNOS */ /*----------------- Defenitions of request and server replies --------------------*/ /* 1. Data manipulation requests */ #define OPENINSREQ 0 /* Open virtual instrument */ #define DATAINFOREQ 1 /* Request of constant info */ #define TIMESETREQ 2 /* Position of pointer by StartTime*/ #define DATAGETREQ 3 /* Data request by time interval */ #define CLOSEINSREQ 4 /* Request to close virtual instrument */ #define MOVPOINTREQ 5 /* Move the pointer od data request*/ #define ADDVIREQ 6 /* Add New virtual instrument */ /* 2. Security requests */ #define GETTICKETREQ 10 #define SHOWTICKETREQ 11 /*-------- Some constants ------------------*/ #define EMPTY 0 /* Filler of the trailer */ #define FILEACCMARG 1 /* The minimum time from the last access to remove this file */ /*------------ Important lengths and pathes ----------------*/ #define PROTOCOL 0 /* protocol TCP */ #define REPLYLENGTH 12 /* Length of header of reply packet */ #define REQUESTLENGTH 196 /* Length of request packets MAXSETLENGTH + 2*MAXVARLENGTH + 16 */ #define MAXVARLENGTH 64 /* Length (with \0) of Variable Name */ #define MAXSETLENGTH 52 /* Max Length of VI name */ #define PATHLENGTH 128 /* Length of complete path */ #define MAXFILENAME 32 /* The maximal length of the data file (info, cach, times as well)*/ #define REFNAME "/refer.nc" /* path name for databse refer file */ #define CASHLEN 20 /* Length of cash array */ #define TRY 100 /* How many tymes to ask the socket */ #define MAXPACKSIZE 5000000 /* Maximal size of one packet of transmission in bytes */ #define MAXCOMMANDL 300 /* Command in system() maximal length /*------------------------------------------------- * XDR length to calcolate the total len *-------------------------------------------------*/ #define XDRINTLEN 4 #define XDRFLOATLEN 4 #define XDRDOUBLELEN 8 // String length is counted as 4B + N + r (to completed to 4 bytes) /*------------ List of External Call of DD_Server and ERRORS -------------------*/ #define ADDDATASETCALL "php %s/CALLEXT/createVI.php %s %s %s" /* Format to call to create new VI */ #define GETNEWDATACALL "php %s/CALLEXT/getData.php %s %s %s %s %s &" /* Format to call to get new data */ #define NOPHP 32512 #define NOSCRIPT 256 #define PHPOK 0 /*------ Constant to understand data availabilities -------------------------------*/ #define GLOBSTARTNAME "GlobalStart" #define GLOBSTOPNAME "GlobalStop" #define SAMPLNAME "MinSampling" #define REMARCHNAME "DataBaseID" #define REMINSTNAME "DataSetID" #define MINGAP 86400.0 /*Seconds. The minimal time gap to set up the flag DATAGAP */ #define REQTIMEINT 86400.0 /* One day, +/- of request time interval */ #define ISOTIMEF "%4u%*1c%2u%*1c%2u%*1c%2u%*1c%2u%*1c%2u%*1c%3u" /* Format to READ time in ISO format */ #define ISOTIMEP "%04u-%02u-%02uT%02u:%02u:%02u.%03uZ" /* Format to PRINT time in ISO format */ #define NODATASTR "NODATA" #define DIRLOCK "LOCK" #define QUANTOFFSET 0.01 /*------------- More internal specifications -----------------------*/ /* * See ../DOC/TECHDOC/DDGenProt.html (lyx) */ /* Reply variables: * Error - negative value described in DD.h * Type - int (see DD.h) * Dim_Number - int ( the dimension (vector, matrix, cube, etc) ov the variable) * Data_Size - int (the size of the data packet in bytes) * RemID - int (number of virtual instruments still open in this session) * Dim - int (the particular dimension ) * LastPacketFlag - int ( == OK in this packet is last, or MOREDATA) * Data - array of Type of Dim X Dim X....X Dim size * -------------------- * Dim_Number * DataPacket: * * | * | | * <.....> | Dim_Number | Data_Size bytes * | | * | * ..... | only for real data | * | | * * Note is the value is scalar - the Dim = 0 (???) */ /* REPLY SPECIFICATION * * Reply consists Header 12 bytes length and Data Block * * on Open Virtual instrument: * * on Constant Info request: * * on Set pointer by StartTime: * * on Get Data by TimeInt : * * on Move pointer with records number * * on Close Virtual Instrument * */ /*-------------------- TYPEDEF ---------------------------*/ typedef struct { char CacheFilePath[PATHLENGTH]; char names[CASHLEN][MAXSETLENGTH]; long times[CASHLEN]; int FileOpen[CASHLEN]; /* 1 if file is open */ int ID; /* ID of open cach file */ int nameID; /* ID of names array */ int timeID; /* ID of times array */ int fopenID; /* ID of fopen flag */ } DD_cash_t; /* The structure holding cash informaton * of particular virtual instrument DataBase */ /* * This structure corresponds to ONE requested variable * of some Virtual instrument */ typedef struct { char InstrName[MAXSETLENGTH]; /* Virtual Instrument Name */ char path[PATHLENGTH]; /* Path to directory of open virtual instrument */ /*--------------------------------------- * Cache part *--------------------------------------*/ DD_cash_t Cash; /* Cash holder */ int CurrCushN; /* Current cash pointer */ /*-------------------------------------- * This is the part of open data file and corresponding data set *-------------------------------------*/ int ncID; /* ID of open nc_file */ size_t nc_rec; /* the current record number nc_file */ size_t Maxnc_rec; /* Maximum of records number in in the current nc file */ DD_data_t *VarData; /* Static pointer. Variables Holder */ size_t ParamSize; /* Number or requested variables to save */ /*--------------------------------------------- * This is part of times file of given VI *--------------------------------------------*/ char TimesFileName[PATHLENGTH]; double SDTime; /* Requested Start Time in double form */ double FDTime; /* Requested Stop Time in double form */ double CDTime; /* Current Time in double form */ int tmID; /* ID of "times" file of this virtual instrument*/ int NameID; /* ID of FileName variable in times file */ int StartID; /* ID of Start variable in times file */ int StopID; /* ID of Stop variable in times file */ size_t TimeRecNumber; /* Current Record number in the "times" file */ size_t MaxTimeRecNum; /* Maximum records number in the "times" file */ int RValidMin; /* Minimal record with valid data */ int RValidMax; /* Maximal record with valid data */ double MinValidTime; double MaxValidTime; /* Start of RValidMin, and stop of RValidMax */ int CurrRmin; /* Sure that looking time is greater than stop; -1 if NOT */ int CurrRmax; /* Sure that looking time is less than start; -1 if NOT */ /*------- Working with external Data Base ------------------------------*/ int VILocked; /* Flag to show that request to remote database has been sent */ time_t LockStartTime; /* Value to calculate a time elapsed from lock made by THIS VI */ /*---------- This is the part of Info file of given VI -----------------*/ int attrID; /* ID of constant information nc_file */ char AttrName[PATHLENGTH]; /* Name of constant information file */ DD_data_t AttrData; /* Dimensions of Attributes */ /*---- Part concerning External call ------------------*/ double MinGap; /* The minimal gap between two files */ double GlobalStart; /* The principal begin of data */ double GlobalStop; /* The principal end of data */ char BaseName[MAXSETLENGTH]; /* The name of external data archive */ char RemSetID[MAXSETLENGTH]; /* The name of VI in exterval archiving */ int ExtCallAllowed; /* 1 If Server can call external archiving */ /*------------ Flow Control -----------------------------*/ int LastPacketFlag; /* OK - request is completed, * MOREDATA - one or several blocks expected, * MOREDELAY - wait, system is blocked */ int LastFileStatus; /* The file status after the last SetNewFile */ int NewFile; /* 1 if File was changed, VI has to be refreshed*/ int NewFileWasOpen; /* 1 if the original position of pointer * (in data file, times file) was lost after open * a new data file */ } DD_Var_t; /*---------------- Usefull enumerations ---------------------*/ enum SearchRet {REACHLEFT, REACHRIGHT, OKLEFT, OKRIGHT}; /* * enumerate of the status of time inteval searching * NOONEDATA - no data at al in this VI * INSIDE - CTime is inside valid data interval (tolerance is MINGAP) * DATAATRIGHT, DATAATLEFT - Valid interval is on the right/left from CTime */ enum SearchIntRet {NOONEDATA, INSIDE, DATAATRIGHT, DATAATLEFT, IDLE}; /* Return function IsTimesLocked */ enum LockStatus {NOLOCK, LOCKED, LOCKREMOVED}; /*------------------ Function for Server ---------------------*/ extern int OpenInstr(char *InstrName); /* * Init shared memory for cache system */ extern void Cache_Init(); /* * Free shared memory used for cache system */ extern void Cache_Free(); /* * Free shared memory used for cache system */ extern int Cache_RequestDataFileAccess(DD_Var_t *D, char* dataFileName); /* * Free shared memory used for cache system */ extern int Cache_ReleaseDataFileAccess(DD_Var_t *D); /* * Close cache file */ extern int Cache_CloseFile(DD_Var_t *D); /* * Open Virtual instrument by name and returns the ID * Returns negative value in case of error (see DD.h)or OK */ extern int GetAttribute(int ID, char *Name); /* * Variable - address of structure with variable description * Name - name of attribute * Returns OK or an error (see DD.h) */ extern int GetMultiData(int ID, int VarSize, char **VarNames, char *TimeInterval, int BackFlag); /* * VarSize - size of the array of Names * Names - array of strings with names of requested variables, * TimeInterval - Time in DD_time.h style * Returns negative value in case of error (see bellow) * Returnes MOREDATA if "there is more data", and OK if data is finished. */ extern int SetTime(DD_Var_t *D, double CTime); /*################################################################# * SET TIME * Set time and try to open appropriate data file. If not try to * call external archive * D - address of VI holder * Time - Time in DD_time.h style * Return: * OK * NOID - call with uncorrect VI holder * OUTOFTIME - Requested time is out of General time limitation * WAITEXTCALL - Server sent request to external archive * TRYAGAIN - VI is blocked by call to external database * NODATAATTIME - request time is inside NODATA time interval * some return of SetNewFile(); see ... *#################################################################*/ extern int CloseID(int ID); /* ID - integer identificator of opened Data Set * Returns number of remained IDs of this communication seasson * in case of 0 the server closes this comminication session */ int SetNewFile(DD_Var_t *D, int N); /* * Function tries to get new data for the gap beetween files, or just * open a new data file according to offset N referring to current position in the times file. * The current position changed if file is succesefully open. * Return values: * OK * OUTOFTIME - next interval exceeeds GlobalStart/Stop * TIMEINEMPTY - next interval marked as "NODATA" * TRYAGAIN - the VI is blocked while new data is arriving * WAITEXTCALL - new data is requested * CACHTOOREC - now free space in the CACH * CHACHERR - unrecovable error in CACH * DATAFILEERR - unrecovable error in data file */ size_t MaxRecord(int ncID); /* * Inspect all variables and dimensions of the file (exept Time associated) and * returm maximal record number to transmit */ /*------------------ Global constants ----------------------------------*/ static u_int xdrlen[] = {4,4,4,8,4}; static size_t unixlen[] = {sizeof(char),sizeof(int),sizeof(float),sizeof(double),sizeof(short)}; static bool_t ( *ConvFunc[5])() = {xdr_char, xdr_int, xdr_float, xdr_double, xdr_short}; /*------------------ Global data variable for entire session --------------------*/ extern DD_Var_t **DD_Var ; /* Actually this variable is implimented * in DD_GetData.c . The dimension of this array is defined * by sysconf(_SC_OPEN_MAX)*/ extern size_t MaxIDNumber; /* Size of DD_Var array. Defined actually in DD_GetData.c */ /* * Fuctions prototypes in ExtDataRequest.c file */ /*====================================================================== * IsTimesLocked * Return 1 if there is LOCK in the VI directory *======================================================================*/ extern int IsTimesLocked(DD_Var_t *DD_Var); /*====================================================================== * ExtDataRequest * Return folowing values: * OK - request is accepted SERVER has to wait when LOCK file is gone * NOEXEC - error in external executable * NODATAATTIME - time corresponds to the NODATA interval * GAPISSMALL - Time is inside too small gap *======================================================================*/ extern int ExtDataRequest(DD_Var_t *DD_Var, double CurrTime); /*======================================================================= * UpdateTimeInfo.c * int SearchLeft(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax) * int SearchRight(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax) * Search the next to the left(right) non-empty time interval * DD_VarL - common data structure corresponding to THIS open VI * Rmin, Rmax - start points * * int UpdateTimeInfo(DD_Var_t *DD_VarL) * Function reopen "times" file and update all time constants *======================================================================*/ extern int SearchLeft(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax); extern int SearchRight(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax); extern int UpdateTimeInfo(DD_Var_t *DD_VarL);