diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a7710e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.project +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..765189a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 2.6) + +PROJECT(DDClient) + +add_definitions( -DLINUX ) +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/bin/) +set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build/${CMAKE_BUILD_TYPE}/lib/) + +if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) + #64 bits + MESSAGE( STATUS "64 bits" ) + set(CMAKE_C_FLAGS_DEBUG "-ggdb -DLINUX -Dlinux -m64 -march=core2 -fPIC -D_REENTRANT -pthread") + set(CMAKE_C_FLAGS_RELEASE "-DLINUX -Dlinux -m64 -march=core2 -fPIC -D_REENTRANT -pthread") + set(CMAKE_CXX_FLAGS_DEBUG "-std=c++0x -fPIC -Wall -Wextra -ggdb -DLINUX -Dlinux -D_REENTRANT -malign-double -pthread") + set(CMAKE_CXX_FLAGS_RELEASE "-std=c++0x -Wall -Wextra -fPIC -DLINUX -Dlinux -D_REENTRANT -malign-double -pthread -O3 -DNDEBUG") + set(USRLIB_DIR "/usr/lib64/:/usr/local/lib64/") +else( CMAKE_SIZEOF_VOID_P EQUAL 8 ) + #32 bits + MESSAGE( STATUS "32 bits" ) + set(CMAKE_C_FLAGS_DEBUG "-ggdb -DLINUX -march=i686 -fPIC -Dlinux -D_REENTRANT -malign-double -pthread") + set(CMAKE_C_FLAGS_DEBUG "-DLINUX -march=i686 -fPIC -Dlinux -D_REENTRANT -malign-double -pthread") + set(CMAKE_CXX_FLAGS_DEBUG "-std=c++0x -fPIC -Wall -Wextra -ggdb -DLINUX -Dlinux -D_REENTRANT -malign-double -pthread") + set(CMAKE_CXX_FLAGS_RELEASE "-std=c++0x -Wall -Wextra -fPIC -DLINUX -Dlinux -D_REENTRANT -malign-double -pthread -O3 -DNDEBUG") + set(USRLIB_DIR "/usr/lib/:/usr/local/lib/") +endif( CMAKE_SIZEOF_VOID_P EQUAL 8 ) + + +find_package( Threads REQUIRED ) + +MESSAGE( STATUS "Build DDClient Project" ) +add_subdirectory(src/DDClientLibC) +add_subdirectory(src/DDClientLibCpp) +add_subdirectory(src/TOOLS/DDCheckUser) +add_subdirectory(src/TOOLS/DDHtmlLogin) +add_subdirectory(src/TOOLS/DDLogin) +add_subdirectory(src/TOOLS/DDSimpleTestGetData) +add_subdirectory(src/TOOLS/DDSimpleTestGetMultiData) + +install(DIRECTORY "src/DDClientLibC/INCLUDE/" DESTINATION "include/DDClientLibC") +install(DIRECTORY "src/DDClientLibC/INCLUDE/" DESTINATION "include/DDClientLibCpp") + +SET(CMAKE_VERBOSE_MAKEFILE ON) diff --git a/src/DDClientLibC/CMakeLists.txt b/src/DDClientLibC/CMakeLists.txt new file mode 100644 index 0000000..f5c6093 --- /dev/null +++ b/src/DDClientLibC/CMakeLists.txt @@ -0,0 +1,22 @@ + +PROJECT(DDClientLibC) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibC/INCLUDE/ +) + +#Library configuration +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_LIBRARY( DDClientLibC SHARED ${source_files} ) + +target_link_libraries( + DDClientLibC + ${CMAKE_THREAD_LIBS_INIT} +) + +install (TARGETS DDClientLibC DESTINATION lib) diff --git a/src/DDClientLibC/DD_client.c b/src/DDClientLibC/DD_client.c new file mode 100755 index 0000000..c49246c --- /dev/null +++ b/src/DDClientLibC/DD_client.c @@ -0,0 +1,978 @@ +/* $Id: DD_client.c,v 1.4 2012/10/18 09:25:58 budnik Exp $ */ +/*============================================================== + * DD SYSTEM + * DD_client.c + * V.6.0 + * List of changes: + * November 1995, Version 1.0 + * August 1999 :Access security system was installed by Alexandr Grigoriev (v3.0) + * October 22, 2002 - Communication ideology is changed (V.4.0) + * Oct 29, 2002 - Add DD_GetVersion() and some bags are corrected (V.4.1) + * May 1, 2003 - Network error is developped. (The header receiving is changed): V.4.2 + * Nov 18, 2004 - Cach error is fixed. + * Jun 17, 2007 - Fedorov, V.4.5 Create new VI and Update data requests + * Sep 24, 2007 - Fedorov, V.4.6 Processing of return of Get_Data + * Dec 03, 2007 - Budnik, V.4.7 There may be several sessions with DD Server inside ONE + * Client session. Keep UserHost & UserName + * Oct 18, 2012 - Knizhnikova, V.4.8 new DD_SetTimeInfo() function + * Dec 15, 2012 - Fedorov, V.6.0. DD_GetMultiData(). Request structure is very changed, CurrentData is not a global structure + *===============================================================*/ + +#include <unistd.h> +#include "DD.h" +#include "DD_comm.h" +#include "DD_Access.h" +#include <stdio.h> +#include <string.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#define VERSION "V.6.0" + +/*------------------ GLOBAL STATIC VARIABLES --------------------------*/ +int SocketID = -1; /* Global socket id for this communication session */ +char UserName[USRLENGTH]="\0"; /* string for user name */ +char UserHost[MAXHOSTLENGTH] = "\0"; /* IP of user's host in a string form */ +int UserID; /* ID of user at the user's host */ +extern int errno; + +/*================== FUNCTIONS =================================*/ + +int getInfoFromHostName(const char *hostName, struct sockaddr_in *addr) +{ + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = 0; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + struct addrinfo *result; + int s; + + s = getaddrinfo(hostName, NULL, &hints, &result); + + if (s != 0) + { + return NOHOST; + } + + struct sockaddr_in *h; + h = (struct sockaddr_in *) result->ai_addr; + + memcpy(addr,h,sizeof(struct sockaddr_in)); + + freeaddrinfo(result); + + return 0; +} + +/*----------------------- GET User Host-------------------------------*/ +int GetUserHost() +{ + char HostName[HOSTNAMELENGTH]; + struct hostent *Host; + unsigned int HostAddress; + int userid; + static unsigned int m1 = 0X000000FF; + static unsigned int m2 = 0X0000FF00; + static unsigned int m3 = 0X00FF0000; + static unsigned int m4 = 0XFF000000; + unsigned int b1,b2,b3,b4; + + userid = getuid(); /* Get a client user ID */ + +/* UserHost can be set by extern WEB function in case of WEB communicatio, + * or it should be defined as local host if DD_client is installed at USER + * computer + */ + if(UserHost[0] == '\0') + { + gethostname(HostName,HOSTNAMELENGTH); /* Get a client host name */ + + struct sockaddr_in addr; + + if (getInfoFromHostName(HostName,&addr) != 0) + return NOHOST; + + unsigned int b1, b2, b3, b4; + sscanf(inet_ntoa( addr.sin_addr), "%3u.%3u.%3u.%3u", &b1, &b2, &b3, &b4); + snprintf(UserHost, MAXHOSTLENGTH, "%03u.%03u.%03u.%03u", b1, b2, b3, b4); + } + return userid; +} +/*-------------------------------------------------------------------*/ + + +/*------------------ MAKE_CONNECTION ---------------------------*/ +/* + * The function returns opened socket, ready to read and write + */ +int GetSocket() +/* + * Connect with remote server, and returns socket ID + * In case of error return error number according DD_comm.h + */ +{ +/*-------- Variables for resource file -----------------*/ + char rname[PATHLENGTH]; /* name of res file */ + char line[PATHLENGTH]; + char *path; + FILE *resfile; /* resource file */ + char *pline; + +/*---------- Variables for network ---------------------*/ + static struct hostent *Host; /* name & internet (32b) address for + remout hosts (see netdb.h) */ + static char RemSerName[PATHLENGTH]; /* name of remote server */ + + struct servent *serv; /* pointer to static structure of + port number of registrated service */ + + static struct sockaddr_in IntAFAddr; /* structure of internet address of type AF_INET + see <netinet/in.h> + to get name of socket we should + to convert pointer to this structure + to pointer to "srtruct sockaddr" where + all fields are "char array". */ + + int AFAddrLen = sizeof(struct sockaddr_in); /* size of internet address, <netinet/in.h> 18 bytes*/ + int ScAddrLen = sizeof(struct sockaddr); /* size of socket address, <sys/socket.h> 18 bytes*/ + + int cc,i; + int arg = 0; + int normaddr; +/* + *---------- Getting socket and its address ---------------------*/ +/*---------------- HOST and PORT ------------------------------*/ + if((path = getenv("DDPATH")) == NULL) + { + strcpy(rname,"DD.res"); + } + else + { + strcpy(rname,path); + strcat(rname, "/DD.res"); + } +/* + (void *)strcpy(rname,"./DD.res"); +*/ + if((resfile = fopen(rname,"r")) == NULL) + { + fprintf(stderr,"No resource file, sorry\n"); + exit(1); + } + + pline = fgets(RemSerName, PATHLENGTH-1, resfile); + pline = fgets(line, PATHLENGTH-1, resfile); + fclose(resfile); + + RemSerName[strlen(RemSerName)-1] = '\0'; + sscanf(line,"%d",&(normaddr)); + + if (getInfoFromHostName(RemSerName,&IntAFAddr) != 0) + return NOHOST; + + IntAFAddr.sin_port = htons((uint16_t)normaddr); /* Conversion of the port number to + universal net form */ +/*---------------- END of FILE READING --------------------------*/ +/* + *------- Trying to open socket with this address and name --------- + */ + + if((SocketID = socket(AF_INET,SOCK_STREAM,PROTOCOL)) < 0) + { + perror("Socket:"); return(-1); + } + +/* Filling full internet address for socket "name" + * this address will be used to get communication point */ + + IntAFAddr.sin_family = Host->h_addrtype; + memcpy(&IntAFAddr.sin_addr.s_addr,Host->h_addr_list[0],Host->h_length); + + /* Connection to server socket on remote computer */ + if(connect(SocketID,(struct sockaddr *)&IntAFAddr,AFAddrLen) < 0) + { perror("connect"); return(-1); } + +/* + * Get Host name and Host ID for security application + */ + if((UserID = GetUserHost()) < 0) return(NOHOST); + + return SocketID; +} +/*------------------- end of GetSocket ---------------------*/ + +/*==================== Receive From Net ======================*/ +/* + * Smart buffered receiver + */ +int ReceiveFromNet(char *buf, int PacketSize) +{ + int CurLength = 0; + int i,cc; + do + { + i = 0; + while(((cc = recv(SocketID,buf+ CurLength,PacketSize - CurLength,0)) < 0) && (i < TRY)) i++; + if(cc < 0) return -1; + CurLength = CurLength + cc; + } while(CurLength < PacketSize); + return 1; +} + +/*------------------ Open Virtual Instrument -----------------------*/ +/* + * If no connection, connect to server, then try to order data set and return + * ID if OK or ErrorNumber if not + */ +int DD_SetVariable(char *InstrName) +{ + static caddr_t buff = NULL; + static XDR xdrs; + int InstrID; /* Instrumnet ID to return */ + int cc,i; + int Request = OPENINSREQ; + int hostlen,userlen; + char *PUserHost = UserHost, *PUserName = UserName; + /* We need this because XDR works with adresses of pointers */ + +/* If there is no connection, try to get it */ + if(SocketID < 0) + if((SocketID = GetSocket()) < 0) return(NOCONNECTION); + +/* Encoding request by XDR to buf */ +/* Buffer and stream allocation */ + buff = (caddr_t)malloc(REQUESTLENGTH); + + xdrmem_create(&xdrs, buff, REQUESTLENGTH, XDR_ENCODE); + + xdr_int(&xdrs,&Request); + xdr_string(&xdrs, &InstrName, strlen(InstrName)); + +/* Send Open Virtual Instrument request */ + + if((cc = send(SocketID,buff,REQUESTLENGTH,0)) < 0) + { + perror("DD_SetVariable:"); + free(buff); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + xdrmem_create(&xdrs, buff, REQUESTLENGTH, XDR_FREE); + +/*-------- preparation an authorization request ----------------*/ + if(UserName[0] == '\0') strcpy(UserName,NONAME); + hostlen = strlen(UserHost); + userlen = strlen(UserName); + + xdrmem_create(&xdrs, buff,REQUESTLENGTH, XDR_ENCODE); + + xdr_int(&xdrs,&UserID); + xdr_string(&xdrs, &PUserHost, hostlen); + xdr_string(&xdrs, &PUserName, userlen); +/* fprintf(stderr,"userid %d host %s DD_name %s\n",UserID,UserHost,UserName); */ + +/* Send request */ + if((cc = send(SocketID,buff,REQUESTLENGTH,0)) < 0) + { + perror("DD_Set_Variable:"); + free(buff); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + + free(buff); + xdr_destroy(&xdrs); + +/* Get reply */ + buff = (caddr_t)malloc(REPLYLENGTH); +/* + i=0; + while(((cc = recv(SocketID,buff,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; +*/ + if((cc = ReceiveFromNet(buff, REPLYLENGTH)) < 0) + { + perror("DD_SET_Variable:"); + free(buff); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buff, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&InstrID); + +/* Free all */ + free(buff); + xdr_destroy(&xdrs); + + return InstrID; +} + +/*----------------------- DD_GetInform -----------------------------*/ +/* + * Returns "OK" if OK, fill DD_Data structure + * Return negative value if error + */ + +int DD_GetInform(int VarID,char *AttrName,DD_data_t **data) +{ + static void *v = NULL; + static DD_data_t idd = {DD_CHAR, 0, NULL,1, &v}; + static caddr_t buf = NULL; + static XDR xdrs; + int id; + int cc; + int length; + int op = DATAINFOREQ; + int type; /* type of information or error */ + int DimNumbers; + int PacketSize; + int CurLength; + int i; + u_int count; + u_int MaxNumber; + +/*------------------- Empty static data ------------------------*/ + if(idd.Dimensions != NULL) + { + free(idd.Dimensions); + idd.Dimensions = NULL; + } + if(idd.Variables[0] != NULL) + { + free(idd.Variables[0]); + idd.Variables[0] = NULL; + } + +/*------------------ Check the Name length -----------------------*/ + if(strlen(AttrName) > MAXVARLENGTH) length = MAXVARLENGTH; + else length = strlen(AttrName); + +/*----------- Allocation of memory and stream --------------------*/ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + +/*------------------- Encoding the request ----------------------*/ + xdr_int(&xdrs,&op); + xdr_int(&xdrs,&VarID); + xdr_string(&xdrs, &AttrName, length); + +/*------------------------ Send request ---------------------------*/ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_GetInform:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + +/*------------------------ Get reply header ------------------------*/ + + buf = (caddr_t)malloc(REPLYLENGTH); +/* + i=0; + while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; + if(cc < 0) +*/ + if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0) + { + perror("DD_GetInform:"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&type); + if(type < 0) + { + free(buf); + xdr_destroy(&xdrs); + return(type); + } + xdr_int(&xdrs,&DimNumbers); + xdr_int(&xdrs,&PacketSize); + free(buf); + xdr_destroy(&xdrs); + + idd.DimNumber = DimNumbers; + idd.type = type; + +/*---------------------------- Get Data Packet ----------------------*/ + if(PacketSize > 0) buf = (caddr_t)malloc(PacketSize); + else return(REPLYRECERR); + + if((cc = ReceiveFromNet(buf, PacketSize)) < 0) + { + perror("DD_GetInform:"); + free(buf); + return(REPLYRECERR); + } + +/*--------------------- Decoding data packet ------------------------*/ + if(DimNumbers > 0) + { +/*----------- Memory allocation and xdr creating -----------------*/ + xdrmem_create(&xdrs, buf, (u_int)PacketSize, XDR_DECODE); + +/*----------------- Dimensions decoding -------------------------*/ + if(idd.Dimensions !=NULL) free(idd.Dimensions); + idd.Dimensions = (int *)malloc(DimNumbers*sizeof(int)); + + xdr_array(&xdrs, (caddr_t *)&(idd.Dimensions), + &count, + (u_int )DimNumbers, + unixlen[DD_INT], + (xdrproc_t)xdr_int); + + count = 1; + for(i=0; i < DimNumbers;i++) + count = count*idd.Dimensions[i]; + MaxNumber = count; + } + else + { + free(buf); + return(REPLYRECERR); + } + +/*---------------- Allocate memory for Variables and decoding ------------------*/ + if(idd.Variables[0] != NULL) free(idd.Variables[0]); + idd.Variables[0] = (int *)malloc(unixlen[type] * MaxNumber); + + xdr_array(&xdrs,((caddr_t*)(&idd.Variables[0])),&count, + MaxNumber, unixlen[type], (xdrproc_t)ConvFunc[type]); + +/*-------------------------- Free all ------------------------------*/ + free(buf); + xdr_destroy(&xdrs); + + *data = &idd; + return OK; +} + +/*==================================================== + * DD_SetTime() + *====================================================*/ +/*----------------------------------------------------- + * VarID - ID of Data Set + * Time - string in DD type + * Returns 1 if OK and negative in case of err + *---------------------------------------------------*/ + +int DD_SetTime(int VarID,char *Time) +{ + static caddr_t buf = NULL; + static XDR xdrs; + static int op = TIMESETREQ; + int type; + int cc,i; + int DoneFlag = 0; + + while(DoneFlag == 0) + { +/* Allocatein memory and stream */ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrs,&op); + xdr_int(&xdrs,&VarID); + xdr_string(&xdrs, &Time, TIMELENGTH); + +/* Send request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_SetTime:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + +/* Get reply header */ + + buf = (caddr_t)malloc(REPLYLENGTH); + if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0) + { + perror("DD_SetTime:"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&type); + + free(buf); + xdr_destroy(&xdrs); + + if(type < 0) + { + if(type == CACHTOOREC) sleep((unsigned )(FILEACCMARG)); + else return type; + } + else DoneFlag = 1; + } + return 1 ; +} + +/*================================================================== + * DD_SetTimeInfo() + *=================================================================*/ +/*---------------------------------------------------------- + * VarID - ID of Data Set + * Time - string in DD type + * RealTime - double : time value pointer points to + * Returns 1 if OK and negative in case of err + *----------------------------------------------------------*/ + +int DD_SetTimeInfo(int VarID, char *Time, double *RealTime) +{ + int err; + static char TimeInt[17] = "0000000000001000\0"; + DD_data_t *data; + + err = DD_SetTime(VarID, Time); + if (err < 1) return err; + + err = DD_GetData(VarID, "Time", TimeInt, &data); + if (err < 0) return err; + if (data->VarNumber < 1) return OUTOFTIME; + + *RealTime = DD_Time2Double((char *)data->Variables[0]); + + //BRE - When the corresponding time is the last one of a file, MOREDATA is returned by DDServer. + // => force recall of DD_GetData to open the next file and finish correctly the request + if (err == MOREDATA) + { + if ((err = DD_GetData(VarID, (char *)"Time", TimeInt, &data)) < 0) + { + while ((err == WAITEXTCALL) || (err == TRYAGAIN)) + { + sleep(2); + err = DD_GetData(VarID, (char *)"Time", TimeInt, &data); + } + } + } + + return 1 ; +} + +/*========================================================= + * DD_GetData() + * Just an interface to the DD_GetMultiData() + *========================================================*/ +int DD_GetData(int VarID, char *VarName, char *TimeInt, DD_data_t **data) +{ + char *xxx=VarName; + int err; + err = DD_GetMultiData(VarID, 1, &xxx, TimeInt, data, 1); + return err; +} +/*========================================================= + * DD_GetMultiData() + *========================================================*/ +/*--------------------------------------------------------- + * VarID - ID of open virtual instrument + * VarSize - the size of the array names + * VarNames - araay of the variables names + * TimeInt - Time interval in DD_time style + * data - returned data + * Return values: + * positives: + * MOREDELAY - call this function again after delay + * MOREDATA - call this function again to complete request + * OK - all data received + * negative value - error (see DD.h) + *---------------------------------------------------------*/ + +int DD_GetMultiData(int VarID,size_t VarSize, char **VarNames,char *TimeInt,DD_data_t **data, int BackFlag) +{ + static DD_data_t *CurrentData = NULL; /* Data records array to keep until the next call */ + static size_t OldVarSize = 0; + static caddr_t buf = NULL; + static XDR xdrs; + static int LastPacketFlag = OK; + int id; + int cc; + int *NameLength = NULL; /* Array of lengths */ + int XDRStrLen; /* xdr length of a string */ + int XDRReqlength; // Length in bytes the XDR stream + int op = DATAGETREQ; + int type; /* type of information or error */ + int DimNumbers; + int PacketSize; + int CurLength; + u_int count, MaxSize; + int i; + + /* Empty static data */ + for(id = 0; id < OldVarSize; id++) + { + if(CurrentData[id].Dimensions != NULL) + { + free(CurrentData[id].Dimensions); + CurrentData[id].Dimensions = NULL; + } + if(CurrentData[id].Variables != NULL) + { + for(i = 0; i< CurrentData[id].VarNumber; i++) + free(CurrentData[id].Variables[i]); + free(CurrentData[id].Variables); + CurrentData[id].Variables = NULL; + } + } + free(CurrentData); + + /*-------------------------------------- + * Create a new Current Data empty array + *-------------------------------------*/ + OldVarSize = VarSize; + CurrentData = (DD_data_t *)malloc(sizeof(DD_data_t)*VarSize); + for(id = 0; id < VarSize; id++) + { + CurrentData[id].Dimensions = NULL; + CurrentData[id].Variables = NULL; + CurrentData[id].DimNumber = 0; + CurrentData[id].VarNumber = 0; + CurrentData[id].type = 0; + } + /*-------------------------------------------------------------- + * The follows request preparation and send is performed only + * if the priveous data packed is completely received + *--------------------------------------------------------------*/ + if((LastPacketFlag == OK) || (LastPacketFlag == MOREDELAY)) + { + /*--------------------------------------- + * Preparation of the array the name lengths + * Note that the names are cut down to the MAXVARLENGTH + * Calculation the packet size + *---------------------------------------*/ + NameLength = (int *)malloc(sizeof(int)*VarSize); + XDRReqlength = 8; /* the length of the first+last arguments */ + for(id = 0; id < VarSize; id++) + { + if(strlen(VarNames[id]) > MAXVARLENGTH) NameLength[id] = MAXVARLENGTH; + else NameLength[id] = strlen(VarNames[id]); + XDRStrLen = (NameLength[id] / 4) * 4; + if((NameLength[id] % 4) > 0) XDRStrLen += 4; + XDRReqlength += XDRStrLen + 4; // String length + 4 bytes length coding + //fprintf(stderr,"Variable %s, length %d, total %d\n",VarNames[id],XDRStrLen,XDRReqlength); + } + /*-------------------------------- + * The first packet of the request of the standard size + * Allocation corresponding memory and stream + *------------------------------*/ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + + /* Encoding the request */ + xdr_int(&xdrs,&op); + xdr_int(&xdrs,&VarID); + xdr_string(&xdrs,&TimeInt,TIMELENGTH); + xdr_int(&xdrs,&XDRReqlength); + + /* Send the first request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_GetData: First Request"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + + /*-------------------------------- + * The Second packet of XDRReqlength size + * Allocation corresponding memory and stream + *------------------------------*/ + buf = (caddr_t)malloc(XDRReqlength); + xdrmem_create(&xdrs, buf, XDRReqlength, XDR_ENCODE); + xdr_int(&xdrs,(int *)(&VarSize)); + for(id = 0; id < VarSize; id++) xdr_string(&xdrs, &VarNames[id], NameLength[id]); + xdr_int(&xdrs,&BackFlag); + + /* Send the second request */ + if((cc = send(SocketID,buf,XDRReqlength,0)) < 0) + { + perror("DD_GetData:Second Packet"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + } + + /*----------------------------------------------------------- + * Get the VarSize reply headers and VarSize data + *----------------------------------------------------------*/ + for(id = 0; id < VarSize; id++) + { + /*------------------- + * The header + *-----------------*/ + buf = (caddr_t)malloc(REPLYLENGTH); + if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0) + { + perror("DD_GetData:Error while header receive"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&type); + xdr_int(&xdrs,&DimNumbers); + xdr_int(&xdrs,&PacketSize); + free(buf); + xdr_destroy(&xdrs); + + if((type < 0) && (type != NOVAR)) /* Server returns unrecoverable error */ + { + fprintf(stderr,"DD_GetData: Server returns %d, unrecovable error\n",type); + return type; + } + + /*----------- Header is received ----------------------*/ + CurrentData[id].DimNumber = DimNumbers - 1; + CurrentData[id].type = type; + + /*--------------- Receive Data Packet ------------------------------*/ + if(PacketSize > 0) buf = (caddr_t)malloc(PacketSize); + else return(REPLYRECERR); + if((cc = ReceiveFromNet(buf, PacketSize)) < 0) + { + perror("DD_GetData: Error while data packet receive"); + free(buf); + return(REPLYRECERR); + } + /*----------------- Decoding data packet --------------------*/ + if(DimNumbers > 1) + { + xdrmem_create(&xdrs, buf, (u_int)PacketSize, XDR_DECODE); + count = DimNumbers-1; + /* allocation memory for dimensions */ + CurrentData[id].Dimensions = (int *)malloc((DimNumbers-1)*sizeof(int)); + + xdr_int(&xdrs,&LastPacketFlag); /* Last Paket Indicatort*/ + xdr_int(&xdrs,&CurrentData[id].VarNumber); /* Variables number */ + + if(LastPacketFlag > 2) + { + LastPacketFlag = OK; + CurrentData[id].VarNumber = 0; + free(buf); + return(REPLYRECERR); + } + + /*----- Decoding dimensions array -------------------*/ + xdr_array(&xdrs, (caddr_t *)&(CurrentData[id].Dimensions), + &count, + (u_int )DimNumbers-1, + unixlen[DD_INT], + (xdrproc_t)xdr_int); + + count = 1; + for(i=0; i < DimNumbers-1;i++) + { + count = count*CurrentData[id].Dimensions[i]; + } + MaxSize = count; + } + else + { + if(type != NOVAR) + { + free(buf); + return(REPLYRECERR); + } + else + { + CurrentData[id].VarNumber = 0; + } + } + + /*---------- Decoding variables -------------------------*/ + if(CurrentData[id].VarNumber != 0) CurrentData[id].Variables = (void *)malloc(CurrentData[id].VarNumber*sizeof(void *)); + else CurrentData[id].Variables = NULL; + + for(i = 0; i < CurrentData[id].VarNumber; i++) + { + CurrentData[id].Variables[i] = (void *)malloc(unixlen[type]*MaxSize); + count = MaxSize; + xdr_array(&xdrs,(caddr_t *)(&(CurrentData[id].Variables[i])),&count,MaxSize,unixlen[type], (xdrproc_t)ConvFunc[type]); + } + + /* Free all */ + free(buf); + xdr_destroy(&xdrs); + } + *data = CurrentData; + return(LastPacketFlag); +} +/*===================================================================*/ + +/*-------------------------- DD_CLOSE --------------------------------*/ +/* + * + * VarID - entry point of ID table + * Returns 1 if OK or negative err + * Close Socket if no VarID more ( this information supplyed by server ) + */ + +int DD_Close(int VarID) +{ + static caddr_t buf = NULL; + static XDR xdrs; + static int op = CLOSEINSREQ; + int RemainedID; /* Server returns number of remained ID */ + int cc,i; +/* Allocatein memory and stream */ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrs,&op); + xdr_int(&xdrs,&VarID); + +/* Send request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_Close:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + +/* Get reply header */ + + buf = (caddr_t)malloc(REPLYLENGTH); +/* + i = 0; + while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; + if(cc < 0) +*/ + if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0) + { + perror("DD_Close:"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&RemainedID); + if(RemainedID< 0) + { + free(buf); + xdr_destroy(&xdrs); + return(RemainedID); + } + free(buf); + xdr_destroy(&xdrs); + + if(RemainedID == 0) + { + shutdown(SocketID,2); + close(SocketID); + SocketID = -1; +/* + UserHost[0] = '\0'; + UserName[0] = '\0'; +*/ + } + + return(1); +} +/*------------------------------------------------------------------------------*/ + +/*=============== DATABASE UPDATE FUNCTIONS ====================================*/ +/*------------------ DD_AddDataSet() -------------------------------------------*/ +int DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName) +{ + static caddr_t buf = NULL; + static XDR xdrs; + static int op = ADDVIREQ; + int Err; /* Server returns OK or NOEXEC */ + int cc,i,length; + int CloseFlag = 0; + +/* If there is no connection, try to get it */ + if(SocketID < 0) + { + if((SocketID = GetSocket()) < 0) return(NOCONNECTION); + CloseFlag = 1; // To close Connection at the end + } + +/* Allocatein memory and stream */ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrs,&op); + +/* Coding DataSetName */ + if((length = strlen(DataSetName)) > MAXSETLENGTH) length = MAXSETLENGTH; + xdr_string(&xdrs, &DataSetName, length); +/* Coding RemSetID */ + if((length = strlen(RemSetID)) > MAXVARLENGTH) length = MAXVARLENGTH; + xdr_string(&xdrs, &RemSetID, length); +/* Coding BaseName */ + if((length = strlen(BaseName)) > MAXVARLENGTH) length = MAXVARLENGTH; + xdr_string(&xdrs, &BaseName, length); + +/* Send request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_AddDataSet:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + +/* Get reply header */ + buf = (caddr_t)malloc(REPLYLENGTH); + if((cc = ReceiveFromNet(buf, REPLYLENGTH)) < 0) + { + perror("DD_AddDataSet:"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&Err); + + if(CloseFlag) // Close everything if function established connection + { + shutdown(SocketID,2); + close(SocketID); + SocketID = -1; +/* Session with DD Server was closed, but User Session continues !!!!! */ + /* UserHost[0] = '\0'; + UserName[0] = '\0'; */ + } + return Err; +} +/*-----------------------------------------------------------------------------*/ + +/*---------------------- DD GET VERSION ---------------------------------------*/ +char *DD_GetVersion() +/* + * return static pointer to internal string with the DDLIB-SERVER package version + */ +{ + static char Version[] = VERSION; + return (char *)Version; +} +/*------------------------- End Library -------------------------------*/ diff --git a/src/DDClientLibC/DD_time.c b/src/DDClientLibC/DD_time.c new file mode 100755 index 0000000..946432a --- /dev/null +++ b/src/DDClientLibC/DD_time.c @@ -0,0 +1,321 @@ +/* =================================================================== + * Name : DD_time.c + * Version: : 4.1 + * Author : Andrey Fedorov + * Institution : IRAP/UPS/CNRS Toulouse + * Modifications list: + * Oct 5, 2002: V.3.0, New functions DD_Time2Double and Double2DD_Time were added. + * March 26, 2010: V.3.1 YEARS up to 2025 + * May 17, 2011: V.4.0 Fedorov, completely revised version. + * There is no more confuse between Time and Time Interval + * Sept 05, 2011: V.4.1 SetIntNew => arg TimeKind => to work with 1970-1973 : BR + *==================================================================*/ + +#include "DD_time.h" +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#define YEARS 56 +#define STARTYEAR 1970 + +/*---- Static array of days shift from Jan-1-1970 -------*/ +/* 1970 1971 1972 1973 1974 1975 1976 + * 1977 1978 1979 1980 1981 1982 1983 + * 1984 1985 1986 1987 1988 1989 1990 + * 1991 1992 1993 1994 1995 1996 1997 + * 1998 1999 2000 2001 2002 2003 2004 + * 2005 2006 2007 2008 2009 2010 2011 + * 2012 2013 2014 2015 2016 2017 2018 + * 2019 2020 2021 2022 2023 2024 2025 + */ +static double + YearDays[YEARS] = { 0.0, 365.0, 730.0, 1096.0, 1461.0, 1826.0, 2191.0, + 2557.0, 2922.0, 3287.0, 3652.0, 4018.0, 4383.0, 4748.0, + 5113.0, 5479.0, 5844.0, 6209.0, 6574.0, 6940.0, 7305.0, + 7670.0, 8035.0, 8401.0, 8766.0, 9131.0, 9496.0, 9862.0, + 10227.0, 10592.0, 10957.0, 11323.0, 11688.0, 12053.0, 12418.0, + 12784.0, 13149.0, 13514.0, 13879.0, 14245.0, 14610.0, 14975.0, + 15340.0, 15706.0, 16071.0, 16436.0, 16801.0, 17167.0, 17532.0, + 17897.0, 18262.0, 18628.0, 18993.0, 19358.0, 19723.0, 20089.0}; + +/*------------------------------------------------------------- + * DAY_OF_YEAR = monthday[*][month-1]+day_of_month -1 + *------------------------------------------------------------*/ +static int monthday[2][12] = +{ +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, +{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} +}; + +/*------------------------------------------------------------ + * Global static Flag to show the current state of the time + * processor. Is it Time interval (0), or DD Time (1) + *----------------------------------------------------------*/ +static int TimeFlag = 1; +/*================== INTERNAL FUNCTION ====================*/ +/*-------------------- SetInt ----------------------------*/ +void SetInt(dd_tmstr_t *UT) +{ + SetIntNew(UT,DD_TM_UNKNOWN); +} + +void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind) /* Fill int values of dd_tmstr_t */ +/* If the double times field of UT structure is defined, + * this function fills remains fields of Year, day .... separately + */ +{ + static double msofday = 24.0*60.0*60.0; + static double msofhour = 60.0*60.0; + static double msofmin = 60.0; + long daynumber; + double msrest; + int i; + + daynumber = (long)(UT->times / msofday); + for(i=0;i<YEARS;i++) if(daynumber < (long)YearDays[i]) break; + i--; + + switch(timeKind) + { + case DD_TM_DATE : + { + //it's a date + UT->year = i+1970; + UT->day = (int)(daynumber - (long)YearDays[i]); + break; + } + case DD_TM_TIME_INTERVAL : + { + //it's a time interval + UT->year = 0; + UT->day = (int)(daynumber); + break; + } + default : + //compatibility mode + if(i > 3) + { + UT->year = i+1970; + UT->day = (int)(daynumber - (long)YearDays[i]); + } + else + { + UT->year = 0; + UT->day = (int)(daynumber); + } + break; + } + + msrest = UT->times - (double)daynumber * msofday; + UT->hour = (int)(msrest / msofhour); + msrest -= (double)(UT->hour)*msofhour; + UT->min = (int)(msrest / msofmin); + msrest -= (double)(UT->min)*msofmin; + UT->sec = (int)(msrest); + UT->msec = (int)((msrest - (double)(UT->sec))*1000.0); + return; +} + +/*---------------- end of SetInt -----------------------*/ + +/*------------------------------------------------------- + * SetDouble() + * Returns the double value of seconds since 1 Jan 1970 + * The calculations are made from already filled dd_tmstr_t. + * If UT->year + *------------------------------------------------------*/ +void SetDouble(dd_tmstr_t *UT) +{ + static double SecInMls = 1.0/1000.0; + static double SecImMin = 60.0; + static double SecInHour = 60.0*60.0; + static double SecInDay = 60.0*60.0*24.0; + if(UT->year >= STARTYEAR) // This is DD Time ! + UT->times = (double)UT->msec*SecInMls + + (double)UT->sec + + (double)UT->min*SecImMin + + (double)UT->hour*SecInHour + + (double)UT->day*SecInDay + + YearDays[(UT->year - 1970)]*SecInDay; + else if(UT->year < STARTYEAR) // This is Time Interval + UT->times = (double)UT->msec*SecInMls + + (double)UT->sec + + (double)UT->min*SecImMin + + (double)UT->hour*SecInHour + + (double)UT->day*SecInDay + + YearDays[UT->year]*SecInDay; + else + UT->times = 0.0; + return; +} +/*----------------- end of SetDouble ---------------------*/ + +/*=================== PUBLIC FUNCTIONS ==================*/ +/*------------------- DD_Time2Double --------------------*/ +double DD_Time2Double(dd_time_t UTstring) +{ + static dd_tmstr_t UT; + static char year[5] = "0000\0"; + static char day[4] = "000\0"; + static char hour[3]= "00\0"; + static char min[3] = "00\0"; + static char sec[3]= "00\0"; + static char msec[4] = "000\0"; + + strncpy(year,UTstring,4); + strncpy(day,UTstring+4,3); + strncpy(hour,UTstring+7,2); + strncpy(min,UTstring+9,2); + strncpy(sec,UTstring+11,2); + strncpy(msec,UTstring+13,3); + + sscanf(year,"%d",&(UT.year)); + sscanf(day,"%d",&(UT.day)); + sscanf(min,"%d",&(UT.min)); + sscanf(hour,"%d",&(UT.hour)); + sscanf(sec,"%d",&(UT.sec)); + sscanf(msec,"%d",&(UT.msec)); + if(UT.year < STARTYEAR) TimeFlag = 0; // Time Inetrval + + SetDouble(&UT); + return UT.times; +} +/*------------------------------------------------------*/ + +/*------------------- Double2DD_Time ---------------------*/ + char *Double2DD_Time(double Time) + { + static dd_time_t UTstring; + dd_tmstr_t UT; + + UT.times = Time; + SetInt(&UT); + sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT.year),(UT.day),(UT.hour), (UT.min), (UT.sec),(UT.msec)); + return &(UTstring[0]); + } +/*------------------------------------------------------------*/ + +/*================== BACKUP COMPABILITY FUNCTIONS =================*/ +/*----------------------------------------------------------------- + * ReadTime() + * Reads a standard DD time string as an argument + * and converts it into dd_tmstr_t structure. + * Function returns the pointer to the internal startic structure dd_tmstr_t. + * Function redefines TimeFlag. + *----------------------------------------------------------------*/ +dd_tmstr_t *ReadTime(char *UTstring) +{ + static dd_tmstr_t UT; + static char year[5] = "0000\0"; + static char day[4] = "000\0"; + static char hour[3]= "00\0"; + static char min[3] = "00\0"; + static char sec[3]= "00\0"; + static char msec[4] = "000\0"; + + strncpy(year,UTstring,4); + strncpy(day,UTstring+4,3); + strncpy(hour,UTstring+7,2); + strncpy(min,UTstring+9,2); + strncpy(sec,UTstring+11,2); + strncpy(msec,UTstring+13,3); + + sscanf(year,"%d",&(UT.year)); + sscanf(day,"%d",&(UT.day)); + sscanf(min,"%d",&(UT.min)); + sscanf(hour,"%d",&(UT.hour)); + sscanf(sec,"%d",&(UT.sec)); + sscanf(msec,"%d",&(UT.msec)); + + if(UT.year < STARTYEAR) TimeFlag = 0; // Time Inetrval + + SetDouble(&UT); + return(&UT); +} +/*-------------------- end of ReadTime ------------------------*/ + +/*---------------------- Write Time ---------------------------*/ +/* Function Write time convert use only double times field + * of dd_tmstr_t structure to print time in DD style + * in internal static string. The integer fields redefined. + * Function return string pointer. + */ + +char *WriteTime(dd_tmstr_t *UT) +{ + static dd_time_t UTstring; + + SetInt(UT); + sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT->year),(UT->day),(UT->hour), + (UT->min), (UT->sec),(UT->msec)); + return(UTstring); +} +/*------------------- end of WriteTime -------------------*/ + +void WriteFmtTime(dd_tmstr_t *UT,char *UTstring) +{ + SetInt(UT); + sprintf(UTstring,"%04d:%03d:%02d:%02d:%02d",(UT->year),(UT->day),(UT->hour), + (UT->min), (UT->sec)); +} +/*------------------- end of WriteFmtTime -------------------*/ + +/*========================================================= + * Functions for DECODERs + * These functions make conversion from/to DD double/DD_time_structure and + * a integer array as follows: + * {Year, Month, Day_Of_Month, Hour, Min, Sec, Mls} + *========================================================*/ +/*-------------------------------------------------------- + * UT2double() + * Fille the DD_time_structure with double fild from the + * integer array (see the section header) + *-------------------------------------------------------*/ +dd_tmstr_t *UT2double(unsigned *ut) +/* Fill the standard structure with double too using as + * argument 7 int length array in Gavrilova Passport Standard + */ +{ +static dd_tmstr_t UT; +int visocos; + +if(ut[0]%4 == 0) visocos = 1; else visocos = 0; +UT.year = ut[0]; +UT.day = monthday[visocos][ut[1] - 1]+ut[2] - 1; +UT.hour = ut[3]; +UT.min = ut[4]; +UT.sec = ut[5]; +UT.msec = ut[6]; + +SetDouble(&UT); +return(&UT); +} +/*-------------------------------------------------------*/ +/*------------------------------------------------------- + * Double2UT() + * Converts Standard DD double time to interger array (see + * the section header) + *--------------------------------------------------------*/ +unsigned *Double2UT(double t) +{ + static unsigned UT[7]; + dd_tmstr_t tm; + int i,visocos; + + tm.times = t; + SetInt(&tm); + if(tm.year % 4 == 0) visocos = 1; else visocos = 0; + i = 0; + while((i < 12) && (tm.day >= monthday[visocos][i])) i++; + UT[0] = tm.year; + UT[1] = i; + UT[2] = tm.day +1 - monthday[visocos][i-1]; + UT[3] = tm.hour; + UT[4] = tm.min; + UT[5] = tm.sec; + UT[6] = tm.msec; + + return( (unsigned *)UT); +} +/*=======================================================================*/ diff --git a/src/DDClientLibC/INCLUDE/DD.h b/src/DDClientLibC/INCLUDE/DD.h new file mode 100755 index 0000000..646ce63 --- /dev/null +++ b/src/DDClientLibC/INCLUDE/DD.h @@ -0,0 +1,143 @@ +/*================================================================================================= + * DD SYSTEM + * DD.h + * Version: 6.0 + * Description: The public header to use DD library libDD.a + * List of changes: + * Apr. 17, 2002 Fedorov, - New error constant to interrupt the + * transmission if data dimensions are changed from file + * to file + * Nov 18, 2004 - V.4.2 - Fedorov, New errors for CACH manipulating + * Jun 17, 2007 - V.4.6 Fedorov New requestes and external executables + * Aug 02, 2007 - V.4.7 Fedorov Modification of call external executables + * Sep 24, 2007 - V.5.0 Fedorov New status of Get Data: MOREDELAY + * May 21, 2008 - V.5.1 Fedorov New Status of SetTime: CTIMEISSHIFTED + * Oct 18, 2012 - V.5.2 Knizhnikova New DD_SetTimeInfo() function + *=================================================================================================*/ + +#include "DD_time.h" + +typedef struct { int type; /* Type of variable in netcdf style */ + int DimNumber; /* number of dimensions */ + int *Dimensions; /* Dimensions array + * fastest change is last */ + int VarNumber; /* Dimension of variable array */ + void **Variables;/* Variables array pointer + * It is static array refreshed + * each call + */ + } DD_data_t; + +/*------------------- FUNCTIONS ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int DD_SetVariable(char *VarName); +/* + * VarName - full name of variable <project>:<instrument>:<Variable> + * Returns VarID or negative in case of error (see bellow) + */ + +extern int DD_GetInform(int VarID,char *AttrName, DD_data_t **data); +/* + * VarID - Variable ID from DD_SetVariable + * AttrName - name of attribute ( defined by konvention ) + * data - address of data structure + * Returns 1 if OK and negative value in case of error (see bellow) + */ + +extern int DD_SetTime(int VarID, char *Time); +/* + * VarID - Variable ID from DD_SetVariable + * Time - string defined in DD_time.h + * Returns 1 if OK and negative value in case of error (see bellow) + */ + +extern int DD_SetTimeInfo(int VarID, char *Time, double *RealTime); +/* + * VarID - Variable ID from DD_SetVariable + * Time - string defined in DD_time.h + * RealTime - time pointer was set to + * Returns 1 if OK and negative value in case of error (see bellow) + */ + +extern int DD_GetMultiData(int VarID, size_t VarSize, char **VarNames, char *TimeInt, DD_data_t **data, int BackFlag); +/* + * VarID - Variable ID from DD_SetVariable + * VarSize - number of variables to return + * VarNames - the array of Names of the requested Variable + * TimeInt - String of Time interval in DD_time style + * data - Data structures array + * BackFlag - 0 - pointer is at the lasy position, 1 - pointer returns to the start point + * Returns 1 if OK and negative value in case of error (see bellow) + */ + +/* ---------------------------------------- + * This function below just call DD_GetMultiData + * for backup + *---------------------------------------*/ +extern int DD_GetData(int VarID, char *VarName, char *TimeInt, DD_data_t **data); + +extern int DD_MovePoint(int VarID, int RecordNumber); +/* + * VarID - Open virtual instrument ID + * int RecordNumber - +/- records to move + * Move pointer in the open instrument and return 1 or negative if error + */ + +extern int DD_Close(int VarID); +/* + * VarID - Variable ID from DD_SetVariable + * Returns 1 if OK and negative value in case of error (see bellow) + */ + +extern char *DD_GetVersion(); +/* + * return static pointer to internal string with the DDLIB-SERVER package version + */ + +/*----------- Data Update functions -----------------------------------*/ +extern int DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName); +/* + * Request for new VI. See ../DOC/TECHDOC/DDServFunct.html + */ + +#ifdef __cplusplus +} +#endif + +/*--------------------- CONSTANTS -----------------------------------------*/ +#define MOREDATA 1 /* There is data, but we have to call GetData again right now*/ +#define MOREDELAY 2 /* There is data, but we have to call GetData again after delay */ +#define OK 0 /* It is last data packet */ +#define NOCONNECTION -1 +#define TOOMANYREQ -2 +#define REQSENDERR -3 +#define REPLYRECERR -4 +#define NOID -5 +#define NOREFFILE -6 +#define NOTIMESFILE -7 +#define NOINFOFILE -8 +#define NOVAR -9 +#define OUTOFTIME -10 +#define CACHERR -11 /* The error occured when program manipulated the cach */ +#define CACHTOOREC -33 /* Off files in the CASH are created less then 5 sec ago */ +#define WAITEXTCALL -34 /* Server Waits external call finish */ +#define TRYAGAIN -35 /* Times file is locked. This request should be repeated again */ +#define NODATAATTIME -36 /* Requested time is inside NODATA time interval */ +#define GAPISSMALL -37 /* Gap is too small to call external archive */ +#define CTIMEISSHIFTED -38 /* The request was in NoData interval, try again with time at the end */ +#define DATAFILEERR -12 /* The error while manipulate with data file */ +#define ENVIRERROR -13 /* Error in Environments */ +#define NOPOINTER -14 /* The pointer points nowhere, SetTime were failed */ +#define INTSERERR -15 /* Server internal error */ +#define TIMEINEMPTY -16 /* No data for specified time interval */ +#define NOEXEC -17 /* No executable */ + +#define DD_SHORT 4 +#define DD_INT 1 +#define DD_FLOAT 2 +#define DD_DOUBLE 3 +#define DD_CHAR 0 diff --git a/src/DDClientLibC/INCLUDE/DD_Access.h b/src/DDClientLibC/INCLUDE/DD_Access.h new file mode 100755 index 0000000..a1d3b10 --- /dev/null +++ b/src/DDClientLibC/INCLUDE/DD_Access.h @@ -0,0 +1,93 @@ +/* ====================================================== + * + * DD_Access.h + * V.2.0 + * Last revision: Oct 7, 2002 + * List of revisions: 1997 - version 1.0 + * Oct 7, 2002 - version 2.0 (update a little ) + */ + +#define MAXHOSTLENGTH 16 /* IP-address: "255.255.255.255\0" */ +#define USRLENGTH 21 /* Length of UserName: + \0 */ +#define TICKETLENGTH 9 /* Length of passwd: 8 + \0 */ +#define HOSTNAMELENGTH 120 /* Length of the user host name */ +#define USERCASHLEN 100 /* Size of user_ticket.nc file must be 300 */ +#define NONAME "no_name\0" /* Name of user in case of non-WEB connection */ +#define ACCINSTR "iball:acc:all" /* Instrument which watch the access */ +#define TICKET_PATH "/ACC/user_ticket.nc" +#define USERREFNAME "/ACC/user_info.nc" +#define LOGFILE "/ACC/login.log" + +/*------------ Errors of ACCESS ---------------------*/ +#define NOPERMISSION -100 +#define NOHOST -101 +#define NOUSERSFILE -102 + +/*--------------- Extern global variables -------------------*/ +extern char UserName[USRLENGTH]; /* defined in DD_client.c */ +extern char UserHost[MAXHOSTLENGTH]; /* defined in DD_client.c */ +extern int UserID; /* defined in DD_client.c */ + +/*--------------- Extern Functions ---------------------------*/ +extern int FillStruct (int argc, void **argv); +/* This function used to set up the host address from IDL (when WWW access used) + * Arguments allocation is as follows: + * UserName - 0 + * UserHost - 1 + * Location: DD_idl.c -> DD_idl.so +*/ + +extern int GetTicket(int UID, char *HostName, int DD_user_id); +/* Description: This function find the user data in user_cash.nc + * If O'k rewrite the line with new time. + * In case of a new user, remove the first line with + * older time data then a current time + 4.5 hours. + * + Takes 3 arguments: UserId (id in the romote host) + Remote host address(string,like "193.232.6.60\0") + DD_user_id(can see in user_info.nc) + + Returns 0 if O'k or NOPERMISSIONS, or ERROR + + If DD_log_name equal NULL searching for UserId, IP-address + If DD_log_name nonequal NULL searching for IP-address,DD_log_name* + * + */ +extern int CheckTicket(char *NameUsr, char *Ticket); +/* Description: This function check if user exosts + * in user_info.nc file. Returns DD_id if O'k. + * It returns NOPERMISSION or other errors + */ + +extern int ShowTicket(int userid, char *hostname, char *DD_name); +/* + * Show if user has authorisation to work + */ + +extern int LoginRequest(char *UserPasswd, char *UserLogin, char *HostName); +/* Description: Library function for client-server using. + * Send ID, Password,UserLogin, and host to server. + * Compares the information with your {id,hostname and other}. + * Returns 0 if O'k, or a negative value in case + * of "NOPERMISSION" or error. + * + */ +extern int SetUser(int UserID, char *HostName, char *LogName); +/* Description: Library function for client-server using. + * Send UserID, HostName to server. + * Compares the information with your {id,hostname}. + * Returns 1 if O'k, or a NOPERMISSION, or error number + */ + +extern int CheckID(char *NameUsr); +/* Description: This function check the user name in user_info.nc file. + * Returns DD_id if exists. + * It returns NOPERMISSION or other errors + */ + +extern void Put2Log(int UID, char *Host, char *LogName, int error); +/* Description: This function logs a user's ID, IP-address of a local host, + * login name and permission information into log file. + * + */ + diff --git a/src/DDClientLibC/INCLUDE/DD_comm.h b/src/DDClientLibC/INCLUDE/DD_comm.h new file mode 100755 index 0000000..94a5037 --- /dev/null +++ b/src/DDClientLibC/INCLUDE/DD_comm.h @@ -0,0 +1,412 @@ +/*================================================================================= + * 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 <baseID> <remSetID> <ddSetID> + * 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 <stdio.h> +#include <sys/errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> +#include "DD_Access.h" + +#ifdef SOLARIS +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> /* internet stile addres */ +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/rpc.h> +#endif /* SOLARIS */ + +#ifdef HPUX +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <sys/un.h> +#include <rpc/xdr.h> +#include <rpc/rpc.h> +#endif + +#ifdef OSF1 +#include <sys/socket.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <rpc/xdr.h> +#endif /* OSF1 */ + +#ifdef LINUX +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <rpc/rpc.h> +#include <rpc/xdr.h> +#endif /* LINUX */ + +#ifdef SUNOS +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <netinet/in.h> +#include <netdb.h> +#include <rpc/xdr.h> +#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%s.php %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: + * + * <LastPacketFlag> | + * <Dim> | | + * <.....> | Dim_Number | Data_Size bytes + * <Dim> | | + * <data> | + * ..... | only for real data | + * <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: + * <OPENINSREQ><ID/Eroor><EMPTY><EMPTY> + * on Constant Info request: + * <DATAINFOREQ><Type/Error><Dim_Number><Data_Size><DataPacket> + * on Set pointer by StartTime: + * <SETTIMEREQ><EMPTY/Error><EMPTY><EMPTY> + * on Get Data by TimeInt : + * <DATAGETREQ><Type/Error><Dim_Numbers><Data_Size><LastRecordFlag><DataPacket> + * on Move pointer with records number + * <MOVPOINTREQ><EMPTY/Error><EMPTY><EMPTY> + * on Close Virtual Instrument + * <CLOSEINSREQ><RemID/Error><EMPTY><EMPTY> + */ + +/*-------------------- 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); + diff --git a/src/DDClientLibC/INCLUDE/DD_time.h b/src/DDClientLibC/INCLUDE/DD_time.h new file mode 100755 index 0000000..51c4720 --- /dev/null +++ b/src/DDClientLibC/INCLUDE/DD_time.h @@ -0,0 +1,59 @@ +/* This is header file for working with DD time */ +/* V.4.1 */ +/* name: DD_time.h + * Author: Andrey Fredorov + * Institution: IKI RAN + * Date: 21-Feb-1995 + * Last update Sept 05, 2011 + * Sept 05, 2011: V.3.2 SetIntNew => arg TimeKind => to work with 1970-1973 : BR + */ + +#define TIMELENGTH 17 + +typedef char dd_time_t[TIMELENGTH]; /* YYYYDDDHHMMSSMLS */ + +/* ---------------- Functions prototypes ----------------------*/ +extern double DD_Time2Double(dd_time_t DD_Time); +/* Convert string to double and return. + * Return negative value in case of error string format + */ +extern char *Double2DD_Time(double Time); +/* Convert double Time value into string form and return pointer to static string + * allocated INSIDE the library. Thus the value is renoveted each function call. + */ + +/*---------------- Backup compability with V.3.0 and earlier ----------*/ +typedef struct { double times; /* time sec from 1970 */ + int year; + int day; + int hour; + int min; + int sec; + int msec; + } dd_tmstr_t ; + + +extern dd_tmstr_t *ReadTime(char *UT); /* Read time from sring and fill static + * structure defined IN function. + * Returns pointer of strusture */ +extern char *WriteTime(dd_tmstr_t *UT); /* Get pointer of time structure + * and convert it into string + * Function returns pointer of + * internal string */ + +extern void WriteFmtTime(dd_tmstr_t *UT,char *UTstring); + +extern void SetDouble(dd_tmstr_t *UT); /* Fill double value of dd_tmstr_t */ + +typedef enum {DD_TM_UNKNOWN, DD_TM_TIME_INTERVAL, DD_TM_DATE} t_DDTimeKind; + +extern void SetInt(dd_tmstr_t *UT); /* Fill int values of dd_tmstr_t */ +extern void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind); + +/*------- Functions for DECODERS ------------------------ + *These functions works with with Gavrilova's UT representation */ +extern dd_tmstr_t *UT2double(unsigned *UT); /* Set standard time + * structure and return + * its pointer + */ +extern unsigned *Double2UT(double Time); /*Converts Double to Gavrilova array */ diff --git a/src/DDClientLibCpp/CMakeLists.txt b/src/DDClientLibCpp/CMakeLists.txt new file mode 100644 index 0000000..e543550 --- /dev/null +++ b/src/DDClientLibCpp/CMakeLists.txt @@ -0,0 +1,22 @@ + +PROJECT(DDClientLibCpp) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibCpp/INCLUDE/ +) + +#Library configuration +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_LIBRARY( DDClientLibCpp SHARED ${source_files} ) + +target_link_libraries( + DDClientLibCpp + ${CMAKE_THREAD_LIBS_INIT} +) + +install (TARGETS DDClientLibCpp DESTINATION lib) diff --git a/src/DDClientLibCpp/DD_client.cc b/src/DDClientLibCpp/DD_client.cc new file mode 100644 index 0000000..832763d --- /dev/null +++ b/src/DDClientLibCpp/DD_client.cc @@ -0,0 +1,1113 @@ +/* $Id: DD_client.c,v 1.3 2009/04/14 08:37:28 budnik Exp $ */ +/*============================================================== + * DD SYSTEM + * DD_client.c + * V.4.8 + * List of changes: + * November 1995, Version 1.0 + * August 1999 :Access security system was installed by Alexandr Grigoriev (v3.0) + * October 22, 2002 - Communication ideology is changed (V.4.0) + * Oct 29, 2002 - Add DD_GetVersion() and some bags are corrected (V.4.1) + * May 1, 2003 - Network error is developped. (The header receiving is changed): V.4.2 + * Nov 18, 2004 - Cach error is fixed. + * Jun 17, 2007 - Fedorov, V.4.5 Create new VI and Update data requests + * Sep 24, 2007 - Fedorov, V.4.6 Processing of return of Get_Data + * Dec 03, 2007 - Budnik, V.4.7 There may be several sessions with DD Server inside ONE + * Client session. Keep UserHost & UserName + * Oct 18, 2012 - Knizhnikova, V.4.8 new DD_SetTimeInfo() function + *===============================================================*/ + +#include <unistd.h> +#include <stdio.h> +#include <string.h> + +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "DD.hh" + +#ifdef LOG4CXX +log4cxx::LoggerPtr DD_Client::_logger = log4cxx::Logger::getLogger( + "AMDA-Kernel.DD_Client"); +#endif + +/*------------------ GLOBAL STATIC VARIABLES --------------------------*/ + +//extern int errno; + +/*================== FUNCTIONS =================================*/ +/*----------------------- GET User Host-------------------------------*/ + +static size_t unixlen[] = {sizeof(char),sizeof(int),sizeof(float),sizeof(double),sizeof(short)}; + +static xdrproc_t ConvFunc[5] = {(xdrproc_t )xdr_char, (xdrproc_t )xdr_int, (xdrproc_t )xdr_float, (xdrproc_t )xdr_double, (xdrproc_t )xdr_short}; + +DD_Client:: DD_Client() : + idd (DD_CHAR, 0, NULL,1, (void**) malloc(sizeof(void*))), + CurrentData(NULL), + _varNumber(0), + SocketID( -1), + UserID(0), + m1(0X000000FF), + m2( 0X0000FF00), + m3(0X00FF0000), + m4( 0XFF000000), + //Host(NULL), + buffSetVarialbe(NULL), + bufDD_SetTime (NULL), + op(TIMESETREQ), + bufDD_GetData( NULL), + LastPacketFlag(OK), + bufDD_Close (NULL), + opDD_Close(CLOSEINSREQ), + bufDD_AddDataSet(NULL), + opDD_AddDataSet(ADDVIREQ), + Version(VERSION) + + { + UserName[0] = '\0'; + UserHost[0] = '\0'; + RemSerName[0]='\0'; + strcpy(TimeInt, "0000000000001000"); + idd.Variables[0]=NULL; +} + +int DD_Client::GetUserHost() { + int userid; + + userid = getuid(); /* Get a client user ID */ + +#ifdef LOG4CXX + //LOG4CXX_DEBUG(_logger, "DD_Client::GetUserHost - UserId : " << userid); +#endif + + /* UserHost can be set by extern WEB function in case of WEB communicatio, + * or it should be defined as local host if DD_client is installed at USER + * computer + */ + if (UserHost[0] == '\0') { + char HostName[HOSTNAMELENGTH]; + + gethostname(HostName, HOSTNAMELENGTH); /* Get a client host name */ + + struct sockaddr_in addr; + + if (getInfoFromHostName(HostName,addr) != 0) + return NOHOST; + + unsigned int b1, b2, b3, b4; + sscanf(inet_ntoa( addr.sin_addr), "%3u.%3u.%3u.%3u", &b1, &b2, &b3, &b4); + snprintf(UserHost, MAXHOSTLENGTH, "%03u.%03u.%03u.%03u", b1, b2, b3, b4); + +#ifdef LOG4CXX + //LOG4CXX_DEBUG(_logger, "DD_Client::GetUserHost - UserHost : " << UserHost); +#endif + } + return userid; +} + +void DD_Client::setUserHost(const char* host) { + snprintf(UserHost, MAXHOSTLENGTH, "%s", host); +#ifdef LOG4CXX + //LOG4CXX_DEBUG(_logger, "DD_Client::setUserHost - UserHost : " << UserHost); +#endif +} + +int DD_Client::getInfoFromHostName(const char *hostName, struct sockaddr_in &addr) +{ + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = 0; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + struct addrinfo *result; + int s; + + s = getaddrinfo(hostName, NULL, &hints, &result); + + if (s != 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::getIpFromHostName - Cannot get ip from host name " << hostName); +#endif + return NOHOST; + } + + struct sockaddr_in *h; + h = (struct sockaddr_in *) result->ai_addr; + + memcpy(&addr,h,sizeof(struct sockaddr_in)); + + freeaddrinfo(result); + + return 0; +} +/*-------------------------------------------------------------------*/ + +/*------------------ MAKE_CONNECTION ---------------------------*/ +/* + * The function returns opened socket, ready to read and write + */ +int DD_Client::GetSocket() +/* + * Connect with remote server, and returns socket ID + * In case of error return error number according DD_comm.h + */ +{ +/*-------- Variables for resource file -----------------*/ + char rname[PATHLENGTH]; /* name of res file */ + char line[PATHLENGTH]; + char *path; + FILE *resfile; /* resource file */ + +/*---------- Variables for network ---------------------*/ + + int normaddr; +/* + *---------- Getting socket and its address ---------------------*/ +/*---------------- HOST and PORT ------------------------------*/ + if((path = getenv("DDPATH")) == NULL) + { + strcpy(rname,"DD.res"); + } + else + { + strcpy(rname,path); + strcat(rname, "/DD.res"); + } +/* + (void *)strcpy(rname,"./DD.res"); +*/ + if((resfile = fopen(rname,"r")) == NULL) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - Cannot find resource file " << rname); +#endif + + fprintf(stderr,"No resource file, sorry\n"); + exit(1); + } + + fgets(RemSerName, PATHLENGTH-1, resfile); + fgets(line, PATHLENGTH-1, resfile); + fclose(resfile); + + RemSerName[strlen(RemSerName)-1] = '\0'; + sscanf(line,"%5d",&(normaddr)); + + +/*---------------- END of FILE READING --------------------------*/ +/* + *------- Trying to open socket with this address and name --------- + */ + + if((SocketID = socket(AF_INET,SOCK_STREAM,PROTOCOL)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - Socket error "); +#endif + perror("Socket:"); return(-1); + } + +/* Filling full internet address for socket "name" + * this address will be used to get communication point */ + + struct sockaddr_in IntAFAddr; + + if (getInfoFromHostName(RemSerName,IntAFAddr) != 0) + return NOHOST; + + IntAFAddr.sin_port = htons((uint16_t)normaddr); /* Conversion of the port number to + universal net form */ +#ifdef LOG4CXX + //LOG4CXX_DEBUG(_logger, "DD_Client::GetSocket - HostName : " << RemSerName << " - IP : " << inet_ntoa(IntAFAddr.sin_addr) << " - Port : " << IntAFAddr.sin_port); +#endif + + /* Connection to server socket on remote computer */ + int errnum = connect(SocketID,(struct sockaddr *)&IntAFAddr,sizeof(struct sockaddr_in)); + if(errnum < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - Connection to server socket error - " << strerror (errnum)); +#endif + perror("connect"); + return(-1); + } + +/* + * Get Host name and Host ID for security application + */ + if((UserID = GetUserHost()) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::GetSocket - NOHOST error"); +#endif + return(NOHOST); + } + + return SocketID; +} +/*------------------- end of GetSocket ---------------------*/ + +/*==================== Receive From Net ======================*/ +/* + * Smart buffered receiver + */ +int DD_Client::ReceiveFromNet(char *buf, int PacketSize) +{ + int CurLength = 0; + + do + { + int i = 0; + int cc = 0; + while(( (cc = recv(SocketID,buf+ CurLength,PacketSize - CurLength,0)) < 0) && (i < TRY)) i++; + if(cc < 0) return -1; + CurLength = CurLength + cc; + } while(CurLength < PacketSize); + return 1; +} + +/*------------------ Open Virtual Instrument -----------------------*/ +/* + * If no connection, connect to server, then try to order data set and return + * ID if OK or ErrorNumber if not + */ +int DD_Client::DD_SetVariable(char *InstrName) +{ + int InstrID; /* Instrumnet ID to return */ + int Request = OPENINSREQ; + int hostlen,userlen; + char *PUserHost = UserHost, *PUserName = UserName; + /* We need this because XDR works with adresses of pointers */ + +/* If there is no connection, try to get it */ + if(SocketID < 0) + if((SocketID = GetSocket()) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - No connection"); +#endif + return(NOCONNECTION); + } + +/* Encoding request by XDR to buf */ +/* Buffer and stream allocation */ + buffSetVarialbe = (caddr_t)calloc(REQUESTLENGTH, 1); + + xdrmem_create(&xdrs, buffSetVarialbe, REQUESTLENGTH, XDR_ENCODE); + + xdr_int(&xdrs,&Request); + xdr_string(&xdrs, &InstrName, strlen(InstrName)); + +/* Send Open Virtual Instrument request */ + + if( send(SocketID,buffSetVarialbe,REQUESTLENGTH,0) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - Cannot open virtual instrument"); +#endif + perror("DD_SetVariable:"); + free(buffSetVarialbe); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + xdrmem_create(&xdrs, buffSetVarialbe, REQUESTLENGTH, XDR_FREE); + +/*-------- preparation an authorization request ----------------*/ + if(UserName[0] == '\0') strcpy(UserName,NONAME); + hostlen = strlen(UserHost); + userlen = strlen(UserName); + + xdrmem_create(&xdrs, buffSetVarialbe,REQUESTLENGTH, XDR_ENCODE); + + xdr_int(&xdrs,&UserID); + xdr_string(&xdrs, &PUserHost, hostlen); + xdr_string(&xdrs, &PUserName, userlen); +/* fprintf(stderr,"userid %d host %s DD_name %s\n",UserID,UserHost,UserName); */ + +/* Send request */ + if( send(SocketID,buffSetVarialbe,REQUESTLENGTH,0) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - Cannot send request"); +#endif + perror("DD_Set_Variable:"); + free(buffSetVarialbe); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + + free(buffSetVarialbe); + xdr_destroy(&xdrs); + +/* Get reply */ + buffSetVarialbe = (caddr_t)malloc(REPLYLENGTH); +/* + i=0; + while(((cc = recv(SocketID,buff,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; +*/ + if( ReceiveFromNet(buffSetVarialbe, REPLYLENGTH) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetVariable - Cannot receive from net"); +#endif + perror("DD_SET_Variable:"); + free(buffSetVarialbe); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buffSetVarialbe, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&InstrID); + +/* Free all */ + free(buffSetVarialbe); + xdr_destroy(&xdrs); + + return InstrID; +} + +/*----------------------- DD_GetInform -----------------------------*/ +/* + * Returns "OK" if OK, fill DD_Data structure + * Return negative value if error + */ + +int DD_Client::DD_GetInform(int VarID,char *AttrName,DD_data_t **data) +{ + XDR xdrs; + caddr_t bufDD_GetInform = NULL; + int length; + int op = DATAINFOREQ; + int type; /* type of information or error */ + int DimNumbers; + int PacketSize; + u_int count; + u_int MaxNumber; + +/*------------------- Empty static data ------------------------*/ + if(idd.Dimensions != NULL) + { + free(idd.Dimensions); + idd.Dimensions = NULL; + } + if(idd.Variables[0] != NULL) + { + free(idd.Variables[0]); + idd.Variables[0] = NULL; + } + +/*------------------ Check the Name length -----------------------*/ + if(strlen(AttrName) > MAXVARLENGTH) length = MAXVARLENGTH; + else length = strlen(AttrName); + +/*----------- Allocation of memory and stream --------------------*/ + bufDD_GetInform = (caddr_t)calloc(REQUESTLENGTH,1); + xdrmem_create(&xdrs, bufDD_GetInform, REQUESTLENGTH, XDR_ENCODE); + +/*------------------- Encoding the request ----------------------*/ + xdr_int(&xdrs,&op); + xdr_int(&xdrs,&VarID); + xdr_string(&xdrs, &AttrName, length); + +/*------------------------ Send request ---------------------------*/ + if( send(SocketID,bufDD_GetInform,REQUESTLENGTH,0) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot send request"); +#endif + perror("DD_GetInform:"); + free(bufDD_GetInform); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(bufDD_GetInform); + xdr_destroy(&xdrs); + +/*------------------------ Get reply header ------------------------*/ + + bufDD_GetInform = (caddr_t)malloc(REPLYLENGTH); +/* + i=0; + while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; + if(cc < 0) +*/ + if(( ReceiveFromNet(bufDD_GetInform, REPLYLENGTH)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot receive from net"); +#endif + perror("DD_GetInform:"); + free(bufDD_GetInform); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, bufDD_GetInform, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&type); + if(type < 0) + { + free(bufDD_GetInform); + xdr_destroy(&xdrs); + return(type); + } + xdr_int(&xdrs,&DimNumbers); + xdr_int(&xdrs,&PacketSize); + free(bufDD_GetInform); + xdr_destroy(&xdrs); + + idd.DimNumber = DimNumbers; + idd.type = type; + +/*---------------------------- Get Data Packet ----------------------*/ + if(PacketSize > 0) bufDD_GetInform = (caddr_t)malloc(PacketSize); + else + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot Cannot get data packet"); +#endif + return(REPLYRECERR); + } + + if(( ReceiveFromNet(bufDD_GetInform, PacketSize)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot receive from net"); +#endif + perror("DD_GetInform:"); + free(bufDD_GetInform); + return(REPLYRECERR); + } + +/*--------------------- Decoding data packet ------------------------*/ + if(DimNumbers > 0) + { +/*----------- Memory allocation and xdr creating -----------------*/ + xdrmem_create(&xdrs, bufDD_GetInform, (u_int)PacketSize, XDR_DECODE); + +/*----------------- Dimensions decoding -------------------------*/ + if(idd.Dimensions !=NULL) free(idd.Dimensions); + idd.Dimensions = (int *)malloc(DimNumbers*sizeof(int)); + + xdr_array(&xdrs, (caddr_t *)&(idd.Dimensions), + &count, + (u_int )DimNumbers, + unixlen[DD_INT], + (xdrproc_t)xdr_int); + + count = 1; + for(int i=0; i < DimNumbers;i++) + count = count*idd.Dimensions[i]; + MaxNumber = count; + } + else + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetInform - Cannot decoding data packet"); +#endif + free(bufDD_GetInform); + return(REPLYRECERR); + } + +/*---------------- Allocate memory for Variables and decoding ------------------*/ + if(idd.Variables[0] != NULL) free(idd.Variables[0]); + idd.Variables[0] = (int *)malloc(unixlen[type] * MaxNumber); + + xdr_array(&xdrs,((caddr_t*)(&idd.Variables[0])),&count, + MaxNumber, unixlen[type], ConvFunc[type]); + +/*-------------------------- Free all ------------------------------*/ + free(bufDD_GetInform); + xdr_destroy(&xdrs); + + *data = &idd; + return OK; +} + +/*------------------- DD_SETTIME ------------------------------------*/ +/* + * VarID - ID of Data Set + * Time - string in DD type + * Returns 1 if OK and negative in case of err + */ + +int DD_Client:: DD_SetTime(int VarID,char *Time) +{ + int type; + int DoneFlag = 0; + + while(DoneFlag == 0) + { +/* Allocatein memory and stream */ + bufDD_SetTime = (caddr_t)calloc(REQUESTLENGTH, 1); + xdrmem_create(&xdrsDD_SetTime, bufDD_SetTime, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrsDD_SetTime,&op); + xdr_int(&xdrsDD_SetTime,&VarID); + xdr_string(&xdrsDD_SetTime, &Time, TIMELENGTH); + +/* Send request */ + if(( send(SocketID,bufDD_SetTime,REQUESTLENGTH,0)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTime - Cannot send request"); +#endif + perror("DD_SetTime:"); + free(bufDD_SetTime); + xdr_destroy(&xdrsDD_SetTime); + return(REQSENDERR); + } + free(bufDD_SetTime); + xdr_destroy(&xdrsDD_SetTime); + +/* Get reply header */ + + bufDD_SetTime = (caddr_t)malloc(REPLYLENGTH); + + if(( ReceiveFromNet(bufDD_SetTime, REPLYLENGTH)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTime - Cannot receive from net"); +#endif + perror("DD_SetTime:"); + free(bufDD_SetTime); + return(REPLYRECERR); + } + + xdrmem_create(&xdrsDD_SetTime, bufDD_SetTime, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrsDD_SetTime,&type); + + free(bufDD_SetTime); + xdr_destroy(&xdrsDD_SetTime); + + if(type < 0) + { + if(type == CACHTOOREC) sleep((unsigned )(FILEACCMARG)); + else return type; + } + else DoneFlag = 1; + } + return 1 ; +} + +/*------------------- DD_SETTIMEINFO ------------------------------------*/ +/* + * VarID - ID of Data Set + * Time - string in DD type + * RealTime - double : time value pointer points to + * Returns 1 if OK and negative in case of err + */ + +int DD_Client:: DD_SetTimeInfo(int VarID, char *Time, double *RealTime) +{ + int err; + + DD_data_t *data; + + if ((err = DD_SetTime(VarID, Time)) < 0) + { + while ((err == WAITEXTCALL) || (err == TRYAGAIN)) + { + sleep(2); + err = DD_SetTime(VarID, Time); + } + } + + if (err < 1) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTimeInfo - Cannot set time " << Time); +#endif + return err; + } + + if ((err = DD_GetData(VarID, (char *)"Time", TimeInt, &data)) < 0) + { + while ((err == WAITEXTCALL) || (err == TRYAGAIN)) + { + sleep(2); + err = DD_GetData(VarID, (char *)"Time", TimeInt, &data); + } + } + + if (err < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTimeInfo - Cannot get data " << Time); +#endif + return err; + } + if (data->VarNumber < 1) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_SetTimeInfo - OUTOFTIME error " << Time); +#endif + return OUTOFTIME; + } + + *RealTime = DD_Time2Double((char *)data->Variables[0]); + + //BRE - When the corresponding time is the last one of a file, MOREDATA is returned by DDServer. + // => force recall of DD_GetData to open the next file and finish correctly the request + if (err == MOREDATA) + { + if ((err = DD_GetData(VarID, (char *)"Time", TimeInt, &data)) < 0) + { + while ((err == WAITEXTCALL) || (err == TRYAGAIN)) + { + sleep(2); + err = DD_GetData(VarID, (char *)"Time", TimeInt, &data); + } + } + } + + return 1 ; +} + +/*------------------------- DD_GETDATA --------------------------------*/ +/* + * VarID - ID of open virtual instrument + * VarName - Variable name associated with this virtual instrument + * TimeInt - Time interval in DD_time style + * data - returned data + * Return values: + * positives: + * MOREDELAY - call this function again after delay + * MOREDATA - call this function again to complete request + * OK - all data received + * negative value - error (see DD.h) + */ + +int DD_Client::DD_GetData(int VarID,char *VarName,char *TimeInt,DD_data_t **data) +{ + char *xxx=VarName; + int err = DD_GetMultiData(VarID, 1, &xxx, TimeInt, data, 1); + return err; + } + +/*------------------------- DD_GetMultiData() --------------------------------*/ +/*--------------------------------------------------------- + * VarID - ID of open virtual instrument + * VarSize - the size of the array names + * VarNames - array of the variables names + * TimeInt - Time interval in DD_time style + * data - returned data + * Return values: + * positives: + * MOREDELAY - call this function again after delay + * MOREDATA - call this function again to complete request + * OK - all data received + * negative value - error (see DD.h) + */ +int DD_Client::DD_GetMultiData(int VarID,size_t VarSize, char **VarNames,char *TimeInt,DD_data_t **data, int BackFlag) +{ + size_t id; + int *NameLength = NULL; /* Array of lengths */ + int XDRStrLen; /* xdr length of a string */ + int XDRReqlength; // Length in bytes the XDR stream + int op = DATAGETREQ; + int type; /* type of information or error */ + int DimNumbers; + int PacketSize; + u_int count, MaxSize=0; + int i; + + /*-------------------------------------- + * Create a new Current Data empty array + *-------------------------------------*/ + for( int i = 0; i < _varNumber; ++i) { + CurrentData[i].clear(); + } + delete[] CurrentData; + _varNumber = VarSize; + CurrentData = new DD_data_t[_varNumber]; + + /*-------------------------------------------------------------- + * The follows request preparation and send is performed only + * if the priveous data packed is completely received + *--------------------------------------------------------------*/ + if((LastPacketFlag == OK) || (LastPacketFlag == MOREDELAY)) + { + /*--------------------------------------- + * Preparation of the array the name lengths + * Note that the names are cut down to the MAXVARLENGTH + * Calculation the packet size + *---------------------------------------*/ + NameLength = (int *)malloc(sizeof(int)*VarSize); + XDRReqlength = 8; /* the length of the first+last arguments */ + for(id = 0; id < VarSize; id++) + { + if(strlen(VarNames[id]) > MAXVARLENGTH) NameLength[id] = MAXVARLENGTH; + else NameLength[id] = strlen(VarNames[id]); + XDRStrLen = (NameLength[id] / 4) * 4; + if((NameLength[id] % 4) > 0) XDRStrLen += 4; + XDRReqlength += XDRStrLen + 4; // String length + 4 bytes length coding + //fprintf(stderr,"Variable %s, length %d, total %d\n",VarNames[id],XDRStrLen,XDRReqlength); + } + /*-------------------------------- + * The first packet of the request of the standard size + * Allocation corresponding memory and stream + *------------------------------*/ + bufDD_GetData = (caddr_t)calloc(REQUESTLENGTH, 1); + xdrmem_create(&xdrsDD_GetData, bufDD_GetData, REQUESTLENGTH, XDR_ENCODE); + + /* Encoding the request */ + xdr_int(&xdrsDD_GetData,&op); + xdr_int(&xdrsDD_GetData,&VarID); + xdr_string(&xdrsDD_GetData,&TimeInt,TIMELENGTH); + xdr_int(&xdrsDD_GetData,&XDRReqlength); + + /* Send the first request */ + if(( send(SocketID,bufDD_GetData,REQUESTLENGTH,0)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot send the first request"); +#endif + perror("DD_GetData: First Request"); + free(bufDD_GetData); + free(NameLength); + xdr_destroy(&xdrsDD_GetData); + return(REQSENDERR); + } + free(bufDD_GetData); + xdr_destroy(&xdrsDD_GetData); + + /*-------------------------------- + * The Second packet of XDRReqlength size + * Allocation corresponding memory and stream + *------------------------------*/ + bufDD_GetData = (caddr_t)malloc(XDRReqlength); + xdrmem_create(&xdrsDD_GetData, bufDD_GetData, XDRReqlength, XDR_ENCODE); + xdr_int(&xdrsDD_GetData,(int *)(&VarSize)); + for(id = 0; id < VarSize; id++) xdr_string(&xdrsDD_GetData, &VarNames[id], NameLength[id]); + + free(NameLength); + NameLength = NULL; + xdr_int(&xdrsDD_GetData,&BackFlag); + + /* Send the second request */ + if(( send(SocketID,bufDD_GetData,XDRReqlength,0)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot send the second request"); +#endif + perror("DD_GetData:Second Packet"); + free(bufDD_GetData); + xdr_destroy(&xdrsDD_GetData); + return(REQSENDERR); + } + free(bufDD_GetData); + xdr_destroy(&xdrsDD_GetData); + } + + /*----------------------------------------------------------- + * Get the VarSize reply headers and VarSize data + *----------------------------------------------------------*/ + for(id = 0; id < VarSize; id++) + { + /*------------------- + * The header + *-----------------*/ + bufDD_GetData = (caddr_t)malloc(REPLYLENGTH); + if(( ReceiveFromNet(bufDD_GetData, REPLYLENGTH)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot receive header"); +#endif + perror("DD_GetData:Error while header receive"); + free(bufDD_GetData); + return(REPLYRECERR); + } + + xdrmem_create(&xdrsDD_GetData, bufDD_GetData, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrsDD_GetData,&type); + xdr_int(&xdrsDD_GetData,&DimNumbers); + xdr_int(&xdrsDD_GetData,&PacketSize); + free(bufDD_GetData); + xdr_destroy(&xdrsDD_GetData); + + if (type < 0) /* Server returns unrecoverable error */ + { +#ifdef LOG4CXX + LOG4CXX_DEBUG(_logger, "DD_Client::DD_GetMultiData - Server returns " << type << ", no data\n"); +#endif + fprintf(stderr, "DD_GetData: Server returns %d, no data\n", type); + return type; + } + + /*----------- Header is received ----------------------*/ + CurrentData[id].DimNumber = DimNumbers - 1; + CurrentData[id].type = type; + + /*--------------- Receive Data Packet ------------------------------*/ + if(PacketSize > 0) bufDD_GetData = (caddr_t)malloc(PacketSize); + else + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot receive data packet"); +#endif + return(REPLYRECERR); + } + if((ReceiveFromNet(bufDD_GetData, PacketSize)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Cannot receive data packet from web"); +#endif + perror("DD_GetData: Error while data packet receive"); + free(bufDD_GetData); + return(REPLYRECERR); + } + /*----------------- Decoding data packet --------------------*/ + if(DimNumbers > 1) + { + xdrmem_create(&xdrsDD_GetData, bufDD_GetData, (u_int)PacketSize, XDR_DECODE); + count = DimNumbers-1; + /* allocation memory for dimensions */ + CurrentData[id].Dimensions = (int *)malloc((DimNumbers-1)*sizeof(int)); + + xdr_int(&xdrsDD_GetData,&LastPacketFlag); /* Last Paket Indicatort*/ + xdr_int(&xdrsDD_GetData,&CurrentData[id].VarNumber); /* Variables number */ + + if(LastPacketFlag > 2) + { + LastPacketFlag = OK; + CurrentData[id].VarNumber = 0; + free(bufDD_GetData); +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Reply received error"); +#endif + return(REPLYRECERR); + } + + /*----- Decoding dimensions array -------------------*/ + xdr_array(&xdrsDD_GetData, (caddr_t *)&(CurrentData[id].Dimensions), + &count, + (u_int )DimNumbers-1, + unixlen[DD_INT], + (xdrproc_t)xdr_int); + + count = 1; + for(i=0; i < DimNumbers-1;i++) + { + count = count*CurrentData[id].Dimensions[i]; + } + MaxSize = count; + } + else { + if (type != NOVAR) { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_GetMultiData - Reply received error"); +#endif + free (bufDD_GetData); + return (REPLYRECERR); + } else { + CurrentData[id].VarNumber = 0; + } + } + + /*---------- Decoding variables -------------------------*/ + if (CurrentData[id].VarNumber != 0) { + CurrentData[id].Variables = (void **) malloc(CurrentData[id].VarNumber * sizeof(void *)); + } else { + CurrentData[id].Variables = NULL; + } + + for(i = 0; i < CurrentData[id].VarNumber; i++) + { + CurrentData[id].Variables[i] = (void *)malloc(unixlen[type]*MaxSize); + count = MaxSize; + xdr_array(&xdrsDD_GetData,(caddr_t *)(&(CurrentData[id].Variables[i])),&count,MaxSize,unixlen[type], (xdrproc_t)ConvFunc[type]); + } + + /* Free all */ + free(bufDD_GetData); + xdr_destroy(&xdrsDD_GetData); + } + *data = CurrentData; + return(LastPacketFlag); +} + +/*===================================================================*/ + +/*-------------------------- DD_CLOSE --------------------------------*/ +/* + * + * VarID - entry point of ID table + * Returns 1 if OK or negative err + * Close Socket if no VarID more ( this information supplyed by server ) + */ + +int DD_Client:: DD_Close(int VarID) +{ + int RemainedID; /* Server returns number of remained ID */ +/* Allocatein memory and stream */ + bufDD_Close = (caddr_t)calloc(REQUESTLENGTH, 1); + xdrmem_create(&xdrsDD_Close, bufDD_Close, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrsDD_Close,&opDD_Close); + xdr_int(&xdrsDD_Close,&VarID); + +/* Send request */ + if(( send(SocketID,bufDD_Close,REQUESTLENGTH,0)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_Close - Cannot send request " << VarID); +#endif + perror("DD_Close:"); + free(bufDD_Close); + xdr_destroy(&xdrsDD_Close); + return(REQSENDERR); + } + free(bufDD_Close); + xdr_destroy(&xdrsDD_Close); + +/* Get reply header */ + + bufDD_Close = (caddr_t)malloc(REPLYLENGTH); +/* + i = 0; + while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; + if(cc < 0) +*/ + if(( ReceiveFromNet(bufDD_Close, REPLYLENGTH)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_Close - Cannot receive from net " << VarID); +#endif + perror("DD_Close:"); + free(bufDD_Close); + return(REPLYRECERR); + } + + xdrmem_create(&xdrsDD_Close, bufDD_Close, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrsDD_Close,&RemainedID); + if(RemainedID< 0) + { + free(bufDD_Close); + xdr_destroy(&xdrsDD_Close); + return(RemainedID); + } + free(bufDD_Close); + xdr_destroy(&xdrsDD_Close); + + if(RemainedID == 0) + { + shutdown(SocketID,2); + close(SocketID); + SocketID = -1; +/* + UserHost[0] = '\0'; + UserName[0] = '\0'; +*/ + } + + return(1); +} + +DD_Client::~DD_Client() { + + for( int i = 0; i < _varNumber; ++i) { + CurrentData[i].clear(); + } + delete[] CurrentData; +} + +/*------------------------------------------------------------------------------*/ + +/*=============== DATABASE UPDATE FUNCTIONS ====================================*/ +/*------------------ DD_AddDataSet() -------------------------------------------*/ +int DD_Client:: DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName) +{ + + int Err; /* Server returns OK or NOEXEC */ + int length; + int CloseFlag = 0; + +/* If there is no connection, try to get it */ + if(SocketID < 0) + { + if((SocketID = GetSocket()) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_AddDataSet - No connection"); +#endif + return(NOCONNECTION); + } + CloseFlag = 1; // To close Connection at the end + } + +/* Allocatein memory and stream */ + bufDD_AddDataSet = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrsDD_AddDataSet, bufDD_AddDataSet, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrsDD_AddDataSet,&opDD_AddDataSet); + +/* Coding DataSetName */ + if((length = strlen(DataSetName)) > MAXSETLENGTH) length = MAXSETLENGTH; + xdr_string(&xdrsDD_AddDataSet, &DataSetName, length); +/* Coding RemSetID */ + if((length = strlen(RemSetID)) > MAXVARLENGTH) length = MAXVARLENGTH; + xdr_string(&xdrsDD_AddDataSet, &RemSetID, length); +/* Coding BaseName */ + if((length = strlen(BaseName)) > MAXVARLENGTH) length = MAXVARLENGTH; + xdr_string(&xdrsDD_AddDataSet, &BaseName, length); + +/* Send request */ + if(( send(SocketID,bufDD_AddDataSet,REQUESTLENGTH,0)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_AddDataSet - Cannot send request"); +#endif + perror("DD_AddDataSet:"); + free(bufDD_AddDataSet); + xdr_destroy(&xdrsDD_AddDataSet); + return(REQSENDERR); + } + free(bufDD_AddDataSet); + xdr_destroy(&xdrsDD_AddDataSet); + +/* Get reply header */ + bufDD_AddDataSet = (caddr_t)malloc(REPLYLENGTH); + if(( ReceiveFromNet(bufDD_AddDataSet, REPLYLENGTH)) < 0) + { +#ifdef LOG4CXX + LOG4CXX_ERROR(_logger, "DD_Client::DD_AddDataSet - Cannot receive from net"); +#endif + perror("DD_AddDataSet:"); + free(bufDD_AddDataSet); + return(REPLYRECERR); + } + + xdrmem_create(&xdrsDD_AddDataSet, bufDD_AddDataSet, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrsDD_AddDataSet,&Err); + + if(CloseFlag) // Close everything if function established connection + { + shutdown(SocketID,2); + close(SocketID); + SocketID = -1; +/* Session with DD Server was closed, but User Session continues !!!!! */ + /* UserHost[0] = '\0'; + UserName[0] = '\0'; */ + } + return Err; +} +/*-----------------------------------------------------------------------------*/ + +/*---------------------- DD GET VERSION ---------------------------------------*/ +const char *DD_Client:: DD_GetVersion() +/* + * return static pointer to internal string with the DDLIB-SERVER package version + */ +{ + return Version; +} +/*------------------------- End Library -------------------------------*/ diff --git a/src/DDClientLibCpp/DD_time.cc b/src/DDClientLibCpp/DD_time.cc new file mode 100644 index 0000000..bec29c7 --- /dev/null +++ b/src/DDClientLibCpp/DD_time.cc @@ -0,0 +1,291 @@ +/* =================================================================== + * Name : DD_time.c + * Version: : 3.2 + * Author : Andrey Fedorov + * Institution : IKI RAN, Moscow , CESR, Toulouse + * Written on : Tue Feb 21 14:27:10 EET 1995 + * Modified on : Oct 5, 2002 + * List of modifications: + * Oct 5, 2002: V.3.0, New functions DD_Time2Double and Double2DD_Time + * were added. + * March 26, 2010: V.3.1 YEARS up to 2025 + * Sept 05, 2011: V.3.2 SetIntNew => arg TimeKind => to work with 1970-1973 : BR + *==================================================================*/ + +#include "DD_time.hh" +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#define YEARS 56 + +/*---- Static array of days shift from Jun-1-1970 -------*/ +/* 1970 1971 1972 1973 1974 1975 1976 + * 1977 1978 1979 1980 1981 1982 1983 + * 1984 1985 1986 1987 1988 1989 1990 + * 1991 1992 1993 1994 1995 1996 1997 + * 1998 1999 2000 2001 2002 2003 2004 + * 2005 2006 2007 2008 2009 2010 2011 + * 2012 2013 2014 2015 2016 2017 2018 + * 2019 2020 2021 2022 2023 2024 2025 + */ +static double + YearDays[YEARS] = { 0.0, 365.0, 730.0, 1096.0, 1461.0, 1826.0, 2191.0, + 2557.0, 2922.0, 3287.0, 3652.0, 4018.0, 4383.0, 4748.0, + 5113.0, 5479.0, 5844.0, 6209.0, 6574.0, 6940.0, 7305.0, + 7670.0, 8035.0, 8401.0, 8766.0, 9131.0, 9496.0, 9862.0, + 10227.0, 10592.0, 10957.0, 11323.0, 11688.0, 12053.0, 12418.0, + 12784.0, 13149.0, 13514.0, 13879.0, 14245.0, 14610.0, 14975.0, + 15340.0, 15706.0, 16071.0, 16436.0, 16801.0, 17167.0, 17532.0, + 17897.0, 18262.0, 18628.0, 18993.0, 19358.0, 19723.0, 20089.0}; + +static int monthday[2][12] = +{ +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, +{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} +}; +/* so, DAY = monthday[*][month-1]+day -1 */ + +/*================== INTERNAL FUNCTION ====================*/ +/*-------------------- SetInt ----------------------------*/ +void SetInt(dd_tmstr_t *UT) +{ + SetIntNew(UT,DD_TM_UNKNOWN); +} + +void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind) /* Fill int values of dd_tmstr_t */ +/* If the double times field of UT structure is defined, + * this function fills remains fields of Year, day .... separately + */ +{ + static const double msofday = 24.0*60.0*60.0; + static const double msofhour = 60.0*60.0; + static const double msofmin = 60.0; + long daynumber; + double msrest; + int i; + + daynumber = (long)(UT->times / msofday); + for(i=0;i<YEARS;i++) if(daynumber < (long)YearDays[i]) break; + i--; + + switch(timeKind) + { + case DD_TM_DATE : + { + //it's a date + UT->year = i+1970; + UT->day = (int)(daynumber - (long)YearDays[i]); + break; + } + case DD_TM_TIME_INTERVAL : + { + //it's a time interval + UT->year = 0; + UT->day = (int)(daynumber); + break; + } + default : + //compatibility mode + if(i > 3) + { + UT->year = i+1970; + UT->day = (int)(daynumber - (long)YearDays[i]); + } + else + { + UT->year = 0; + UT->day = (int)(daynumber); + } + break; + } + + msrest = UT->times - (double)daynumber * msofday; + UT->hour = (int)(msrest / msofhour); + msrest -= (double)(UT->hour)*msofhour; + UT->min = (int)(msrest / msofmin); + msrest -= (double)(UT->min)*msofmin; + UT->sec = (int)(msrest); + UT->msec = (int)((msrest - (double)(UT->sec))*1000.0); + return; +} + +/*---------------- end of SetInt -----------------------*/ + +/*-----------------SetDouble ---------------------------*/ +void SetDouble(dd_tmstr_t *UT) /* Fill double value of dd_tmstr_t */ +/* If indeger fields of UT is defined, You can calculate double + * field - amount of sec after Jun-1-1970 + */ +{ + if(UT->year >= 1970) + UT->times = (double)UT->msec/1000.0 + + (double)UT->sec + + (double)UT->min*60 + + (double)UT->hour*60.0*60.0 + + (double)UT->day*60.0*60.0*24.0 + + YearDays[(UT->year - 1970)]*60.0*60.0*24.0; + else if(UT->year < YEARS) + UT->times = (double)UT->msec/1000.0 + + (double)UT->sec + + (double)UT->min*60 + + (double)UT->hour*60.0*60.0 + + (double)UT->day*60.0*60.0*24.0 + + YearDays[UT->year]*60.0*60.0*24.0; + else + UT->times = 0.0; + return; +} +/*----------------- end of SetDouble ---------------------*/ + +/*=================== PUBLIC FUNCTIONS ==================*/ +/*------------------- DD_Time2Double --------------------*/ +double DD_Time2Double(const dd_time_t UTstring) +{ + dd_tmstr_t UT; + char year[5] = "0000"; + char day[4] = "000"; + char hour[3]= "00"; + char min[3] = "00"; + char sec[3]= "00"; + char msec[4] = "000"; + + strncpy(year,UTstring,4); + strncpy(day,UTstring+4,3); + strncpy(hour,UTstring+7,2); + strncpy(min,UTstring+9,2); + strncpy(sec,UTstring+11,2); + strncpy(msec,UTstring+13,3); + + sscanf(year,"%4d",&(UT.year)); + sscanf(day,"%3d",&(UT.day)); + sscanf(min,"%2d",&(UT.min)); + sscanf(hour,"%2d",&(UT.hour)); + sscanf(sec,"%2d",&(UT.sec)); + sscanf(msec,"%3d",&(UT.msec)); + + SetDouble(&UT); + return UT.times; +} +/*------------------------------------------------------*/ +/*------------------- Double2DD_Time ---------------------*/ +void Double2DD_Time(char * buffer, double Time) + { + dd_time_t UTstring; + dd_tmstr_t UT; + + UT.times = Time; + SetIntNew(&UT,DD_TM_DATE); // + sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT.year),(UT.day),(UT.hour), (UT.min), (UT.sec),(UT.msec)); + strncpy(buffer, &(UTstring[0]), TIMELENGTH); + } +/*------------------------------------------------------------*/ + +/*================== BACKUP COMPABILITY FUNCTIONS =================*/ +/*---------------------ReadTime --------------------------*/ +/* The fiunction ReadTime read standard for DD time string + * and convert it into dd_tmstr_t structure. + * see DD-time.h + * Return pointer to static internal structure or NULL in case + * of error. + */ +void ReadTime(dd_tmstr_t &UT,char *UTstring) +{ + char year[5] = "0000"; + char day[4] = "000"; + char hour[3]= "00"; + char min[3] = "00"; + char sec[3]= "00"; + char msec[4] = "000"; + + strncpy(year,UTstring,4); + strncpy(day,UTstring+4,3); + strncpy(hour,UTstring+7,2); + strncpy(min,UTstring+9,2); + strncpy(sec,UTstring+11,2); + strncpy(msec,UTstring+13,3); + + sscanf(year,"%4d",&(UT.year)); + sscanf(day,"%2d",&(UT.day)); + sscanf(min,"%2d",&(UT.min)); + sscanf(hour,"%2d",&(UT.hour)); + sscanf(sec,"%2d",&(UT.sec)); + sscanf(msec,"%3d",&(UT.msec)); + + SetDouble(&UT); +} +/*-------------------- end of ReadTime ------------------------*/ + +/*---------------------- Write Time ---------------------------*/ +/* Function Write time convert use only double times field + * of dd_tmstr_t structure to print time in DD style + * in internal static string. The integer fields redefined. + * Function return string pointer. + */ + +char *WriteTime(dd_tmstr_t *UT) +{ + static dd_time_t UTstring; + + SetIntNew(UT,DD_TM_DATE); + sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT->year),(UT->day),(UT->hour), + (UT->min), (UT->sec),(UT->msec)); + return(UTstring); +} +/*------------------- end of WriteTime -------------------*/ + +void WriteFmtTime(dd_tmstr_t *UT,char *UTstring) + { + SetIntNew(UT,DD_TM_DATE); + sprintf(UTstring,"%04d:%03d:%02d:%02d:%02d",(UT->year),(UT->day),(UT->hour), + (UT->min), (UT->sec)); + } + +/*=================== Functions for INTERBALL DECODERS ==============*/ +/*---------------------- UT 2 DOUBLE ---------------------*/ +dd_tmstr_t *UT2double(unsigned *ut) +/* Fill the standard structure with double too using as + * argument 7 int length array in Gavrilova Passport Standard + */ +{ +static dd_tmstr_t UT; +int visocos; + +if(ut[0]%4 == 0) visocos = 1; else visocos = 0; +UT.year = ut[0]; +UT.day = monthday[visocos][ut[1] - 1]+ut[2] - 1; +UT.hour = ut[3]; +UT.min = ut[4]; +UT.sec = ut[5]; +UT.msec = ut[6]; + +SetDouble(&UT); +return(&UT); +} +/*-------------------------------------------------------*/ +/*---------------- DOUBLE 2 UT --------------------------*/ +/* + * Converts Standard DD double time to Gavrilova UT array + */ +unsigned *Double2UT(double t) +{ + static unsigned UT[7]; + dd_tmstr_t tm; + int i,visocos; + + tm.times = t; + SetIntNew(&tm,DD_TM_DATE); + if(tm.year % 4 == 0) visocos = 1; else visocos = 0; + i = 0; + while((i < 12) && (tm.day >= monthday[visocos][i])) i++; + UT[0] = tm.year; + UT[1] = i; + UT[2] = tm.day +1 - monthday[visocos][i-1]; + UT[3] = tm.hour; + UT[4] = tm.min; + UT[5] = tm.sec; + UT[6] = tm.msec; + + return( (unsigned *)UT); +} +/*=======================================================================*/ diff --git a/src/DDClientLibCpp/INCLUDE/DD.hh b/src/DDClientLibCpp/INCLUDE/DD.hh new file mode 100644 index 0000000..ecd479a --- /dev/null +++ b/src/DDClientLibCpp/INCLUDE/DD.hh @@ -0,0 +1,219 @@ +/*================================================================================================= + * DD SYSTEM + * DD.h + * Version: 5.2 + * Description: The public header to use DD library libDD.a + * List of changes: + * Apr. 17, 2002 Fedorov, - New error constant to interrupt the + * transmission if data dimensions are changed from file + * to file + * Nov 18, 2004 - V.4.2 - Fedorov, New errors for CACH manipulating + * Jun 17, 2007 - V.4.6 Fedorov New requestes and external executables + * Aug 02, 2007 - V.4.7 Fedorov Modification of call external executables + * Sep 24, 2007 - V.5.0 Fedorov New status of Get Data: MOREDELAY + * May 21, 2008 - V.5.1 Fedorov New Status of SetTime: CTIMEISSHIFTED + * Oct 18, 2012 - V.5.2 Knizhnikova New DD_SetTimeInfo() function + * Dec 15, 2012 - Fedorov, V.6.0. DD_GetMultiData(). Request structure is very changed, CurrentData is not a global structure + *=================================================================================================*/ + +#ifndef DD_H_ +#define DD_H_ + + +#include "DD_comm.hh" +#include "DD_Access.hh" +#include "DD_time.hh" + +#ifdef LOG4CXX +#include <log4cxx/logger.h> +#endif + +#define VERSION "V.6.0" + +class DD_Client { +private: + /* variable for DD_GetInform */ + DD_data_t idd; + + +public: + + DD_data_t *CurrentData; /* Data block received recently */ + int _varNumber = 0; + + int SocketID; /* Global socket id for this communication session */ + char UserName[USRLENGTH]; /* string for user name */ + char UserHost[MAXHOSTLENGTH]; /* IP of user's host in a string form */ + int UserID; /* ID of user at the user's host */ /* User's ID at a local client host */ + + + unsigned int m1 ; + unsigned int m2 ; + unsigned int m3 ; + unsigned int m4 ; + //struct hostent *Host; /* name & internet (32b) address for + // remout hosts (see netdb.h) */ + char RemSerName[PATHLENGTH]; /* name of remote server */ + + //struct sockaddr_in IntAFAddr; /* structure of internet address of type AF_INET + // see <netinet/in.h> + // to get name of socket we should + // to convert pointer to this structure + // to pointer to "srtruct sockaddr" where + // all fields are "char array". */ + + caddr_t buffSetVarialbe; + XDR xdrs; + + /* variable for DD_SetTime */ + caddr_t bufDD_SetTime; + XDR xdrsDD_SetTime; + int op; + char TimeInt[17]; + + /* variable for DD_GetData */ + caddr_t bufDD_GetData ; + XDR xdrsDD_GetData; + int LastPacketFlag; + + /* variable for DD_Close*/ + caddr_t bufDD_Close; + XDR xdrsDD_Close; + int opDD_Close; + + /* variable for DD_AddDataSet */ + caddr_t bufDD_AddDataSet; + XDR xdrsDD_AddDataSet; + int opDD_AddDataSet; + + /* variable for DD_GetVersion */ + const char *Version; + + DD_Client(); + + ~DD_Client(); + + /*------------------- FUNCTIONS ---------------------------*/ + int ReceiveFromNet(char *buf, int PacketSize); + + int GetUserHost(); + + void setUserHost(const char* host); + + int getInfoFromHostName(const char *hostName, struct sockaddr_in &addr); + + int GetSocket(); + + int DD_SetVariable(char *VarName); + /* + * VarName - full name of variable <project>:<instrument>:<Variable> + * Returns VarID or negative in case of error (see bellow) + */ + + int DD_GetInform(int VarID,char *AttrName, DD_data_t **data); + /* + * VarID - Variable ID from DD_SetVariable + * AttrName - name of attribute ( defined by konvention ) + * data - address of data structure + * Returns 1 if OK and negative value in case of error (see bellow) + */ + + int DD_SetTime(int VarID, char *Time); + /* + * VarID - Variable ID from DD_SetVariable + * Time - string defined in DD_time.h + * Returns 1 if OK and negative value in case of error (see bellow) + */ + + int DD_SetTimeInfo(int VarID, char *Time, double *RealTime); + /* + * VarID - Variable ID from DD_SetVariable + * Time - string defined in DD_time.h + * RealTime - time pointer was set to + * Returns 1 if OK and negative value in case of error (see bellow) + */ + + int DD_GetData(int VarID, char *VarName, char *TimeInt, DD_data_t **data); + /* + * VarID - Variable ID from DD_SetVariable + * VarName - Name of requested Variable + * TimeInt - String of Time interval in DD_time style + * data - address of data structure + * Returns 1 if OK and negative value in case of error (see bellow) + */ + + int DD_GetMultiData(int VarID,size_t VarSize, char **VarNames,char *TimeInt,DD_data_t **data, int BackFlag); + /* + * VarID - Variable ID from DD_SetVariable + * VarSize - number of variables to return + * VarNames - the array of Names of the requested Variable + * TimeInt - String of Time interval in DD_time style + * data - Data structures array + * BackFlag - 0 - pointer is at the lasy position, 1 - pointer returns to the start point + * Returns 1 if OK and negative value in case of error (see bellow) + */ + + int DD_MovePoint(int VarID, int RecordNumber); + /* + * VarID - Open virtual instrument ID + * int RecordNumber - +/- records to move + * Move pointer in the open instrument and return 1 or negative if error + */ + + int DD_Close(int VarID); + /* + * VarID - Variable ID from DD_SetVariable + * Returns 1 if OK and negative value in case of error (see bellow) + */ + + const char *DD_GetVersion(); + /* + * return static pointer to internal string with the DDLIB-SERVER package version + */ + + /*----------- Data Update functions -----------------------------------*/ + int DD_AddDataSet(char *DataSetName, char *RemSetID, char *BaseName); + /* + * Request for new VI. See ../DOC/TECHDOC/DDServFunct.html + */ + +private: +#ifdef LO4CXX + static log4cxx::LoggerPtr _logger; +#endif +}; +/*--------------------- CONSTANTS -----------------------------------------*/ +#define MOREDATA 1 /* There is data, but we have to call GetData again right now*/ +#define MOREDELAY 2 /* There is data, but we have to call GetData again after delay */ +#define OK 0 /* It is last data packet */ +#define NOCONNECTION -1 +#define TOOMANYREQ -2 +#define REQSENDERR -3 +#define REPLYRECERR -4 +#define NOID -5 +#define NOREFFILE -6 +#define NOTIMESFILE -7 +#define NOINFOFILE -8 +#define NOVAR -9 +#define OUTOFTIME -10 +#define CACHERR -11 /* The error occured when program manipulated the cach */ +#define CACHTOOREC -33 /* Off files in the CASH are created less then 5 sec ago */ +#define WAITEXTCALL -34 /* Server Waits external call finish */ +#define TRYAGAIN -35 /* Times file is locked. This request should be repeated again */ +#define NODATAATTIME -36 /* Requested time is inside NODATA time interval */ +#define GAPISSMALL -37 /* Gap is too small to call external archive */ +#define CTIMEISSHIFTED -38 /* The request was in NoData interval, try again with time at the end */ +#define DATAFILEERR -12 /* The error while manipulate with data file */ +#define ENVIRERROR -13 /* Error in Environments */ +#define NOPOINTER -14 /* The pointer points nowhere, SetTime were failed */ +#define INTSERERR -15 /* Server internal error */ +#define TIMEINEMPTY -16 /* No data for specified time interval */ +#define NOEXEC -17 /* No executable */ + +#define DD_SHORT 4 +#define DD_INT 1 +#define DD_FLOAT 2 +#define DD_DOUBLE 3 +#define DD_CHAR 0 + +#endif /* DD_H_ */ diff --git a/src/DDClientLibCpp/INCLUDE/DD_Access.hh b/src/DDClientLibCpp/INCLUDE/DD_Access.hh new file mode 100644 index 0000000..a1d3b10 --- /dev/null +++ b/src/DDClientLibCpp/INCLUDE/DD_Access.hh @@ -0,0 +1,93 @@ +/* ====================================================== + * + * DD_Access.h + * V.2.0 + * Last revision: Oct 7, 2002 + * List of revisions: 1997 - version 1.0 + * Oct 7, 2002 - version 2.0 (update a little ) + */ + +#define MAXHOSTLENGTH 16 /* IP-address: "255.255.255.255\0" */ +#define USRLENGTH 21 /* Length of UserName: + \0 */ +#define TICKETLENGTH 9 /* Length of passwd: 8 + \0 */ +#define HOSTNAMELENGTH 120 /* Length of the user host name */ +#define USERCASHLEN 100 /* Size of user_ticket.nc file must be 300 */ +#define NONAME "no_name\0" /* Name of user in case of non-WEB connection */ +#define ACCINSTR "iball:acc:all" /* Instrument which watch the access */ +#define TICKET_PATH "/ACC/user_ticket.nc" +#define USERREFNAME "/ACC/user_info.nc" +#define LOGFILE "/ACC/login.log" + +/*------------ Errors of ACCESS ---------------------*/ +#define NOPERMISSION -100 +#define NOHOST -101 +#define NOUSERSFILE -102 + +/*--------------- Extern global variables -------------------*/ +extern char UserName[USRLENGTH]; /* defined in DD_client.c */ +extern char UserHost[MAXHOSTLENGTH]; /* defined in DD_client.c */ +extern int UserID; /* defined in DD_client.c */ + +/*--------------- Extern Functions ---------------------------*/ +extern int FillStruct (int argc, void **argv); +/* This function used to set up the host address from IDL (when WWW access used) + * Arguments allocation is as follows: + * UserName - 0 + * UserHost - 1 + * Location: DD_idl.c -> DD_idl.so +*/ + +extern int GetTicket(int UID, char *HostName, int DD_user_id); +/* Description: This function find the user data in user_cash.nc + * If O'k rewrite the line with new time. + * In case of a new user, remove the first line with + * older time data then a current time + 4.5 hours. + * + Takes 3 arguments: UserId (id in the romote host) + Remote host address(string,like "193.232.6.60\0") + DD_user_id(can see in user_info.nc) + + Returns 0 if O'k or NOPERMISSIONS, or ERROR + + If DD_log_name equal NULL searching for UserId, IP-address + If DD_log_name nonequal NULL searching for IP-address,DD_log_name* + * + */ +extern int CheckTicket(char *NameUsr, char *Ticket); +/* Description: This function check if user exosts + * in user_info.nc file. Returns DD_id if O'k. + * It returns NOPERMISSION or other errors + */ + +extern int ShowTicket(int userid, char *hostname, char *DD_name); +/* + * Show if user has authorisation to work + */ + +extern int LoginRequest(char *UserPasswd, char *UserLogin, char *HostName); +/* Description: Library function for client-server using. + * Send ID, Password,UserLogin, and host to server. + * Compares the information with your {id,hostname and other}. + * Returns 0 if O'k, or a negative value in case + * of "NOPERMISSION" or error. + * + */ +extern int SetUser(int UserID, char *HostName, char *LogName); +/* Description: Library function for client-server using. + * Send UserID, HostName to server. + * Compares the information with your {id,hostname}. + * Returns 1 if O'k, or a NOPERMISSION, or error number + */ + +extern int CheckID(char *NameUsr); +/* Description: This function check the user name in user_info.nc file. + * Returns DD_id if exists. + * It returns NOPERMISSION or other errors + */ + +extern void Put2Log(int UID, char *Host, char *LogName, int error); +/* Description: This function logs a user's ID, IP-address of a local host, + * login name and permission information into log file. + * + */ + diff --git a/src/DDClientLibCpp/INCLUDE/DD_comm.hh b/src/DDClientLibCpp/INCLUDE/DD_comm.hh new file mode 100644 index 0000000..ebde965 --- /dev/null +++ b/src/DDClientLibCpp/INCLUDE/DD_comm.hh @@ -0,0 +1,426 @@ +/*================================================================================= + * DD SYSTEM base package + * DD_Server DD_Client library + * DD_comm.h + * V. 5.6 + * 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 <baseID> <remSetID> <ddSetID> + * 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 + *===================================================================================*/ +#ifndef DD_COMM_H_ +#define DD_COMM_H_ +#include <stdio.h> +#include <sys/errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> +#include "DD.hh" +#include "DD_Access.hh" + +#ifdef SOLARIS +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> /* internet stile addres */ +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/rpc.h> +#endif /* SOLARIS */ + +#ifdef HPUX +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <sys/un.h> +#include <rpc/xdr.h> +#include <rpc/rpc.h> +#endif + +#ifdef OSF1 +#include <sys/socket.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <rpc/xdr.h> +#endif /* OSF1 */ + +#ifdef LINUX +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <rpc/rpc.h> +#include <rpc/xdr.h> +#endif /* LINUX */ + + +#ifdef SUNOS +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <netinet/in.h> +#include <netdb.h> +#include <rpc/xdr.h> +#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 + 4 */ +#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/createVI.php %s %s %s" /* Format to call to create new VI */ +#define GETNEWDATACALL "php %s/getData%s.php %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" + +/*------------- 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: + * + * <LastPacketFlag> | + * <Dim> | | + * <.....> | Dim_Number | Data_Size bytes + * <Dim> | | + * <data> | + * ..... | only for real data | + * <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: + * <OPENINSREQ><ID/Eroor><EMPTY><EMPTY> + * on Constant Info request: + * <DATAINFOREQ><Type/Error><Dim_Number><Data_Size><DataPacket> + * on Set pointer by StartTime: + * <SETTIMEREQ><EMPTY/Error><EMPTY><EMPTY> + * on Get Data by TimeInt : + * <DATAGETREQ><Type/Error><Dim_Numbers><Data_Size><LastRecordFlag><DataPacket> + * on Move pointer with records number + * <MOVPOINTREQ><EMPTY/Error><EMPTY><EMPTY> + * on Close Virtual Instrument + * <CLOSEINSREQ><RemID/Error><EMPTY><EMPTY> + */ + +/*-------------------- TYPEDEF ---------------------------*/ + + struct DD_data_t { + int type; /* Type of variable in netcdf style */ + int DimNumber; /* number of dimensions */ + int *Dimensions; /* Dimensions array + * fastest change is last */ + int VarNumber; /* Dimension of variable array */ + void **Variables;/* Variables array pointer + * It is static array refreshed + * each call + */ + DD_data_t(int pType, int pDimNumber, int *pDimensions, int pVarNumber, void **pVariables): + type(pType), + DimNumber(pDimNumber), + Dimensions(pDimensions), + VarNumber(pVarNumber), + Variables(pVariables) {} + + DD_data_t(DD_data_t& pData): + type(pData.type), + DimNumber(pData.DimNumber), + Dimensions(pData.Dimensions), + VarNumber(pData.VarNumber), + Variables(pData.Variables) {} + + DD_data_t() : + type(0), + DimNumber(0), + Dimensions(NULL), + VarNumber(0), + Variables(NULL) {} + + void clear() { + if(Dimensions != NULL) + { + free(Dimensions); + Dimensions = NULL; + } + if(Variables != NULL) + { + for(int i = 0; i< VarNumber; i++) + free(Variables[i]); + free(Variables); + Variables = NULL; + VarNumber = 0; + } + + } + ~DD_data_t() { + clear(); + } + } ; + +typedef struct { 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 ------------*/ + 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; /* Dimensions of Variable */ + /*--- 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); +/* + * 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 GetData(int ID, char *Name, char *TimeInterval); +/* Name - string name of requested variable, + * 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 ----------------------------------*/ + +/*------------------ 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); + +#endif /* DD_COMM_H_ */ diff --git a/src/DDClientLibCpp/INCLUDE/DD_time.hh b/src/DDClientLibCpp/INCLUDE/DD_time.hh new file mode 100644 index 0000000..97bad08 --- /dev/null +++ b/src/DDClientLibCpp/INCLUDE/DD_time.hh @@ -0,0 +1,63 @@ +/* This is header file for working with DD time */ +/* V.4.1 */ +/* name: DD_time.h + * Author: Andrey Fredorov + * Institution: IKI RAN + * Date: 21-Feb-1995 + * Last update Sept 05, 2011 + * Sept 05, 2011: V.3.2 SetIntNew => arg TimeKind => to work with 1970-1973 : BR + */ +#ifndef DD_TIME_H_ +#define DD_TIME_H_ + +#define TIMELENGTH 17 + +typedef char dd_time_t[TIMELENGTH]; /* YYYYDDDHHMMSSMLS */ + +/* ---------------- Functions prototypes ----------------------*/ +extern double DD_Time2Double(const dd_time_t DD_Time); +/* Convert string to double and return. + * Return negative value in case of error string format + */ +extern void Double2DD_Time(char *, double Time); +/* Convert double Time value into string form and return pointer to static string + * allocated INSIDE the library. Thus the value is renoveted each function call. + */ + +/*---------------- Backup compability with V.3.0 and earlier ----------*/ +typedef struct { double times; /* time sec from 1970 */ + int year; + int day; + int hour; + int min; + int sec; + int msec; + } dd_tmstr_t ; + + +extern void ReadTime(dd_tmstr_t &UT,char *UTstring); /* Read time from sring and fill static + * structure defined IN function. + * Returns pointer of strusture */ +extern char *WriteTime(dd_tmstr_t *UT); /* Get pointer of time structure + * and convert it into string + * Function returns pointer of + * internal string */ + +extern void WriteFmtTime(dd_tmstr_t *UT,char *UTstring); + +extern void SetDouble(dd_tmstr_t *UT); /* Fill double value of dd_tmstr_t */ + +typedef enum {DD_TM_UNKNOWN, DD_TM_TIME_INTERVAL, DD_TM_DATE} t_DDTimeKind; + +extern void SetInt(dd_tmstr_t *UT); /* Fill int values of dd_tmstr_t */ +extern void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind); + +/*------- Functions for DECODERS ------------------------ + *These functions works with with Gavrilova's UT representation */ +extern dd_tmstr_t *UT2double(unsigned *UT); /* Set standard time + * structure and return + * its pointer + */ +extern unsigned *Double2UT(double Time); /*Converts Double to Gavrilova array */ + +#endif /* DD_TIME_H_ */ diff --git a/src/TOOLS/COMMON/DD_Access_cl.c b/src/TOOLS/COMMON/DD_Access_cl.c new file mode 100755 index 0000000..516b09a --- /dev/null +++ b/src/TOOLS/COMMON/DD_Access_cl.c @@ -0,0 +1,187 @@ +/* + *-------------------- DD_ACCESS ------------------------------- + * + * name: DD_Access.c + * Version: 4.0 + * author: Alexander Grigoriev, Andrei fedorov + * date : Oct 13, 2002 + * Description: Set of CLIENT function for access to DD system + * + * List of revisions: + * March 1999 V1.0 + * 20 Oct 1999 ; ShowTicket was corrected. V2.0 + * 28 Oct 1999 ; Added LOGINS,ddcheck V3.0 + * Oct 13, 2002 - revised by A. Fedorov V4.0 + * see technical doc + */ +#include <limits.h> +#include <unistd.h> +#include <time.h> +#include <DD.h> +#include <DD_comm.h> +#include <DD_Access.h> + +/*=========== Global Variables ===============================*/ +extern int SocketID; /* The socket is defined in DD_client.c */ +/*================= FUNCTIONS ================================*/ + +/*------------------------ LoginRequest -------------------------------*/ +LoginRequest(char *UserPasswd, char *DDUserName, char *Host) +{ + static caddr_t buf = NULL; + static XDR xdrs; + int cc,i, hostlen, ticketlen, userlen; + int op = GETTICKETREQ; + int ServerReply = NOPERMISSION; + +/*------------------CONNECTNION to SERVER---------------------------*/ + + /* If there is no connection, try to get it */ + if(SocketID < 0) + if((SocketID = GetSocket()) < 0) return(NOCONNECTION); + +/*---------------------REQUEST TO SERVER-----------------------------*/ + + if(Host != NULL) /* It is WEB client (not local) */ + { + if(strlen(Host) > MAXHOSTLENGTH-2) Host[MAXHOSTLENGTH-1] = '\0'; + } + else Host = UserHost; /* Local client */ + hostlen = strlen(Host); + ticketlen = strlen(UserPasswd); + userlen = strlen(DDUserName); + +/* Allocation memory and stream */ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrs,&op); + +/* Send request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_GetTicket:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_FREE); + buf = (caddr_t)realloc(buf,REQUESTLENGTH); + + xdrmem_create(&xdrs, buf,REQUESTLENGTH , XDR_ENCODE); + xdr_int(&xdrs,&UserID); /* user's ID on the local host */ + xdr_string(&xdrs, &DDUserName, userlen); /* DD_login name */ + xdr_string(&xdrs, &UserPasswd, ticketlen); /* user's DD-password */ + xdr_string(&xdrs, &Host, hostlen); /* IP-address of the local host */ + +/* Send request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_GetTicket:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + +/* Get reply header */ + + buf = (caddr_t)malloc(REPLYLENGTH); + i =0; + while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; + if(cc < 0) + { + perror("DD_GetTicket:"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&ServerReply); + + free(buf); + xdr_destroy(&xdrs); + + shutdown(SocketID,2); + close(SocketID); + SocketID = -1; + return ServerReply; +} + +/* + *------------------------ SETUSER -------------------------------*/ +/* + * Description: Library function for client-server using. + * Send UserID, HostName to server. + * Compares the information with your {id,hostname}. + * Returns 1 if O'k, or a NOPERMISSION, or error number + */ +int SetUser(int UserIDLocal, char *Host, char *DDUserName) +{ + + static caddr_t buf = NULL; + static XDR xdrs; + int cc,i, hostlen, ticketlen, userlen; + int op = SHOWTICKETREQ; + int ServerReply = NOPERMISSION; + +/*------------------CONNECTION to SERVER---------------------------*/ + if(SocketID < 0) + if((SocketID = GetSocket()) < 0) return(NOCONNECTION); + +/*---------------------REQUEST TO SERVER-----------------------------*/ + +/* Check the HostName length */ + if(strlen(Host) > MAXHOSTLENGTH) hostlen = MAXHOSTLENGTH; + else hostlen = strlen(Host); + if(strlen(DDUserName) > USRLENGTH) userlen = USRLENGTH; + else userlen = strlen(DDUserName); + +/* Allocation memory and stream */ + buf = (caddr_t)malloc(REQUESTLENGTH); + xdrmem_create(&xdrs, buf, REQUESTLENGTH, XDR_ENCODE); + +/* Encoding the request */ + xdr_int(&xdrs,&op); + xdr_int(&xdrs,&UserID); + xdr_string(&xdrs, &Host, hostlen); + xdr_string(&xdrs, &DDUserName, userlen); +/* printf("UserID, HostName just more : %d %s\n",UserID,HostName);*/ +/* Send request */ + if((cc = send(SocketID,buf,REQUESTLENGTH,0)) < 0) + { + perror("DD_GetTicket:"); + free(buf); + xdr_destroy(&xdrs); + return(REQSENDERR); + } + free(buf); + xdr_destroy(&xdrs); + +/* Get reply header */ + + buf = (caddr_t)malloc(REPLYLENGTH); + i =0; + while(((cc = recv(SocketID,buf,REPLYLENGTH,0)) < 0) && (i < TRY)) i++; + if(cc < 0) + { + perror("DD_SetUser:"); + free(buf); + return(REPLYRECERR); + } + + xdrmem_create(&xdrs, buf, REPLYLENGTH, XDR_DECODE); + xdr_int(&xdrs,&ServerReply); + + free(buf); + xdr_destroy(&xdrs); + shutdown(SocketID,2); + close(SocketID); + return(ServerReply); + + +} +/*############################################################################*/ diff --git a/src/TOOLS/DDCheckUser/CMakeLists.txt b/src/TOOLS/DDCheckUser/CMakeLists.txt new file mode 100644 index 0000000..d56e561 --- /dev/null +++ b/src/TOOLS/DDCheckUser/CMakeLists.txt @@ -0,0 +1,23 @@ + +PROJECT(DDCheckUser) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibC/INCLUDE/ +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* + ../COMMON/DD_Access_cl.c +) + +ADD_EXECUTABLE (DDCheckUser ${source_files} ) + +target_link_libraries( + DDCheckUser + DDClientLibC +) + +install (TARGETS DDCheckUser DESTINATION bin) diff --git a/src/TOOLS/DDCheckUser/DD_Check.c b/src/TOOLS/DDCheckUser/DD_Check.c new file mode 100755 index 0000000..e25f7c4 --- /dev/null +++ b/src/TOOLS/DDCheckUser/DD_Check.c @@ -0,0 +1,41 @@ +/*============================================================= + *-------------------- DD_CHECK ------------------------------- + * V2.0 + * name: DD_check.c + * author: Alexandr Grigoriev, Andrei Fedorov + * date : Oct 30 2002 + * + * Description: Check for the current permission to work + * Uses with WEB interface + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <DD_Access.h> + +main (int argc, char *argv[]) +/* + * LocalID - the Unix ID if user, invoking this program + * LogName - the DD login name for specific user + * HostName - current local host (in 255.255.255.255 form) + */ +{ + int length; + char LogName[USRLENGTH],HostName[MAXHOSTLENGTH]; + int LocalID; + + LocalID=getuid(); + + if((argc == 3)) + { + if((length = strlen(argv[2])) >= USRLENGTH) length = USRLENGTH-1; + strncpy(LogName,argv[2],length); LogName[length] = '\0'; + if((length = strlen(argv[1])) >= MAXHOSTLENGTH) length = MAXHOSTLENGTH-1; + strncpy(HostName,argv[1],length); HostName[length] = '\0'; + } + else return 2; + + return SetUser(LocalID,HostName,LogName); + +} diff --git a/src/TOOLS/DDHtmlLogin/CMakeLists.txt b/src/TOOLS/DDHtmlLogin/CMakeLists.txt new file mode 100644 index 0000000..8334af0 --- /dev/null +++ b/src/TOOLS/DDHtmlLogin/CMakeLists.txt @@ -0,0 +1,23 @@ + +PROJECT(DDHtmlLogin) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibC/INCLUDE/ +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* + ../COMMON/DD_Access_cl.c +) + +ADD_EXECUTABLE (DDHtmlLogin ${source_files} ) + +target_link_libraries( + DDHtmlLogin + DDClientLibC +) + +install (TARGETS DDHtmlLogin DESTINATION bin) diff --git a/src/TOOLS/DDHtmlLogin/DD_htmllogin.c b/src/TOOLS/DDHtmlLogin/DD_htmllogin.c new file mode 100755 index 0000000..d534af5 --- /dev/null +++ b/src/TOOLS/DDHtmlLogin/DD_htmllogin.c @@ -0,0 +1,53 @@ +/*============================================================= + * DD HTML LOGIN + * + * name: DD_htmllogin.c + * author: Alexandr Grigoriev, Andrei fedorov + * date : Oct 30, 2002 + * sinopsis: + * + * usage: DD_htmllogin UserLogin UserPasswd HostName + * UserPasswd - password no longer than TICKETLENGTH - 1 + * UserLogin - login name for DD System + * HostName - local host name (in 255.255.255.255 form) + * + * Description: Login to DD system and taking a ticket. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <DD_Access.h> +#include <DD.h> +#include <DD_comm.h> + +/*=========== Global Variables ===============================*/ + + +main (int argc, char *argv[]) +{ + int length; + char HostName[MAXHOSTLENGTH]; + char UserLogin[USRLENGTH]; + char UserPasswd[TICKETLENGTH];/* password of user, logged in*/ + int DD_access = NOPERMISSION; + + if(argc > 3) + { + + if((length = strlen(argv[1])) >= USRLENGTH) length = USRLENGTH-1; + strncpy(UserLogin,argv[1],length); UserLogin[length] = '\0'; + if((length = strlen(argv[2])) >= TICKETLENGTH) length = TICKETLENGTH -1; + strncpy(UserPasswd,argv[2],length); UserPasswd[length] = '\0'; + if((length = strlen(argv[3])) >= MAXHOSTLENGTH) length = MAXHOSTLENGTH-1; + strncpy(HostName,argv[3],length); HostName[length] = '\0'; + } + else + { + exit(2); + } + + return LoginRequest(UserPasswd, UserLogin, HostName); + +} diff --git a/src/TOOLS/DDLogin/CMakeLists.txt b/src/TOOLS/DDLogin/CMakeLists.txt new file mode 100644 index 0000000..4827f63 --- /dev/null +++ b/src/TOOLS/DDLogin/CMakeLists.txt @@ -0,0 +1,23 @@ + +PROJECT(DDLogin) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibC/INCLUDE/ +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* + ../COMMON/DD_Access_cl.c +) + +ADD_EXECUTABLE (DDLogin ${source_files} ) + +target_link_libraries( + DDLogin + DDClientLibC +) + +install (TARGETS DDLogin DESTINATION bin) diff --git a/src/TOOLS/DDLogin/DD_login.c b/src/TOOLS/DDLogin/DD_login.c new file mode 100755 index 0000000..443e9aa --- /dev/null +++ b/src/TOOLS/DDLogin/DD_login.c @@ -0,0 +1,60 @@ +/* + *-------------------- DD_LOGIN ------------------------------- + * + * name: DD_login.c + * version: 2.0 + * author: Alexandr Grigoriev, Andrei Fedorov + * date : March 1999 + * Description: Login to DD_System for 4 hours. + * + * List of revisions: + * March 1999 - Version V.1.0 + * Oct 13, 2002 - V.2.0 by Fedorov + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef LINUX +#include <pwd.h> +#include <unistd.h> +#endif +#include <DD_Access.h> +#include <DD_time.h> + +/*=========== Global Variables ===============================*/ + +/*================= Main =====================================*/ +int main (int argc, char *argv[]) +{ + char *Host = NULL; + char DDUserName[USRLENGTH]; /* Login name in DD system */ + char UserPasswd[TICKETLENGTH]; /* Password for DD System */ + + int DD_Access = 0; + if(argc != 3) {printf("User and passwd must be gived in argmentl\n"); return (0);} + + +/*---------------Login------NewUser-------------------------*/ + + strncpy(DDUserName, argv[1], USRLENGTH - 1); + DDUserName[USRLENGTH-1] = '\0'; + if(strlen(DDUserName) < 2) {printf("User login should be longer than 3 chars\n"); return (0);} + +/*--------------Password-------UserInfo---------------------*/ + strncpy(UserPasswd, argv[2], TICKETLENGTH - 1); + UserPasswd[TICKETLENGTH-1] = '\0'; + DD_Access = LoginRequest(UserPasswd, DDUserName, Host); + + if(DD_Access == 0) + { + printf("You can work 4.5 hours in this session.\n"); + } + else { + printf("Permission denied.\n"); + return 0; + } + + return (1); + +} diff --git a/src/TOOLS/DDSimpleTestGetData/CMakeLists.txt b/src/TOOLS/DDSimpleTestGetData/CMakeLists.txt new file mode 100644 index 0000000..ee70dfa --- /dev/null +++ b/src/TOOLS/DDSimpleTestGetData/CMakeLists.txt @@ -0,0 +1,22 @@ + +PROJECT(DDSimpleTestGetData) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibC/INCLUDE/ +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (DDSimpleTestGetData ${source_files} ) + +target_link_libraries( + DDSimpleTestGetData + DDClientLibC +) + +install (TARGETS DDSimpleTestGetData DESTINATION bin) diff --git a/src/TOOLS/DDSimpleTestGetData/SimpleTest.c b/src/TOOLS/DDSimpleTestGetData/SimpleTest.c new file mode 100644 index 0000000..1f60930 --- /dev/null +++ b/src/TOOLS/DDSimpleTestGetData/SimpleTest.c @@ -0,0 +1,116 @@ +/*============================================================= + * SimpleTest.c + * Simple test of some critical server behaviour + * 11 Apr 2009, V.1.0, Fedorov + *=============================================================*/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <sys/time.h> + +#include <DD.h> + +/*-------------------------*/ +#define VI "ace:imf:all\0" +#define PAR "IMF\0" +#define ATTR "MinSampling\0" +#define START "2008000000000000\0" +#define TI "0000010000000000\0" +/*-------------------------*/ + +int main() +{ + char ViName[100] = VI; + char StartTime[17] = START; + char TimeInt[17] = TI; + char ParName[100] = PAR; + char AttrName[100] = ATTR; + double RealTime; + DD_data_t *data; + + int ID, error; + struct timeval start, end; + long secs, usecs; + + gettimeofday(&start,NULL); + ID = DD_SetVariable(ViName); + printf("ID = %d\n",ID); + if(ID < 0) + { + error = DD_Close(99); + exit(0); + } + +/* + * Get Sampling Time info (secs) + * attribute names : MinSampling (constant sampling) + * attribute names : MinSampling & MaxSampling (variable sampling) + */ + + error = DD_GetInform(ID, AttrName, &data); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + printf(" sampling %lf\n", *(double *)data->Variables[0]); + +/* + * RealTime - double time pointer points to after SetTime + */ + error = DD_SetTimeInfo(ID, StartTime, &RealTime); + printf("DD_SetTimeInfo returns = %d\n",error); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + printf("time set as %lf\n",RealTime); + + + do + { + error = DD_GetData(ID,"Time",TimeInt, &data); + printf("DD_GetData returns = %d\n",error); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + if(error == MOREDELAY) + { + sleep(2); + error = MOREDATA; + } + } + while(error == MOREDATA); + + do + { + error = DD_GetData(ID,ParName,TimeInt, &data); + printf("DD_GetData returns = %d\n",error); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + if(error == MOREDELAY) + { + sleep(2); + error = MOREDATA; + } + } + while(error == MOREDATA); + + /*---------- Close VI and reurn -----------------------*/ + error = DD_Close(ID); + + gettimeofday(&end,NULL); + secs = end.tv_sec - start.tv_sec; + usecs = end.tv_usec - start.tv_usec; + + printf("Time elapsed: msecs %f\n",(float)(secs*1000000 + usecs)/1000.); + + return 1; +} diff --git a/src/TOOLS/DDSimpleTestGetMultiData/CMakeLists.txt b/src/TOOLS/DDSimpleTestGetMultiData/CMakeLists.txt new file mode 100644 index 0000000..32a5871 --- /dev/null +++ b/src/TOOLS/DDSimpleTestGetMultiData/CMakeLists.txt @@ -0,0 +1,22 @@ + +PROJECT(DDSimpleTestGetMultiData) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/DDClientLibC/INCLUDE/ +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (DDSimpleTestGetMultiData ${source_files} ) + +target_link_libraries( + DDSimpleTestGetMultiData + DDClientLibC +) + +install (TARGETS DDSimpleTestGetMultiData DESTINATION bin) diff --git a/src/TOOLS/DDSimpleTestGetMultiData/SimpleTest.c b/src/TOOLS/DDSimpleTestGetMultiData/SimpleTest.c new file mode 100644 index 0000000..040796e --- /dev/null +++ b/src/TOOLS/DDSimpleTestGetMultiData/SimpleTest.c @@ -0,0 +1,101 @@ +/*============================================================= + * SimpleTest.c + * Simple test of some critical server behaviour + * 11 Apr 2009, V.1.0, Fedorov + *=============================================================*/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <DD.h> +#include <time.h> +#include <sys/time.h> + +/*-------------------------*/ +#define VI "ace:imf:all\0" +#define PAR0 "IMF\0" +#define PAR1 "Time\0" +#define NVARS 2 +#define ATTR "MinSampling\0" +#define START "2008000000000000\0" +#define TI "0000010000000000\0" +/*-------------------------*/ + +int main() +{ + char ViName[100] = VI; + char StartTime[17] = START; + char TimeInt[17] = TI; + char ParName1[20] = PAR1; + char ParName0[20] = PAR0; + char *ParNames[NVARS] = {(char *)ParName0, (char *)ParName1}; + char AttrName[100] = ATTR; + double RealTime; + DD_data_t *data; + + int ID, error; + struct timeval start, end; + long secs, usecs; + + gettimeofday(&start,NULL); + ID = DD_SetVariable(ViName); + printf("ID = %d\n",ID); + if(ID < 0) + { + error = DD_Close(99); + exit(0); + } + +/* + * Get Sampling Time info (secs) + * attribute names : MinSampling (constant sampling) + * attribute names : MinSampling & MaxSampling (variable sampling) + */ + + error = DD_GetInform(ID, AttrName, &data); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + printf(" sampling %lf\n", *(double *)data->Variables[0]); + +/* + * RealTime - double time pointer points to after SetTime + */ + error = DD_SetTimeInfo(ID, StartTime, &RealTime); + printf("DD_SetTimeInfo returns = %d\n",error); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + printf("time set as %lf\n",RealTime); + + do + { + error = DD_GetMultiData(ID,NVARS, (char **)ParNames,TimeInt, &data, 1); + printf("DD_GetData returns = %d\n",error); + if(error < 0) + { + error = DD_Close(ID); + exit(0); + } + if(error == MOREDELAY) + { + sleep(2); + error = MOREDATA; + } + } + while(error == MOREDATA); + + /*---------- Close VI and reurn -----------------------*/ + error = DD_Close(ID); + + gettimeofday(&end,NULL); + secs = end.tv_sec - start.tv_sec; + usecs = end.tv_usec - start.tv_usec; + + printf("Time elapsed: msecs %f\n",(float)(secs*1000000 + usecs)/1000.); + + return 1; +} -- libgit2 0.21.2