renamed most source files

This commit is contained in:
cvs
2000-04-05 08:32:32 +00:00
parent 7eee71eab7
commit 0d0394707c
26 changed files with 2115 additions and 117 deletions

View File

@ -3,8 +3,9 @@
# #
# Markus Zolliker, March 2000 # Markus Zolliker, March 2000
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
OBJ= tecc.o client.o coc.o errhdl.o str_util.o str_buf.o \ OBJ= tecs_cli.o coc_client.o coc_util.o err_handling.o \
server.o lsc.o serutil.o logfile.o dlog.o str_util.o str_buf.o coc_server.o tecs_lsc.o tecs_serial.o \
coc_logfile.o tecs_dlog.o
#------------ for DigitalUnix #------------ for DigitalUnix
CC=cc CC=cc
@ -19,8 +20,6 @@ tecs: $(OBJ)
ranlib libtecsl.a ranlib libtecsl.a
- rm TecsServer - rm TecsServer
cc -o TecsServer -g tecs.c -lm -L. -ltecsl -L../hardsup -lhlib cc -o TecsServer -g tecs.c -lm -L. -ltecsl -L../hardsup -lhlib
- rm tcli
cc -o tcli -g tcli.c -lm -L. -ltecsl
clean: clean:
rm *.o rm *.o

View File

@ -56,7 +56,7 @@ int CocRecv(int fd, Str_Buf *buf)
{ {
struct timeval tmo={0,1}; struct timeval tmo={0,1};
fd_set mask; fd_set mask;
int i, ret; int i;
tmo.tv_sec=5; /* timeout 5 sec. */ tmo.tv_sec=5; /* timeout 5 sec. */
@ -68,7 +68,7 @@ int CocRecv(int fd, Str_Buf *buf)
ERR_SI(buf->wrpos=recv(fd, buf->buf, buf->dsize, 0)); ERR_SI(buf->wrpos=recv(fd, buf->buf, buf->dsize, 0));
if (buf->wrpos==0) { ERR_COD(ECONNRESET); } if (buf->wrpos==0) { ERR_COD(ECONNRESET); }
str_get_start(buf); str_get_start(buf);
return(ret); return(buf->wrpos);
OnError: return(-1); OnError: return(-1);
} }

188
tecs/coc_client.c Normal file
View File

@ -0,0 +1,188 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include "err_handling.h"
#include "coc_client.h"
#include "str_util.h"
/*-------------------------------------------------------------------------*/
int CocConnect(CocConn *conn, int allowConnRefused) {
int i;
struct sockaddr_in sadr;
ERR_I(CocCreateSockAdr(&sadr, conn->host, conn->port));
ERR_SI(conn->fd=socket(AF_INET, SOCK_STREAM, 0));
i = 1;
ERR_SI(setsockopt(conn->fd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))); /* allow quick port reuse */
i=connect(conn->fd, (struct sockaddr *)&sadr, sizeof(sadr));
if (i<0) {
if (allowConnRefused && errno==ECONNREFUSED) return(1);
ERR_COD(errno);
}
return(0);
OnError: return(-1);
}
int CocOpen(CocConn *conn)
{
int i, try, tmo;
ERR_I(i=CocConnect(conn, conn->startcmd[0]!='\0'));
if (i==0) return(0);
printf("%s\n", conn->startcmd);
ERR_I(system(conn->startcmd));
try=15;
tmo=100; /* wait total ca. 10 sec. for 15 tries */
while (try>0) {
try--;
CocDelay(tmo); tmo=tmo*5/4;
ERR_I(i=CocConnect(conn, try>0));
if (i==0) return(0);
}
ERR_MSG("error in CocConnect");
OnError: return(-1);
}
/*-------------------------------------------------------------------------*/
int CocInitClient(CocConn *conn, char *host, int port, char *magic, int bufsize, char *startcmd) {
assert(conn!=NULL);
if (bufsize==0) bufsize=1024;
ERR_P(conn->cmdbuf=str_create_buf(bufsize, '\0'));
ERR_P(conn->resbuf=str_create_buf(bufsize, '\0'));
conn->port=port;
ERR_I(str_copy(conn->host, host));
ERR_I(str_copy(conn->magic, magic));
ERR_I(str_copy(conn->startcmd, startcmd));
conn->fd=-1;
conn->varList=NULL;
CocVarList(&conn->varList);
ERR_I(CocOpen(conn));
ERR_I(CocSendMagic(conn, conn->magic));
return(0);
OnError: return(-1);
}
/*-------------------------------------------------------------------------*/
int CocSendMagic(CocConn *conn, char *magic) {
char *err;
if (magic[0]!='#') ERR_MSG("magic must start with '#'");
str_put_start(conn->resbuf); /* use return buffer for command in order to preserve command buffer */
ERR_I(str_put_str(conn->resbuf, magic));
ERR_SI(send(conn->fd, conn->resbuf->buf, conn->resbuf->wrpos, 0));
ERR_I(CocRecv(conn->fd, conn->resbuf));
ERR_P(err=str_get_str(conn->resbuf, NULL));
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0); goto OnError; }
ERR_I(str_get_end(conn->resbuf));
return(0);
OnError: return(-1);
}
/*-------------------------------------------------------------------------*/
int CocTryCmd(CocConn *conn)
{ if (conn->fd<0) {
ERR_I(CocOpen(conn));
ERR_I(CocSendMagic(conn, conn->magic));
}
ERR_SI(send(conn->fd, conn->cmdbuf->buf, conn->cmdbuf->wrpos, 0));
ERR_I(CocRecv(conn->fd, conn->resbuf));
return(0);
OnError: return(-1);
}
/*-------------------------------------------------------------------------*/
int CocCmd(CocConn *conn, const char *rwList)
{ int iret, cnt, setmode, i;
char *err;
const char *t, *s;
char nam[32];
CocVar *var;
void *adr;
assert(conn!=NULL);
str_put_start(conn->cmdbuf);
s=rwList;
setmode=0;
do {
t=strchr(s, ',');
if (t==NULL) t=s+strlen(s);
if (*s=='[') {
if (!setmode) ERR_I(str_put_str(conn->cmdbuf, "["));
s++;
setmode=1;
}
i=t-s;
assert(i<32);
str_ncpy(nam, s, i+1);
if (setmode) {
if (nam[i-1]==']') { i--; nam[i]='\0'; setmode=0; }
ERR_I(str_put_str(conn->cmdbuf, nam));
ERR_I(CocPutVar(conn->varList, conn->cmdbuf, nam, 0));
if (!setmode) ERR_I(str_put_str(conn->cmdbuf, "]"));
} else {
var=CocFindVar(conn->varList, nam, NULL);
if (var==NULL) ERR_MSG("variable not found");
ERR_I(str_put_str(conn->cmdbuf, nam));
}
s=t+1;
} while (*t!='\0');
cnt=3;
while (1) {
cnt--;
if (cnt<=0) {
ERR_I(CocTryCmd(conn));
break;
}
iret=CocTryCmd(conn);
if (iret>=0) break;
close(conn->fd);
conn->fd=-1;
if (ErrCode!=ECONNRESET && ErrCode!=EPIPE) goto OnError;
ErrWrite("try again, error was");
}
ERR_P(err=str_get_str(conn->resbuf, NULL));
if (*err!='\0') { ErrMsg(err); ErrTxt(": (response from server)",0 ); goto OnError; }
/* read values */
s=rwList;
setmode=0;
do {
t=strchr(s, ',');
if (t==NULL) t=s+strlen(s);
if (*s=='[') {
s++;
setmode=1;
}
i=t-s;
if (setmode) {
if (*(t-1)==']') setmode=0;
} else {
str_ncpy(nam, s, i+1);
ERR_I(CocGetVar(conn->varList, conn->resbuf, nam, 0));
}
s=t+1;
} while (*t!='\0');
ERR_I(str_get_end(conn->resbuf));
return(0);
OnError: return(-1);
}
void CocCloseClient(CocConn *conn) {
assert(conn!=NULL);
close(conn->fd);
str_free_buf(conn->cmdbuf);
str_free_buf(conn->resbuf);
CocFreeVarList(&conn->varList);
}

21
tecs/coc_client.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _COC_CLIENT_H_
#define _COC_CLIENT_H_
#include "coc_util.h"
typedef struct {
int fd, port;
CocVar *varList;
Str_Buf *cmdbuf; /* for sending command */
Str_Buf *resbuf; /* for response */
char host[64];
char magic[32];
char startcmd[512];
} CocConn;
int CocInitClient(CocConn *conn, char *host, int port, char *magic, int bufsize, char *startcmd);
int CocSendMagic(CocConn *conn, char *magic);
int CocCmd(CocConn *conn, const char *rwList);
void CocCloseClient(CocConn *conn);
#endif /* _COC_CLIENT_H_ */

239
tecs/coc_logfile.c Normal file
View File

@ -0,0 +1,239 @@
/* switch off ANSI_C_SOURCE for VMS-extended fopen, even when compiling with /ANSI */
#ifdef __VMS
#ifdef __HIDE_FORBIDDEN_NAMES
#undef __HIDE_FORBIDDEN_NAMES
#include <stdio.h>
#define __HIDE_FORBIDDEN_NAMES
#else
#include <stdio.h>
#endif
#else
#include <stdio.h>
#endif
#include <stdlib.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include "coc_logfile.h"
#include "err_handling.h"
#include "str_util.h"
static FILE *fil=NULL;
static char lnam[256]="", filnam[256]="";
static char ebuf[20000]="";
static char *eptr=&ebuf[0];
static int lastStamp=0;
static int notDated=0;
static int logMask=0;
static int wrtMask=0;
int ftime (struct timeb *__timeptr); /* for some reason not defined in timeb.h with flag -std1 */
static int logfileStd;
static int dirty, writeAll;
void logfileOpen(int first) {
struct tm *tim;
struct timeb btim;
if (logfileStd) {
fil=stdout;
return;
}
assert(fil==NULL);
if (first) {
ftime(&btim);
tim=localtime(&btim.time);
if (notDated) {
if (lnam[0]=='\0') {
str_copy(filnam, "test.log");
} else {
str_copy(filnam, lnam);
str_append(filnam, ".log");
}
} else {
sprintf(filnam, "%s%04d-%02d-%02d.log", lnam, tim->tm_year+1900, tim->tm_mon+1, tim->tm_mday);
}
} else {
assert(filnam[0]!='\0');
}
#ifdef __VMS
if (first && notDated) {
fil=fopen(filnam, "w", "SHR=UPD"); /* new version at restart */
} else {
fil=fopen(filnam, "a", "SHR=UPD");
}
#else
if (first && notDated) {
fil=fopen(filnam, "w"); /* overwrite at restart */
} else {
fil=fopen(filnam, "a");
}
#endif
}
void logfileInit(char *path, int nodate, int use_stdout, int write_all) {
str_copy(lnam, path);
lastStamp=-1;
logfileStd=use_stdout;
writeAll=write_all;
notDated=nodate;
logfileOpen(1);
}
void logfileOut(int mask, const char *fmt, ...)
{ va_list ap;
assert(mask>0 && mask<32);
va_start(ap, fmt);
if (writeAll) {
#ifdef __VMS
if (fil==NULL) logfileOpen(0);
#endif
vfprintf(fil, fmt, ap);
wrtMask=LOG_ALL;
} else {
if (eptr!=NULL) {
if (eptr-ebuf > sizeof(ebuf)-512) {
sprintf(eptr, "... buffer full ... \1\1");
eptr=NULL;
} else {
vsprintf(eptr, fmt, ap);
assert(NULL==strchr(eptr, '\1'));
eptr+=strlen(eptr);
eptr[0]='\1'; /* put \1 as separator between blocks */
eptr[1]=mask;
eptr[2]='\0';
eptr+=2;
}
}
wrtMask=wrtMask | mask;
}
va_end(ap);
}
void logfileMask(int mask) {
logMask=logMask | mask;
}
void logfileStamp(void) {
struct tm *tim;
struct timeb btim;
int stamp;
ftime(&btim);
tim=localtime(&btim.time);
stamp=tim->tm_hour*60+tim->tm_min;
if (stamp!=lastStamp) {
if (stamp<lastStamp) { /* time smaller than last time -> new day -> new logfile */
if (fil!=NULL) { fclose(fil); fil=NULL; }
logfileOpen(1);
}
#ifdef __VMS
else if (fil==NULL) logfileOpen(0);
#endif
lastStamp=stamp;
fprintf(fil, "--- %02d:%02d:%02d ---\n", tim->tm_hour, tim->tm_min, tim->tm_sec);
dirty=0;
}
}
void logfileWrite0(int mask) {
char *s, *next;
logMask=logMask | mask;
if (dirty) logfileStamp(); /* there was something written since last time */
s=ebuf;
if (writeAll || *s!='\0' && wrtMask & logMask) {
logfileStamp(); /* write stamp before write something */
next=strchr(s, '\1');
while (next!=NULL) {
*next='\0';
next++;
if (*next & logMask) {
fprintf(fil, "%s", s);
dirty=1;
}
s=next+1;
next=strchr(s, '\1');
}
}
ebuf[0]='\0';
eptr=&ebuf[0];
logMask=0;
wrtMask=0;
}
void logfileWrite(int mask) {
#ifdef __VMS
if (fil==NULL) logfileOpen(0);
#endif
logfileWrite0(mask);
#ifdef __VMS
if (!logfileStd) { fclose(fil); fil=NULL; }
#else
fflush(fil);
#endif
}
void logfileShowErr(char *text)
{
#ifdef __VMS
if (fil==NULL) logfileOpen(0);
#endif
logfileWrite0(LOG_ALL); /* write all */
ErrWrite(text);
#ifdef __VMS
if (!logfileStd) { fclose(fil); fil=NULL; }
#else
fflush(fil);
#endif
}
void logfileClose()
{
#ifdef __VMS
if (fil==NULL) logfileOpen(0);
#endif
logfileWrite0(LOG_MAIN+LOG_WARN);
lastStamp-=1;
logfileStamp();
if (fil!=NULL) { fclose(fil); fil=NULL; }
filnam[0]='\0';
}
void logfileOutBuf(int mask, Str_Buf *buf)
{ char str[256];
int rd0, sep;
rd0=buf->rdpos;
if (buf->rdpos < 0 || buf->rdpos >= buf->dsize
|| buf->wrpos < 0 || buf->wrpos >= buf->dsize) {
logfileOut(mask, "<buffer corrupt>"); return;
}
sep=0;
while (buf->rdpos < buf->wrpos) {
str_get_str(buf, str);
if (buf->sep=='\0') {
if (sep) logfileOut(mask, " ");
if (*str=='\0') {
logfileOut(mask, ".");
} else {
logfileOut(mask, "%s", str);
}
sep=1;
} else {
if (sep) logfileOut(mask, "%c", buf->sep);
logfileOut(mask, "%s", str);
sep=1;
}
}
buf->rdpos=rd0;
}

20
tecs/coc_logfile.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _COC_LOGFILE_H_
#define _COC_LOGFILE_H_
#include "str_buf.h"
#define LOG_ALL 31
#define LOG_SER 8
#define LOG_NET 4
#define LOG_WARN 2
#define LOG_MAIN 1
void logfileInit(char *path, int nodate, int use_stdout, int write_all);
void logfileOut(int mask, const char *fmt, ...);
void logfileOutBuf(int mask, Str_Buf *buf);
void logfileShowErr(char *text);
void logfileMask(int mask);
void logfileWrite(int mask);
void logfileClose(void);
#endif /* _COC_LOGFILE_H_ */

242
tecs/coc_server.c Normal file
View File

@ -0,0 +1,242 @@
/* needed to define accept() and gethostbyaddr() correctly when using flag -std1
*/
#ifdef __unix__
#ifndef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED
#endif
#endif
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <strings.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include "err_handling.h"
#include "coc_logfile.h"
#include "coc_server.h"
#include "str_util.h"
static Str_Buf *buf, *bufo;
static fd_set mask, rmask;
static int maxfd;
struct CocClient *cList, *cLastCmd=NULL;
static int mainFd;
static int modified;
int CocInitServer(int bufsize, int port) {
int i;
struct sockaddr_in sadr;
char *err;
if (bufsize==0) bufsize=1024;
ERR_P(buf=str_create_buf(bufsize, '\0'));
ERR_P(bufo=str_create_buf(bufsize,'\0'));
cList=malloc(sizeof(*cList)); /* empty header */
/* first try to connect to an existing server */
ERR_SI(mainFd=socket(AF_INET, SOCK_STREAM, 0));
i = 1;
ERR_SI(setsockopt(mainFd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))); /* allow quick port reuse */
ERR_I(CocCreateSockAdr(&sadr, NULL, port));
ERR_SI(bind(mainFd, (struct sockaddr *)&sadr, sizeof(sadr)));
logfileOut(LOG_MAIN, "created server on port %d\n", port);
ERR_SI(listen(mainFd, 8));
FD_ZERO(&mask);
FD_SET(mainFd, &mask);
maxfd=mainFd+1;
return(0);
OnError: return(-1);
}
int CocHandle1Request(int tmo_msec, int fd) {
struct sockaddr_in cadr;
struct hostent *h;
struct timeval tmo={0,1};
struct CocClient *cl, *cl0;
int i, newfd, setmode;
size_t cadrlen;
char *err, *varname;
rmask=mask;
if (fd>0) FD_SET(fd, &rmask);
tmo.tv_sec=tmo_msec / 1000;
tmo.tv_usec=(tmo_msec % 1000)*1000+1;
if (fd>=maxfd) maxfd=fd+1;
ERR_SI(i=select(maxfd,&rmask,NULL,NULL,&tmo));
if (fd>0 && FD_ISSET(fd, &rmask)) return(1); /* event on fd */
if (i==0) return(0); /* timeout */
if (FD_ISSET(mainFd, &rmask)) {
ERR_SI(newfd=accept(mainFd, (struct sockaddr *)&cadr, &cadrlen));
FD_SET(newfd, &mask);
if (newfd>=maxfd) maxfd=newfd+1;
cl=cList;
cl->fd=newfd;
cl->mode=0;
cl->cmd[0]='\0';
cl->res[0]='\0';
cList=malloc(sizeof(*cList));
cList->next=cl;
h=gethostbyaddr(&cadr.sin_addr, 4, AF_INET);
if (h==NULL) {
logfileOut(LOG_MAIN, "(%d) open from %s\n", newfd, "local");
} else {
logfileOut(LOG_MAIN, "(%d) open from %s\n", newfd, h->h_name);
}
} else {
cl0=cList; cl=cl0->next;
while (cl!=NULL) {
if (FD_ISSET(cl->fd, &rmask)) {
buf->wrpos=recv(cl->fd, buf->buf, buf->dsize, 0);
if (buf->wrpos<=0) {
logfileOut(LOG_MAIN, "(%d) disconnected\n",cl->fd);
close(cl->fd);
FD_CLR(cl->fd, &mask);
cl0->next=cl->next;
free(cl);
cl=cl0;
} else {
str_put_start(bufo);
str_get_start(buf);
ERR_I(str_put_str(bufo, "")); /* empty error message */
setmode=0;
err=NULL;
ERR_P(varname=str_get_str(buf, NULL));
logfileOut(LOG_NET, "(%d) ", cl->fd);
if (varname[0]=='#') { /* access code */
if (0==strcmp(varname,"#rdacc")) {
logfileOut(LOG_MAIN, "set read mode\n");
cl->mode=1;
} else if (0==strcmp(varname,"#rwacs")) {
logfileOut(LOG_MAIN, "set write mode\n");
cl->mode=2;
} else {
err="bad access code";
}
} else if (cl->mode==0) {
err="no access";
} else {
while (1) {
if (varname[0]=='[') {
if (cl->mode<2) { err="no write access"; break; }
setmode=1; /* switch to set mode */
} else if (varname[0]==']') { /* switch to read mode */
setmode=0;
} else if (setmode) {
if (0==strcmp("$", varname)) { /* special case: command */
ERR_P(str_get_str(buf, cl->cmd));
cl->res[0]='\0';
} else {
i=CocGetVar(serverVarList, buf, varname, 1);
if (i<0) { err=ErrMessage; break; }
}
modified=1;
} else {
if (0==strcmp("$", varname)) { /* special case: response */
ERR_I(str_put_str(bufo, cl->res));
cl->res[0]='\0';
} else {
i=CocPutVar(serverVarList, bufo, varname, 0);
if (i<0) { err=ErrMessage; break; }
}
}
if (buf->rdpos>=buf->wrpos) {
ERR_I(str_get_end(buf));
break;
}
ERR_P(varname=str_get_str(buf, NULL));
}
str_get_start(buf);
logfileOutBuf(LOG_NET, buf);
str_get_start(bufo);
logfileOut(LOG_NET, " |");
logfileOutBuf(LOG_NET, bufo);
}
if (err==NULL) {
logfileOut(LOG_NET, "\n");
} else {
str_put_start(bufo); /* reset output */
str_put_str(bufo, err); /* put error message */
logfileOut(LOG_NET, " (%s)\n", err);
logfileMask(LOG_NET);
}
ERR_SI(send(cl->fd, bufo->buf, bufo->wrpos, 0));
}
}
cl0=cl; cl=cl->next;
}
}
if (modified) return(2);
return(3);
OnError: return(-1);
}
int CocHandleRequests(int tmo_msec, int fd) {
struct timeb tim1, tim0;
int tdif, iret;
if (modified && fd==0) { /* earlier modification */
modified=0;
return(2);
}
ftime(&tim0);
tdif=tmo_msec;
while (tdif>=0) {
ERR_I(iret=CocHandle1Request(tdif, fd));
if (fd==0) {
if (iret==2) return(2); /* modification of a varaible */
} else {
if (iret==1) return(1); /* event on fd */
}
if (iret==0) return(0); /* timeout */
ftime(&tim1);
tdif=tmo_msec-((tim1.time-tim0.time)*1000+tim1.millitm-tim0.millitm);
}
return(0); /* timeout */
OnError: return(-1);
}
struct CocClient *CocGetNextCmd() {
struct CocClient *cl;
cl=cLastCmd;
while (cl!=NULL) {
if (cl->cmd[0]!='\0') {
cLastCmd=cl->next;
return(cl);
}
cl=cl->next;
}
cl=cList->next;
while (cl!=NULL && cl!=cLastCmd) {
if (cl->cmd[0]!='\0') {
cLastCmd=cl->next;
return(cl);
}
cl=cl->next;
}
return(NULL);
}
void CocCloseServer() {
struct CocClient *cl, *cl0;
cl=cList->next;
while (cl!=NULL) {
close(cl->fd);
cl0=cl;
cl=cl->next;
free(cl0);
}
free(cList);
close(mainFd);
str_free_buf(buf); str_free_buf(bufo);
logfileClose();
}

40
tecs/coc_server.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef _SERVER_H_
#define _SERVER_H_
#include "coc_util.h"
struct CocClient { struct CocClient *next; int fd; int mode; char cmd[80]; char res[80]; };
int CocInitServer(int bufsize, int port);
int CocHandleRequests(int tmo_msec, int fd);
int CocHandle1Request(int tmo_msec, int fd);
/*
handle hetwork requests.
return value: <0: error
=0: timeout
=1: event on fd
=2: variable was changed
=3: other network request treated
CocHandle1Request handles only one network request
For CocHandleRequests:
if fd=0: returns when a network request has changed a variable,
or when timeout has expired (result is 0 or 2)
if fd>0: returns when an read event is pending on fd
or when timeout has expired (result is 0 or 1)
*/
struct CocClient *CocGetNextCmd(void);
/*
get next client with a pending command
*/
void CocCloseServer(void);
#endif /* _SERVER_H_ */

249
tecs/coc_util.c Normal file
View File

@ -0,0 +1,249 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <assert.h>
#include "err_handling.h"
#include "str_util.h"
#include "coc_util.h"
/*-------------------------------------------------------------------------*/
/* CreateSocketAddress stolen from Tcl. Thanks to John Ousterhout */
CocVar *serverVarList=NULL;
static CocVar **varListHdl=&serverVarList;
int CocRD=0;
int CocWR=0;
int CocCreateSockAdr(
struct sockaddr_in *sockaddrPtr, /* Socket address */
const char *host, /* Host. NULL implies INADDR_ANY */
int port) /* Port number */
{
struct hostent *hostent; /* Host database entry */
struct in_addr addr; /* For 64/32 bit madness */
(void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
sockaddrPtr->sin_family = AF_INET;
sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));
if (host == NULL || host[0]=='\0') {
addr.s_addr = INADDR_ANY;
} else {
hostent = gethostbyname(host);
if (hostent != NULL) {
memcpy((char *) &addr,
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
} else {
addr.s_addr = inet_addr(host);
if (addr.s_addr == (unsigned long)-1) {
return -1; /* error */
}
}
}
/*
* There is a rumor that this assignment may require care on
* some 64 bit machines.
*/
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
return 0;
}
/*-------------------------------------------------------------------------*/
int CocRecv(int fd, Str_Buf *buf)
{
struct timeval tmo={0,1};
fd_set mask;
int i;
tmo.tv_sec=5; /* timeout 5 sec. */
FD_ZERO(&mask);
FD_SET(fd, &mask);
ERR_SI(i=select(fd+1,&mask,NULL,NULL,&tmo));
if (i==0) ERR_MSG("time out");
ERR_SI(buf->wrpos=recv(fd, buf->buf, buf->dsize, 0));
if (buf->wrpos==0) { ERR_COD(ECONNRESET); }
str_get_start(buf);
return(buf->wrpos);
OnError: return(-1);
}
void CocVarList(CocVar **varList) {
assert(varList!=NULL);
varListHdl=varList;
}
void CocList() {
CocVar *p;
p=*varListHdl;
while (p!=NULL) {
printf("%s %d\n", p->name, p->type);
p=p->next;
}
}
CocVar *CocFindVar1(CocVar *varList, const char *name) {
CocVar *p;
p=varList;
while (p!=NULL && 0!=strcmp(p->name,name)) p=p->next;
return(p);
}
CocVar *CocFindVar(CocVar *varList, const char *name, void **adr) {
CocVar *p, *t;
const char *f;
void *base;
char nam[32];
f=str_split(nam, name, '.');
if (f==NULL) {
f=str_split(nam, name, '-');
if (f!=NULL) {
if (f[0]!='>') {
f=NULL;
} else {
f++;
}
}
}
if (f!=NULL) {
if (adr!=NULL) *adr=NULL;
p=CocFindVar1(varList, nam);
if (p==NULL) { return(NULL); }
t=p->strucType;
if (t==NULL) { return(NULL); }
str_copy(nam, t->name);
str_append(nam, ":");
str_append(nam, f);
if (adr!=NULL) {
base=p->var;
if (p->type==COC_PTR) base=*(void **)base;
*adr=base;
}
} else if (adr!=NULL) {
*adr=NULL;
}
p=CocFindVar1(varList, nam);
if (p!=NULL && p->type==COC_ALIAS) { /* recursive call for alias */
p=CocFindVar(varList, p->var, adr);
}
return(p);
}
CocVar *CocDefVar(const char *name, void *var, int type, int *flag) {
CocVar *p;
const char *f;
void *adr;
assert(varListHdl!=NULL);
p=CocFindVar1(*varListHdl, name);
if (p==NULL) {
p=malloc(sizeof(*p));
p->next=*varListHdl;
*varListHdl=p;
str_copy(p->name, name);
}
p->var=var;
p->type=type;
p->flag=flag;
return(p);
}
void CocDefVarS(const char *name, const char *tname, void *var, int type) {
CocVar *p, *t;
assert(type==COC_PTR || type==COC_STRUCT);
p=CocDefVar(name, var, type, &CocRD);
p->strucType=CocDefVar(tname, NULL, COC_TYPE, &CocRD);
}
int CocGetVar(CocVar *varList, Str_Buf *buf, const char *name, int secure) {
CocVar *var;
void *adr;
var=CocFindVar(varList, name, &adr);
if (var==NULL) ERR_MSG("undefined variable");
if (adr==NULL) {
adr=var->var;
} else {
adr=(char *)adr + (int)var->var;
}
if (secure) { /* we are the server */
if (var->flag==&CocRD) ERR_MSG("variable is read only");
}
if (var->type==-1) {
ERR_I(str_get_int(buf, (int *)adr));
} else if (var->type==-2) {
ERR_I(str_get_float(buf, (float *)adr));
} else if (var->type>1) {
ERR_P(str_nget_str(buf, (char *)adr, var->type));
} else {
ERR_MSG("unknown type");
}
if (secure) { /* we are the server */
(*var->flag)++;
}
return(0);
OnError: return(-1);
}
int CocPutVar(CocVar *varList, Str_Buf *buf, const char *name, int secure) {
CocVar *var;
void *adr;
char *c;
var=CocFindVar(varList, name, &adr);
if (var==NULL) ERR_MSG("undefined variable");
if (adr==NULL) {
adr=var->var;
} else {
adr=(char *)adr + (int)var->var;
}
if (secure) { /* we are the client */
if (var->flag==&CocRD) ERR_MSG("variable is read only");
}
if (var->type==-1) {
ERR_I(str_put_int(buf, *(int *)adr));
} else if (var->type==-2) {
ERR_I(str_put_float(buf, *(float *)adr));
} else if (var->type>1) {
ERR_I(str_put_str(buf, adr));
} else {
ERR_MSG("unknown type");
}
if (secure) { /* we are a client */
if (var->flag!=NULL) (*var->flag)++;
}
return(0);
OnError: return(-1);
}
void CocFreeVarList(CocVar **varList) {
CocVar *p, *v;
if (varList==NULL) varList=&serverVarList;
v=*varList;
while (v!=NULL) {
p=v;
v=p->next;
p->next=NULL;
free(p);
}
*varList=NULL;
}
void CocDelay(int msec) {
struct timeval tmo;
tmo.tv_sec=msec / 1000;
tmo.tv_usec=(msec % 1000)*1000+1;
select(1,NULL,NULL,NULL,&tmo);
}

47
tecs/coc_util.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef _COC_UTIL_H_
#define _COC_UTIL_H_
#include <netinet/in.h>
#include "str_buf.h"
int CocCreateSockAdr(
struct sockaddr_in *sockaddrPtr, /* Socket address */
const char *host, /* Host. NULL implies INADDR_ANY */
int port); /* Port number */
int CocRecv(int fd, Str_Buf *buf);
typedef struct { void *next; char name[32]; void *var; int *flag; int type; void *strucType; } CocVar;
extern int CocRD;
extern int CocWR;
CocVar *serverVarList;
CocVar *CocDefVar(const char *name, void *var, int type, int *flag);
void CocDefVarS(const char *name, const char *tname, void *var, int type);
void CocVarList(CocVar **varlist);
void CocFreeVarList(CocVar **varList);
CocVar *CocFindVar(CocVar *varList, const char *name, void **adr);
int CocPutVar(CocVar *varList, Str_Buf *buf, const char *name, int secure);
int CocGetVar(CocVar *varList, Str_Buf *buf, const char *name, int secure);
#define COC_INT -1
#define COC_FLT -2
#define COC_PTR -3
#define COC_STRUCT -4
#define COC_TYPE -5
#define COC_ALIAS -6
#define CocDefInt(V,F) CocDefVar(#V,&V,COC_INT,&F)
#define CocDefFlt(V,F) CocDefVar(#V,&V,COC_FLT,&F)
#define CocDefStr(V,F) CocDefVar(#V,V,sizeof(V),&F)
#define CocDefPtr(V,S) CocDefVarS(#V,#S,&V,COC_PTR*(V!=(S *)NULL));
#define CocDefStruct(V,S) CocDefVarS(#V,#S,&V,COC_STRUCT*(&V!=(S *)NULL));
#define CocIntFld(S,V,F) CocDefVar(#S":"#V,&((S *)NULL)->V,COC_INT,&F);
#define CocFltFld(S,V,F) CocDefVar(#S":"#V,&((S *)NULL)->V,COC_FLT,&F);
#define CocStrFld(S,V,F) CocDefVar(#S":"#V,((S *)NULL)->V,sizeof(((S *)NULL)->V),&F);
#define CocDefCmd(V) CocDefVar("$",V,sizeof(V),&CocWR)
#define CocDefStrPtr(V,S,F) CocDefVar(#V,V,S,&F)
#define CocAlias(A,V) CocDefVar(#A, #V, COC_ALIAS, &CocRD);
void CocDelay(int msec);
#endif /* _COC_UTIL_H_ */

View File

@ -9,6 +9,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -21,6 +22,8 @@
#define DEFINED(F) (abs((F)-dset->undef)>1.0e-5*(F)) #define DEFINED(F) (abs((F)-dset->undef)>1.0e-5*(F))
static time_t gmtoff;
int DlogWrite(DlogSet *dset, int idx, void *data) { int DlogWrite(DlogSet *dset, int idx, void *data) {
int p; int p;
@ -50,23 +53,26 @@ int DlogRead(DlogSet *dset, int idx, void *data) {
} }
int DlogOpen(DlogSet *dset, char *name, int write) { int DlogOpen(DlogSet *dset, char *name, int write) {
int i, p, np, fd; int i, p, np, fd, flags;
time_t tim;
struct tm *timp;
fd=0; fd=0;
str_copy(dset->name, name); str_copy(dset->name, name);
if (write) { if (write) {
#ifdef __VMS flags=O_RDWR | O_SYNC;
ERR_SI(fd=open(name, O_RDWR | O_SYNC, 0, "SHR=UPD"));
#else
ERR_SI(fd=open(name, O_RDWR | O_SYNC, 0));
#endif
} else { } else {
#ifdef __VMS flags=O_RDONLY | O_SYNC;
ERR_SI(fd=open(name, O_RDONLY | O_SYNC, 0, "SHR=UPD"));
#else
ERR_SI(fd=open(name, O_RDONLY | O_SYNC, 0));
#endif
} }
#ifdef __VMS
ERR_SI(fd=open(name, flags, 0, "SHR=UPD"));
gmtoff=0;
#else
ERR_SI(fd=open(name, flags, 0));
time(&tim);
timp=localtime(&tim);
gmtoff=timp->tm_gmtoff;
#endif
dset->fd=fd; dset->fd=fd;
p=(char *)&dset->fd - (char *)dset; p=(char *)&dset->fd - (char *)dset;
@ -162,7 +168,7 @@ int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], flo
} }
i0=i1; i0=i1;
*starttime = dset->start + i1 * dset->period; *starttime = dset->start + i1 * dset->period + gmtoff;
n=0; n=0;
undef=2; undef=2;
while (i0<=i) { while (i0<=i) {
@ -203,7 +209,7 @@ int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[],
return(-1); return(-1);
} }
int Dlog_Get_(char *name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[], int namlen) { int dlog_get_(char *name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[], int namlen) {
DlogSet dset; DlogSet dset;
char buf[64]; char buf[64];
int ntot; int ntot;
@ -214,13 +220,13 @@ int Dlog_Get_(char *name, int *nset, int *nmax, double *starttime, float x[], fl
DlogClose(&dset); DlogClose(&dset);
return(ntot); return(ntot);
OnError: OnError:
ErrShow("error in Dlog_Get"); ErrShow("error in dlog_get_");
return(-1); return(-1);
} }
int Dlog_Get(char **name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[]) { int Dlog_Get(char **name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[]) {
/* for VMS */ /* for VMS */
return(Dlog_Get_(name[1], nset, nmax, starttime, x, y, index, *(short *)name)); return(dlog_get_(name[1], nset, nmax, starttime, x, y, index, *(short *)name));
} }
int DlogUpd(DlogSet *dset) { int DlogUpd(DlogSet *dset) {

95
tecs/err_handling.c Normal file
View File

@ -0,0 +1,95 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "err_handling.h"
#define SLEN 64
#define MLEN 64
static char *txt[SLEN];
static int sp=0;
int ErrCode;
char *ErrMessage=NULL;
void (*outrtn)()=NULL;
void *outarg;
void ErrTxt(char *text, int systemError)
{
if (systemError) { sp=0; ErrCode=errno; ErrMessage=strerror(errno); }
if (sp<SLEN) {
txt[sp++]=text;
}
}
void ErrMsg(char *msg)
{
ErrCode=-1;
ErrMessage=msg; sp=0;
}
void ErrCod(int code)
{
ErrCode=code;
ErrMessage=strerror(code); sp=0;
}
void ErrOutFil(void *arg, char *text) {
fprintf((FILE *)arg, "%s\n", text);
}
void ErrWrite(char *text)
{
int i, l;
char buf[256];
if (outrtn==NULL) {
outrtn=ErrOutFil;
outarg=stdout;
}
l=strlen(text)+strlen(ErrMessage)+6;
assert(l<256);
sprintf(buf, "--- %s: %s", text, ErrMessage);
for (i=0;i<sp;i++) {
if (txt[i][0]==':') {
l+=strlen(txt[i]);
assert(l<256);
strcat(buf, &(txt[i][1]));
} else {
outrtn(outarg, buf);
l=strlen(txt[i]);
assert(l<256);
strcpy(buf, txt[i]);
}
}
outrtn(outarg, buf);
outrtn(outarg, "");
}
void ErrSetOutRtn(void (*rtn)(), void *arg) {
outrtn=rtn;
outarg=arg;
}
#ifdef __VMS
typedef struct { short size, dummy; char *text; } Desc;
void ErrShowVms(Desc *desc, void (*outrtn)(), void *arg) {
char buf[256];
int l;
l=desc->size;
if (l>=256) l=255;
strncpy(buf, desc->text, l);
buf[l]='\0';
ErrWrite(buf);
}
#endif
void ERR_EXIT(char *text) {
ErrWrite(text); exit(1);
}

83
tecs/err_handling.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef _ERR_HANDLING_H_
#define _ERR_HANDLING_H_
#include <sys/errno.h>
/* ErrHDL Error handling utilities
-------------------------------
Makes code more readable by hiding annoying error condition checks.
Macros and routines:
Spelling in uppercase indicates, that it the program flow
may be modified (jump to OnError label or program exit).
ERR_x
Usage Error condition Error message taken from
-----------------------------------------------------------------------------------------
ERR_SI(res=routine1(...)) res<0 errno
ERR_SP(ptr=routine2(...)) ptr==NULL errno
ERR_I(res=routine3(...)) res<0 stored by routine3 using errhdl mechanism
ERR_P(ptr=routine4(...)) ptr==NULL stored by routine4 using errhdl mechanism
The result assignment "res=" or "ptr=" is optional.
Description:
The routine routineX is called.
If the result indicates an error, the source text is saved and the
program continues at the OnError label.
The error message and the source code of the calling instructions is
saved for a later call to ErrShow or ErrExit.
ERR_EXIT("program_name")
Show error and exit program.
ERR_MSG("message")
Signals an error condition. If "message" is replaced by a variable,
take care that it is not modified until ErrShow is called.
ERR_COD(cod)
Signals an error condition as code from errno.h
ErrShow("program_name")
ErrWrite(fil, "program_name")
Show actual error message with traceback information to stdout
or a file fil
Global Variables (read only)
int ErrCode
actual error message code
= errno for system errors or
= -1 for custom errors signaled by ERRMSG
char *ErrMessage
actual error message
*/
#define ERR_SI(R) { if(0>(R)) { ErrTxt(#R,1); goto OnError; }; }
#define ERR_SP(R) { if(NULL==(R)) { ErrTxt(#R,1); goto OnError; }; }
#define ERR_I(R) { if(0>(R)) { ErrTxt(#R,0); goto OnError; }; }
#define ERR_P(R) { if(NULL==(R)) { ErrTxt(#R,0); goto OnError; }; }
#define ERR_MSG(R) { ErrMsg(R); goto OnError; }
#define ERR_COD(R) { ErrCod(R); goto OnError; }
void ErrTxt(char *text, int systemError);
void ErrMsg(char *msg);
void ErrCod(int code);
void ErrWrite(char *text);
void ERR_EXIT(char *text);
void ErrLog(char *text);
extern int ErrCode;
extern char *ErrMessage;
#endif /* _ERR_HANDLING_H_ */

View File

@ -150,21 +150,18 @@ char *LscCmd(SerChannel *ser, const char *cmds) {
} }
} }
if (retreq!=NULL) { /* query */ if (retreq!=NULL) { /* query */
if (retreq[1]=='>') { /* >> get whole response */ str_link_buf(&sbuf, result, 0, ',');
str_link_buf(&sbuf, result, 0, ';'); str_split(par, retreq+1, ';');
str_split(varname, retreq+2, ';'); p=par;
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0)); while (p!=NULL) {
} else { p=str_split(varname, p, ',');
str_link_buf(&sbuf, result, 0, ','); if (varname[0]!='\0') {
str_split(par, retreq+1, ';'); if (p==NULL) { /* last element: get rest of line */
p=par; sbuf.sep='\0';
while (p!=NULL) {
p=str_split(varname, p, ',');
if (varname[0]!='\0') {
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0));
} else {
ERR_P(str_get_str(&sbuf, NULL));
} }
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0));
} else {
ERR_P(str_get_str(&sbuf, NULL));
} }
} }
} }
@ -172,70 +169,3 @@ char *LscCmd(SerChannel *ser, const char *cmds) {
return(res); return(res);
OnError: return(NULL); OnError: return(NULL);
} }
int LscCmdChk(SerChannel *ser, char *cmds) {
char *b, *o, *cn, *c, *d, *r, *res;
char *clist[MC], *plist[MC], *rlist[MC], *olist[MC];
char obuf[SER_BUF_LEN], r1[SER_BUF_LEN];
int i,n,m,j,cnt,l;
if (NULL!=strchr(cmds, '?')) ERR_COD(EINVAL);
cn=cmds;
o=&obuf[0];
m=MC;
do {
n=m;
cn=str_splitx(cn, ';', clist, &n);
for (i=0; i<n; i++) {
c=clist[i];
b=strchr(c, ' ');
d=strchr(c, ':');
if (d==NULL) ERR_COD(EINVAL);
if (b==NULL || b>d) {
*d=' '; b=d;
} else {
*d=',';
}
plist[i]=d+1;
l=strlen(c);
if ((o-&obuf[0])+l+(d-c)+2>SER_BUF_LEN) ERR_COD(ENOBUFS);
olist[i]=o;
strcpy(o, c); o+=l;
*o=';'; o++;
strncpy(o, c, d-c);
o[b-c]='?'; o+=d-c;
if (b==d) o++;
*o=';'; o++;
};
o--; *o='\0';
cnt=0;
do {
cnt++;
if (cnt>3) ERR_MSG("can not set parameter");
ERR_P(res=SerCmd(ser, obuf));
if (cnt>0) {
if (0==strcmp(r1, res)) break; /* got two times the same result */
}
strcpy(r1, res);
j=n;
r=str_splitx(res, ';', rlist, &n);
if (r==NULL || n!=j) continue;
for (i=0; i<n; i++) { /* compare parameters */
if (! LscEqPar(plist[i], rlist[i])) {
j=0; break;
logfileMask(LOG_SER);
}
}
} while (j==0);
} while (cn!=NULL);
return(0);
OnError: return(-1);
}
int LscCmdChkC(SerChannel *ser, const char *cmds) {
char buf[128];
assert(strlen(cmds)<128);
strcpy(buf, cmds);
return(LscCmdChk(ser, buf));
}

View File

@ -1,8 +1,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <stdlib.h> #include <stdlib.h>
#include "errhdl.h" #include "err_handling.h"
#include "str_util.h" #include "str_util.h"
#include "str_buf.h" #include "str_buf.h"

View File

@ -1,3 +1,5 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -5,7 +7,7 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "errhdl.h" #include "err_handling.h"
#include "str_util.h" #include "str_util.h"
char *str_splitx(char *str, char sep, char *list[], int *n) { char *str_splitx(char *str, char sep, char *list[], int *n) {

View File

@ -74,7 +74,7 @@ void str_nupcase(char *dst, const char *src, int dstlen);
*/ */
#ifdef __VMS_VER #ifdef __VMS_VER
#if _VMS_VER<70000000 #if __VMS_VER<70000000
int strcasecmp(const char *str1, const char *str2); int strcasecmp(const char *str1, const char *str2);
/* /*

View File

@ -1,14 +1,16 @@
#include <math.h> #include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "errhdl.h" #include "err_handling.h"
#include "server.h" #include "coc_server.h"
#include "logfile.h" #include "coc_logfile.h"
#include "str_util.h" #include "str_util.h"
#include "lsc.h" #include "tecs_lsc.h"
#include "dlog.h" #include "tecs_dlog.h"
#define TABLE_FILE "lsc.tab" #define TABLE_FILE "lsc.tab"
#define NO_CODE 999 #define NO_CODE 999
@ -146,7 +148,7 @@ int instCurve(char *nam, char *channel) {
if (num>20) ERR_MSG("illegal standard curve number"); if (num>20) ERR_MSG("illegal standard curve number");
retstat=-1; /* an error could be fixed */ retstat=-1; /* an error could be fixed */
ERR_P(LscCmd(ser, "CRVHDR?[num]>>head")); ERR_P(LscCmd(ser, "CRVHDR?[num]>head"));
} else { } else {
@ -189,7 +191,7 @@ int instCurve(char *nam, char *channel) {
if (num<21 || num>60) ERR_MSG("illegal curve number"); if (num<21 || num>60) ERR_MSG("illegal curve number");
retstat=-1; /* an error could be fixed */ retstat=-1; /* an error could be fixed */
ERR_P(LscCmd(ser, "CRVHDR?[num]>>head")); ERR_P(LscCmd(ser, "CRVHDR?[num]>head"));
e=strchr(entry, '\n'); e=strchr(entry, '\n');
if (e!=NULL) { *e='\0'; e++; } if (e!=NULL) { *e='\0'; e++; }
@ -216,7 +218,7 @@ int instCurve(char *nam, char *channel) {
n=3; n=3;
do { do {
ERR_P(LscCmd(ser, "CRVDEL [num];CRVHDR?[num]>buf1")); ERR_P(LscCmd(ser, "CRVDEL [num];CRVHDR?[num]>buf1,"));
buf1[4]='\0'; buf1[4]='\0';
i=strcmp(buf1, "User"); i=strcmp(buf1, "User");
n--; n--;
@ -359,7 +361,7 @@ int loadCache() {
bufi[2]=buf3; bufi[2]=buf3;
bufi[3]=buf4; bufi[3]=buf4;
for (i=60; i>21; i-=4) { for (i=60; i>21; i-=4) {
sprintf(buf, "CRVHDR?%d>>buf1;CRVHDR?%d>>buf2;CRVHDR?%d>>buf3;CRVHDR?%d>>buf4", i, i-1, i-2, i-3); sprintf(buf, "CRVHDR?%d>buf1;CRVHDR?%d>buf2;CRVHDR?%d>buf3;CRVHDR?%d>buf4", i, i-1, i-2, i-3);
ERR_P(LscCmd(ser, buf)); ERR_P(LscCmd(ser, buf));
k=0; k=0;
for (j=i; j>i-4; j--) { for (j=i; j>i-4; j--) {
@ -422,7 +424,7 @@ int SetTemp(int switchOn) {
str_copy(chan, ch); str_copy(chan, ch);
tempH=tempC+tShift; tempH=tempC+tShift;
if (switchOn) { if (switchOn) {
ERR_P(LscCmd(ser, "CSET 1:[chan],1;RANGE:5;SETP 1:[tempH]")); ERR_P(LscCmd(ser, "CSET 1:[chan],1,1,0;RANGE:[iRange];SETP 1:[tempH]"));
} else { } else {
ERR_P(LscCmd(ser, "CSET 1:[chan],1;SETP 1:[tempH]")); ERR_P(LscCmd(ser, "CSET 1:[chan],1;SETP 1:[tempH]"));
} }
@ -445,7 +447,7 @@ int ReadTemp() {
if (noResp) { /* check serial number */ if (noResp) { /* check serial number */
k=serialNo; k=serialNo;
ERR_P(LscCmd(ser, "*IDN?>buf1,buf2,serialNo")); ERR_P(LscCmd(ser, "*IDN?>buf1,buf2,serialNo,"));
if (0!=strcmp(buf1, "LSCI") || 0!=strcmp(buf2, "MODEL340") || serialNo==0) return(0); if (0!=strcmp(buf1, "LSCI") || 0!=strcmp(buf2, "MODEL340") || serialNo==0) return(0);
if (k!=serialNo) { if (k!=serialNo) {
if (cryo.manual || cryo.code!=0) cryo.dirty=1; if (cryo.manual || cryo.code!=0) cryo.dirty=1;
@ -615,7 +617,11 @@ int Settings() {
} }
} }
power=pw; power=pw;
ERR_P(LscCmd(ser, "CLIMIT 1:[tLimit],0,0,[iAmp],[iRange];CSET 1:[cryo.ch1],1,1,0")); /* some times .ch2? */ logfileOut(LOG_MAIN, "power %f\n", power, iAmp, iRange);
ERR_P(LscCmd(ser, "CLIMIT 1:[tLimit],0,0,[iAmp],[iRange]"));
tempC=0.001; tShift=0;
ERR_I(SetTemp(1));
tempC=0;
} }
if (samp.nSens>=cryo.nSens) { if (samp.nSens>=cryo.nSens) {
maxfld=2*samp.nSens; maxfld=2*samp.nSens;

143
tecs/tecs_cli.c Normal file
View File

@ -0,0 +1,143 @@
#include <stdlib.h>
#include <string.h>
#include "err_handling.h"
#include "str_util.h"
#include "tecs_cli.h"
static char device[80], command[80];
static int quit;
static float tempX, tempP, tempC;
pTecsClient TeccInit(char *startcmd, int port) {
CocConn *conn;
ERR_SP(conn=(CocConn *)malloc(sizeof(*conn)));
ERR_I(CocInitClient(conn, "", port, "#rwacs", 0, startcmd));
CocDefFlt(tempC, CocRD);
CocDefFlt(tempP, CocRD);
CocDefFlt(tempX, CocRD);
CocDefStr(device, CocWR);
CocDefInt(quit, CocWR);
CocDefCmd(command);
return((pTecsClient)conn);
OnError: return(NULL);
}
int TeccSetDev(pTecsClient conn, char *dev) {
str_copy(device, dev);
ERR_I(CocCmd(conn, "[device]"));
return(0);
OnError: return(-1);
}
char *TeccGetDev(pTecsClient conn) {
ERR_I(CocCmd(conn, "device"));
return(device);
OnError: return(NULL);
}
int TeccGet3(pTecsClient conn, float *tC, float *tX, float *tP) {
ERR_I(CocCmd(conn, "tempC,tempX,tempP"));
*tC=tempC;
*tX=tempX;
*tP=tempP;
return(0);
OnError: return(-1);
}
int TeccGet(pTecsClient conn, float *temp) {
ERR_I(CocCmd(conn, "tempP"));
*temp=tempP;
return(0);
OnError: return(-1);
}
int TeccSet(pTecsClient conn, float temp) {
tempC=temp;
ERR_I(CocCmd(conn, "[tempC]"));
return(0);
OnError: return(-1);
}
int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen) {
char *res;
int cnt;
str_copy(command, cmd);
ERR_I(CocCmd(conn, "[$]"));
cnt=40;
CocDelay(100);
while (cnt>0) {
ERR_I(CocCmd(conn, "$"));
if (command[0]!='\0') {
str_ncpy(reply, command, replyLen);
return(0);
}
CocDelay(250);
cnt--;
}
str_ncpy(reply, "<no response>", replyLen);
return(0);
OnError: return(-1);
}
int TeccQuitServer(pTecsClient conn) {
quit=1;
ERR_I(CocCmd(conn, "[quit]"));
return(0);
OnError: return(-1);
}
void TeccClose(pTecsClient conn) {
if (conn!=NULL) {
CocCloseClient(conn);
free(conn);
}
}
#ifdef __VMS
int TeccSetDevVms(pTecsClient conn, char **dev) {
int l;
l=*(short *)dev;
if (l>=sizeof(device)) l=sizeof(device)-1;
strncpy(device, dev[1], l);
while (l>0 && device[l-1]==' ') l--; /* trim */
device[l]='\0';
ERR_I(CocCmd(conn, "[device]"));
return(0);
OnError: return(-1);
}
int TeccGetDevVms(pTecsClient conn, char **dev) {
int l, ld;
ERR_I(CocCmd(conn, "device"));
ld=strlen(device);
l=*(short *)dev;
if (ld>=l) ld=l;
strncpy(dev[1], device, ld);
return(ld);
OnError: return(-1);
}
int TeccSendVms(pTecsClient conn, char **cmd, char **reply) {
int l, lr;
char cbuf[80], rbuf[80];
l=*(short *)cmd;
if (l>=sizeof(cbuf)) l=sizeof(cbuf)-1;
strncpy(cbuf, cmd[1], l);
while (l>0 && cbuf[l-1]==' ') l--; /* trim */
cbuf[l]='\0';
ERR_I(TeccSend(conn, cbuf, rbuf, sizeof(rbuf)));
lr=strlen(rbuf);
l=*(short *)reply;
if (lr>=l) lr=l;
strncpy(reply[1], rbuf, lr);
return(lr);
OnError: return(-1);
}
#endif

47
tecs/tecs_cli.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef _TECS_CLI_H_
#define _TECS_CLI_H_
#include "coc_client.h"
/*
tecc.h: tecs client interface routines
M. Zolliker March 2000
------------------------------------------------------------------------*/
typedef CocConn *pTecsClient;
pTecsClient TeccInit(char *server, int port);
/* init tecs client (connect to server)
------------------------------------------------------------------------*/
int TeccSetDev(pTecsClient conn, char *dev);
/* set device type
------------------------------------------------------------------------*/
char *TeccGetDev(pTecsClient conn);
/* get device type
------------------------------------------------------------------------*/
int TeccGet(pTecsClient conn, float *temp);
/* set temperature
------------------------------------------------------------------------*/
int TeccSet(pTecsClient conn, float temp);
/* get temperature
------------------------------------------------------------------------*/
int TeccSend(pTecsClient conn, char *cmd, char *reply, int replyLen);
/* send a command transparently to the controller
replyLen is the maximal length of reply
------------------------------------------------------------------------*/
void TeccClose(pTecsClient conn);
/* close connection and free ressources
------------------------------------------------------------------------*/
int TeccKillServer(pTecsClient conn);
/* kill the server process
------------------------------------------------------------------------*/
#endif /* _TECS_CLI_H_ */

244
tecs/tecs_dlog.c Normal file
View File

@ -0,0 +1,244 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include "err_handling.h"
#include "str_util.h"
#include "tecs_dlog.h"
#define VERSION 1.1
#define DEFINED(F) (abs((F)-dset->undef)>1.0e-5*(F))
static time_t gmtoff;
int DlogWrite(DlogSet *dset, int idx, void *data) {
int p;
p = dset->headsize + (idx % dset->nlen) * dset->fsize;
if (p!=dset->pos) {
ERR_SI(lseek(dset->fd, p, SEEK_SET));
}
ERR_SI(write(dset->fd, data, dset->fsize));
dset->pos = p + dset->fsize;
return(0);
OnError:
return(-1);
}
int DlogRead(DlogSet *dset, int idx, void *data) {
int p;
p = dset->headsize + (idx % dset->nlen) * dset->fsize;
if (p!=dset->pos) {
ERR_SI(lseek(dset->fd, p, SEEK_SET));
}
ERR_SI(read(dset->fd, data, dset->fsize));
dset->pos = p + dset->fsize;
return(0);
OnError:
return(-1);
}
int DlogOpen(DlogSet *dset, char *name, int write) {
int i, p, np, fd, flags;
time_t tim;
struct tm *timp;
fd=0;
str_copy(dset->name, name);
if (write) {
flags=O_RDWR | O_SYNC;
} else {
flags=O_RDONLY | O_SYNC;
}
#ifdef __VMS
ERR_SI(fd=open(name, flags, 0, "SHR=UPD"));
gmtoff=0;
#else
ERR_SI(fd=open(name, flags, 0));
time(&tim);
timp=localtime(&tim);
gmtoff=timp->tm_gmtoff;
#endif
dset->fd=fd;
p=(char *)&dset->fd - (char *)dset;
ERR_SI(read(dset->fd, dset, p));
dset->pos=p;
if ((int)(dset->version*1000+0.5) != (int)(VERSION*1000+0.5)) ERR_MSG("version mismatch");
if (dset->headsize != p) ERR_MSG("illegal dlog file");
return(0);
OnError:
if (fd!=0) close(fd);
return(-1);
}
int DlogCreate(DlogSet *dset, char *name, time_t start, int nset, int nlen, int period, float undef) {
int fd, i, j, p;
va_list ap;
float f[DLOG_MAX_SET];
fd=0;
if (nset>DLOG_MAX_SET) ERR_MSG("nset too large");
dset->nset=nset;
dset->nlen=nlen;
dset->start=start;
dset->last=start-period;
dset->period=period;
dset->undef=undef;
dset->version=VERSION;
str_copy(dset->name, name);
for (i=0; i<nset; i++) {
f[i]=dset->undef;
}
ERR_SI(fd=open(name, O_RDWR | O_CREAT | O_SYNC | O_TRUNC, 0666));
dset->fd=fd;
p=(char *)&dset->fd - (char *)dset;
dset->headsize = p;
dset->fsize = nset * sizeof(float);
ERR_SI(write(dset->fd, dset, p));
dset->pos=p;
return(0);
OnError:
if (fd!=0) close(fd);
return(-1);
}
int DlogPut(DlogSet *dset, time_t time, int nset, float val[]) {
int i, i0, j;
float f[DLOG_MAX_SET], f0[DLOG_MAX_SET];
if (nset > dset->nset) nset = dset->nset;
for (j=0; j < nset; j++) { f[j]=val[j]; }
for (j=nset; j < dset->nset; j++) { f[j]=dset->undef; }
i = ( time - dset->start ) / dset->period;
i0 = ( dset->last - dset->start ) / dset->period;
if (i0==i) {
ERR_I(DlogRead(dset, i, f0));
for (j=0; j<nset; j++) {
if (DEFINED(f0[j]) && /* when last point defined */
(i%2 && f0[j]>f[j] || /* take maximum (for odd i) */
!i%2 && f0[j]<f[j] ) /* or minimum (for even i) */
) f[j]=f0[j]; /* of f0 and f0 */
}
} else if (i0<i-1) {
for (j=0; j < dset->nset; j++) { f0[j]=dset->undef; }
i0++;
while (i0<i) {
ERR_I(DlogWrite(dset, i0, f0));
i0++;
}
}
ERR_I(DlogWrite(dset, i, f));
dset->last=time;
return(0);
OnError:
return(-1);
}
int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float x[], float y[]) {
int i0, i1, i, n, undef;
float f[DLOG_MAX_SET];
if (iset<0) ERR_MSG("illegal iset");
if (iset>=dset->nset) return(0);
i = ( dset->last - dset->start ) / dset->period;
if (i - dset->nlen > 0) {
i1 = i - dset->nlen + 1;
} else {
i1 = 0;
}
i0=i1;
*starttime = dset->start + i1 * dset->period + gmtoff;
n=0;
undef=2;
while (i0<=i) {
if (n>=nmax) return(n);
ERR_I(DlogRead(dset, i0, f));
i0++;
if (DEFINED(f[iset])) {
x[n]=(float)(i0-i1)*dset->period;
y[n]=f[iset];
n++;
undef=0;
} else if (undef==0) {
undef=1;
} else if (undef==1) {
undef=2;
x[n]=0;
y[n]=0;
n++;
}
}
return(n);
OnError:
return(-1);
}
int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[], float y[], int index[]) {
int n, k, nmx, ntot;
ntot=0;
for (k=0; k<nset; k++) {
index[k]=ntot;
nmx=(nmax-ntot)/(nset-k);
ERR_I(n=DlogGet(dset, k, nmx, starttime, &x[ntot], &y[ntot]));
ntot+=n;
}
return(ntot);
OnError:
return(-1);
}
int dlog_get_(char *name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[], int namlen) {
DlogSet dset;
char buf[64];
int ntot;
/* for compaq unix */
str_trim(buf, name, namlen);
ERR_I(DlogOpen(&dset, buf, 0));
ERR_I(ntot=DlogGetMany(&dset, *nset, *nmax, starttime, x, y, index));
DlogClose(&dset);
return(ntot);
OnError:
ErrWrite("error in dlog_get_");
return(-1);
}
int Dlog_Get(char **name, int *nset, int *nmax, double *starttime, float x[], float y[], int index[]) {
/* for VMS */
return(dlog_get_(name[1], nset, nmax, starttime, x, y, index, *(short *)name));
}
int DlogUpd(DlogSet *dset) {
ERR_SI(lseek(dset->fd, 0, SEEK_SET));
ERR_SI(write(dset->fd, &dset->last, sizeof(int)));
dset->pos=sizeof(int);
#ifdef __VMS
close(dset->fd);
DlogOpen(dset, dset->name, 1);
#endif
return(0);
OnError:
return(-1);
}
int DlogClose(DlogSet *dset) {
ERR_I(DlogUpd(dset));
close(dset->fd);
return(0);
OnError:
return(-1);
}

54
tecs/tecs_dlog.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef _DLOG_H_
#define _DLOG_H_
#include <time.h>
#define DLOG_MAX_SET 32
typedef struct {
time_t last, start;
float version, undef;
int period, headsize, fsize, nset, nlen;
int fd, pos;
char name[128];
} DlogSet;
int DlogOpen(DlogSet *dset, char *name, int write);
/* open existing dlog set */
int DlogCreate(DlogSet *dset, char *name, time_t start, int nset, int nlen, int period, float undef);
/* create new dlog file */
int DlogPut(DlogSet *dset, time_t time, int nset, float val[]);
/* put values to dlog set */
int DlogGet(DlogSet *dset, int iset, int nmax, double *starttime, float *x, float *y);
/* get one dataset from dlog set
iset is the dataset to be returned
nmax is the maximal number of points to be returned
x, y: the data (arrays declared with at least nmax elements)
on success, the return value is the effective length of returned data
*/
int DlogGetMany(DlogSet *dset, int nset, int nmax, double *starttime, float x[], float y[], int index[]);
/* get many datasets from dlog set
nset is the nember of datasets to be returned
nmax is the maximal number of points to be returned
x, y: the data, one dataset after an other (arrays declared with at least nmax elements)
index must be an array of at least nset elements.
it returns the start indices in x[] and y[] of the data sets.
on success, the return value is the effective length of returned data
*/
int DlogUpd(DlogSet *dset);
/* update pointer */
int DlogClose(DlogSet *dset);
/* close dlog set */
#endif /* _DLOG_H_ */

179
tecs/tecs_lsc.c Normal file
View File

@ -0,0 +1,179 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include "err_handling.h"
#include "coc_logfile.h"
#include "coc_util.h"
#include "tecs_lsc.h"
#include "str_util.h"
#define MAX_PAR 16
#define MAX_ARG 9
int LscEqPar(char *par, char *res) {
char *p, *r, pbuf[SER_BUF_LEN], rbuf[SER_BUF_LEN];
int i,n,i1,i2;
float f1, f2;
p=par;
r=res;
while (p!=NULL) {
if (r==NULL) {
return(0);
}
p=str_split(pbuf, p, ',');
str_trim(pbuf, pbuf, sizeof(pbuf));
r=str_split(rbuf, r, ',');
str_trim(rbuf, rbuf, sizeof(rbuf));
if (pbuf[0]!='\0' && 0!=strcasecmp(pbuf, rbuf)) {
i1=sscanf(pbuf, "%f", &f1);
i2=sscanf(rbuf, "%f", &f2);
if (i1!=1 || i2!=1 || abs(f1-f2)>1e-4+abs(f1)*5e-6) {
logfileOut(LOG_WARN, "%s#%s\n", pbuf, rbuf);
return(0);
}
}
}
return(1);
}
#define nLIST 30
char *LscCmd(SerChannel *ser, const char *cmds) {
va_list ap;
char *blank, *colon, *qu, *res;
const char *p, *this, *next, *cmd_ptr, *retreq;
const char *list[nLIST];
char seg[SER_BUF_LEN], buf[SER_BUF_LEN], result[SER_BUF_LEN], par[SER_BUF_LEN];
char cmd[SER_BUF_LEN];
char varname[32];
Str_Buf sbuf;
int nres, i, j, response;
nres=0;
response=0;
str_link_buf(&sbuf, buf, sizeof(buf), STR_NOSEPARATOR);
this=cmds;
while (this!=NULL) {
next=str_split(cmd, this, ';');
retreq=strchr(cmd, '>');
if (retreq!=NULL) { /* save pointer to return request */
i=retreq-cmd;
cmd[i]='\0'; /* cut return request */
list[nres]=this+i;
nres++; assert(nres<=nLIST);
}
cmd_ptr=sbuf.buf+sbuf.wrpos; /* pointer to command in buffer */
p=str_split(seg, cmd, '[');
ERR_I(str_put_str(&sbuf, seg));
while (p!=NULL) { /* substitute variables */
p=str_split(varname, p, ']');
if (p==NULL) ERR_MSG("missing '\'");
ERR_I(CocPutVar(serverVarList, &sbuf, varname, 0));
p=str_split(seg, p, '[');
ERR_I(str_put_str(&sbuf, seg));
}
ERR_I(str_copy(cmd, cmd_ptr));
colon=strchr(cmd_ptr, ':');
if (colon!=NULL) { /* command with query */
blank=strchr(cmd_ptr, ' ');
if (blank==NULL || blank>colon) {
*colon=' '; blank=colon;
} else {
*colon=',';
}
list[nres]=colon+1; nres++; assert(nres<=nLIST); /* pointer to parameters */
list[nres]=cmd_ptr; nres++; assert(nres<=nLIST); /* pointer to command */
ERR_I(str_put_str(&sbuf, ";"));
cmd[blank-cmd_ptr]='?'; /* build query */
if (colon==blank) colon++;
cmd[colon-cmd_ptr]='\0';
ERR_I(str_put_str(&sbuf, cmd)); /* put query */
ERR_I(str_put_str(&sbuf, ";"));
response=1;
} else {
qu=strchr(cmd, '?');
ERR_I(str_put_str(&sbuf, ";"));
if (qu!=NULL) { /* command is a query */
response=1;
if (retreq==NULL) {
/* ERR_MSG("missing return format"); */
}
list[nres]=NULL; nres++; assert(nres<=nLIST);
} else {
if (retreq!=NULL) ERR_MSG("no return request allowed after command without query ");
}
}
this=next;
}
if (!response) {
ERR_I(str_put_str(&sbuf, "busy?"));
} else {
buf[sbuf.wrpos-1]='\0'; /* strip off trailing ";" */
}
ERR_P(res=SerCmd(ser, buf));
if (0==strcmp("?TMO", res)) ERR_MSG("timeout");
/*
list[0..nres-1] contains a now:
for a command with return request:
- a pointer to a the request
then, for a command with query:
- a pointer to the parameters and
- a pointer to the command
this is repeated for every command
*/
/* check results */
this=res;
for (i=0; i<nres; i++) {
if (this==NULL) ERR_MSG("not all results received");
this=str_split(result, this, ';');
retreq=list[i];
if (retreq!=NULL) {
if (retreq[0]=='>') {
i++;
} else {
retreq=NULL;
}
}
if (list[i]!=NULL) {
qu=str_split(par, list[i], ';'); /* get parameters */
i++;
if (!LscEqPar(par, result)) { /* try again with single command */
qu=strchr(qu, ';');
assert(list[i]!=NULL);
str_copy(cmd, list[i]);
if (qu!=NULL) cmd[qu-list[i]]='\0';
ERR_P(qu=SerCmd(ser, cmd));
if (!LscEqPar(par, qu)) {
if (0!=strcmp(result, qu)) {
ERR_MSG("result does not match");
} else {
ERR_MSG("result does not match command");
}
}
}
}
if (retreq!=NULL) { /* query */
str_link_buf(&sbuf, result, 0, ',');
str_split(par, retreq+1, ';');
p=par;
while (p!=NULL) {
p=str_split(varname, p, ',');
if (varname[0]!='\0') {
if (p==NULL) { /* last element: get rest of line */
sbuf.sep='\0';
}
ERR_I(CocGetVar(serverVarList, &sbuf, varname, 0));
} else {
ERR_P(str_get_str(&sbuf, NULL));
}
}
}
}
return(res);
OnError: return(NULL);
}

52
tecs/tecs_lsc.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef _TECS_LSC_H_
#define _TECS_LSC_H_
#include "tecs_serial.h"
char *LscCmd(SerChannel *ser, const char *cmds);
/*
Send commands to LSC-340.
There may be several commands separated by semicolon.
A special syntax is used:
- Commands containing a colon are commands with query,
i.e. the sent parameters are checked. The sent parameters
are those after the query, the command before the colon
is used as query, after inserting a question mark.
- Variable names in square brackets are substitute by their value
- Return values may be assigned to variables, separated by
a right angle bracket. There may be several variables
separated by comma, corresponding to the returned parameters,
beeing separated by commas also. If the variable is not terminated
by a comma, the whole remaining result is assigned, even if it
contains commas. Return values may only be used when a command
with wuery was sent, or when the command was a query (containing
a question mark).
Example:
LscCmd(ser, "RANGE:5>range;SETP 1:[tempH];CRVHDR?[num]>name,head;MODE 2");
assume that tempH=295 and num=25 the command sent to LSC is:
RANGE 5;RANGE?;SETP 1,295;SETP?1;CRVHDR?25;MODE 2
and assume LSC sens back:
3;295.000E+00;CTI5 ,R10410 ,3,+330.000E+0,2
then the following variables will be assigned:
range=3
name="CTI5"
head="R10410 ,3,+330.000E+0,2"
All used variables have to be declared with CocDef... (see coc_util.h)
*/
int LscEqPar(char *par, char *res);
/*
compare if parameters are equal (numbers as numbers, spaces ignored)
if any parameter in par is omitted, it is not compared
*/
#endif /* _TECS_LSC_H_ */

97
tecs/tecs_serial.c Normal file
View File

@ -0,0 +1,97 @@
#include <stdlib.h>
#include <string.h>
#include "rs232c_def.h"
#include "asynsrv_def.h"
#include "sinq_prototypes.h"
#include "err_handling.h"
#include "tecs_serial.h"
#include "coc_logfile.h"
#include "str_util.h"
#define A_CHK(R) if (1!=(R)) { SerA_error(); ErrTxt(#R,0); goto OnError; }
void (*idleHandler)(int,int);
struct SerChan {
struct AsynSrv__info asyn_info; /* Contains skt, host, port & chan */
struct RS__MsgStruct to_host;
struct RS__RespStruct from_host;
char cmd[SER_BUF_LEN];
};
void SerA_error(void) {
char *a_txt;
int a_cod, a_my, a_vms;
AsynSrv_ErrInfo(&a_txt, &a_cod, &a_my, &a_vms);
ErrMsg("asynsrv error"); ErrTxt(a_txt,0);
}
SerChannel *SerOpen(const char *host, int msecTmo, void (*idleHdl)(int,int)) {
struct SerChan *ser;
char hbuf[64], cport[16];
char *p, *c;
int port, chan;
idleHandler=idleHdl;
ser=calloc(1, sizeof(*ser));
str_copy(hbuf, host);
p=str_split(ser->asyn_info.host, hbuf, ':');
port=4000;
chan=0;
if (p!=NULL) {
c=str_split(cport, p, '/');
if (c!=NULL) chan=atoi(c);
port=atoi(cport);
}
ser->asyn_info.port=port;
ser->asyn_info.chan=chan;
logfileOut(LOG_MAIN, "open connection to %s:%d/%d\n", ser->asyn_info.host, ser->asyn_info.port, ser->asyn_info.chan);
A_CHK(AsynSrv_Open(&ser->asyn_info));
if (msecTmo==0) msecTmo=5000;
A_CHK(AsynSrv_Config(&ser->asyn_info, "msecTmo", msecTmo, "idleHdl", idleHdl, NULL));
return((SerChannel *)ser);
OnError: return(NULL);
}
int SerClose(SerChannel *serch) {
struct SerChan *ser;
ser=(struct SerChan *)serch;
A_CHK(AsynSrv_Close(&ser->asyn_info, 0));
return(0);
OnError: return(-1);
}
char *SerCmdC(SerChannel *serch, const char *cmnd) {
char cmd[SER_BUF_LEN];
int l;
l=strlen(cmnd);
if (l>=SER_BUF_LEN-1) ERR_COD(ENOBUFS);
strcpy(cmd, cmnd);
return(SerCmd(serch, cmd));
OnError: return(NULL);
}
char *SerCmd(SerChannel *serch, char *cmnd) {
int l;
struct SerChan *ser;
char *result;
l=strlen(cmnd);
if (l>=SER_BUF_LEN-1) ERR_COD(ENOBUFS);
ser=(struct SerChan *)serch;
logfileOut(LOG_SER, ">%s\n", cmnd);
cmnd[l]=ser->asyn_info.eot[1];
cmnd[l+1]='\0';
A_CHK(AsynSrv_SendCmnds(&ser->asyn_info, &ser->to_host, &ser->from_host, cmnd, NULL));
result=AsynSrv_GetReply(&ser->asyn_info, &ser->from_host, NULL);
if (result==NULL) ERR_MSG("empty result");
/* if (idleHandler!=NULL) idleHandler(50,0); */
logfileOut(LOG_SER, "<%s\n", result);
return(result);
OnError: return(NULL);
}

13
tecs/tecs_serial.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _SERUTIL_H_
#define _SERUTIL_H_
#define SER_BUF_LEN 320
typedef struct { int private; } SerChannel;
SerChannel *SerOpen(const char *host, int msecTmo, void (*idleHdl)(int,int));
char *SerCmdC(SerChannel *ser, const char *cmnd);
char *SerCmd(SerChannel *ser, char *cmnd);
int SerClose(SerChannel *ser);
#endif /* _SERUTIL_H_ */