Compare commits
106 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89a6d17353 | ||
|
|
d9666a8f30 | ||
|
|
7cb76ae9e4 | ||
|
|
46e00da251 | ||
|
|
39d98562fc | ||
|
|
8624be05d4 | ||
|
|
c0da182217 | ||
|
|
6dab97f8e7 | ||
|
|
1abcc71e71 | ||
|
|
f8f17eeb33 | ||
|
|
db50e1bdd7 | ||
|
|
96605d4439 | ||
|
|
593bc413bf | ||
|
|
3e20abece8 | ||
|
|
79c01170e8 | ||
|
|
6c21758d23 | ||
|
|
d2347c497c | ||
|
|
099f63fb20 | ||
|
|
665a5134d3 | ||
|
|
e1b04e69bb | ||
|
|
8375a2cf18 | ||
|
|
300f38584b | ||
|
|
b9a5acc88c | ||
|
|
2ff81c09f0 | ||
|
|
63eefd2ba8 | ||
|
|
f9f8e55035 | ||
|
|
0f8f36c4bb | ||
|
|
fd6e666256 | ||
|
|
d492d665fc | ||
|
|
6b659e8404 | ||
|
|
43ecde53f3 | ||
|
|
e6ffa71c54 | ||
|
|
be6ecdfe24 | ||
|
|
e6bec6af38 | ||
|
|
59a2f10867 | ||
|
|
00abe6b876 | ||
|
|
b0e9cc9fba | ||
|
|
6eb04984bd | ||
|
|
d9a05d6051 | ||
|
|
d9233e4864 | ||
|
|
34bd710ffa | ||
|
|
438f00a708 | ||
|
|
622a225308 | ||
|
|
1c14ac4941 | ||
|
|
df2ce01069 | ||
|
|
f7aa394524 | ||
|
|
ed6047ec51 | ||
|
|
a3573cd384 | ||
|
|
81deb4fceb | ||
|
|
b7378bbc62 | ||
|
|
bdffdb0369 | ||
|
|
98809f8141 | ||
|
|
8a0f66cb9b | ||
|
|
0462aed01d | ||
|
|
ea279855da | ||
|
|
66210afed7 | ||
|
|
c13d342680 | ||
|
|
549a4ba978 | ||
|
|
cf7fe3deb4 | ||
|
|
ef8abaa44f | ||
|
|
5624aaefe1 | ||
|
|
2b7e4ff84d | ||
|
|
fb2c2f0925 | ||
|
|
55dae7db1c | ||
|
|
524da0d2df | ||
|
|
93c191ffe9 | ||
|
|
0dc2be41d3 | ||
|
|
11af4456c7 | ||
|
|
f232999d32 | ||
|
|
ca13bfdff9 | ||
|
|
21cbea930a | ||
|
|
8b06e22907 | ||
|
|
f3dcfd60bb | ||
|
|
1b33e449c6 | ||
|
|
afa208a5e1 | ||
|
|
5903ff0cdb | ||
|
|
51d44c6200 | ||
|
|
a362731044 | ||
|
|
0e225a4335 | ||
|
|
8c0527c25a | ||
|
|
92f91ee2cc | ||
|
|
1bd52dfef9 | ||
|
|
c7005b4783 | ||
|
|
d9e3f09760 | ||
|
|
07a265d299 | ||
|
|
feb73d85b3 | ||
|
|
f18238a8b9 | ||
|
|
8ff5572e6c | ||
|
|
865e69d7d3 | ||
|
|
38f82f342d | ||
|
|
20fd27263a | ||
|
|
7760d16956 | ||
|
|
3fab82780b | ||
|
|
fd679234dd | ||
|
|
7f949f441b | ||
|
|
48640936f5 | ||
|
|
1e2d258c66 | ||
|
|
83d4ee2313 | ||
|
|
67324dc7b7 | ||
|
|
47843d49a0 | ||
|
|
d27f70a883 | ||
|
|
bcde03d0a0 | ||
|
|
1887fbd7f8 | ||
|
|
f3e0f33d15 | ||
|
|
09e1c40650 | ||
|
|
0de34c3162 |
125
MakeRelease
Executable file
125
MakeRelease
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Make Release - Creates an EPICS release
|
||||
# By Matthew Needes and Bob Zieman
|
||||
#
|
||||
# MakeRelease [-b]
|
||||
#
|
||||
# [-b] - For fully built release
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.14 1994/12/19 18:42:08 tang
|
||||
# Make the args length compatible for HP and SUN.
|
||||
#
|
||||
# Revision 1.13 1994/12/15 19:19:18 tang
|
||||
# Replace -I opt by cat and xargs for tar for HP compatibility.
|
||||
#
|
||||
# Revision 1.12 1994/12/14 23:57:55 tang
|
||||
# Take out \< and \> pair for hp compatible
|
||||
#
|
||||
# Revision 1.11 1994/10/31 21:44:17 jba
|
||||
# Moved print stmnt, added cd $(EPICS)
|
||||
#
|
||||
# Revision 1.10 1994/10/05 18:29:34 jba
|
||||
# Renamed version.h to epicsVersion.h
|
||||
#
|
||||
# Revision 1.9 1994/09/22 01:41:47 mcn
|
||||
# MakeRelease - MAJOR bug fix. GetVar / MakeDirs - minor fix.
|
||||
#
|
||||
# Revision 1.8 1994/09/07 20:59:15 mcn
|
||||
# Revamped GetVar, modified scripts for new GetVar.
|
||||
#
|
||||
# Revision 1.7 1994/09/02 20:58:00 mcn
|
||||
# minor change.
|
||||
#
|
||||
# Revision 1.6 1994/08/21 00:56:41 mcn
|
||||
# New Stuff
|
||||
#
|
||||
# Revision 1.5 1994/08/02 18:36:29 mcn
|
||||
# Support new configuration.
|
||||
#
|
||||
# Revision 1.4 1994/07/14 22:13:32 mcn
|
||||
# Now include SDR Makefile/Headers
|
||||
#
|
||||
#
|
||||
|
||||
EPICS=${1};
|
||||
|
||||
if [ ! -d include -o ! -d src ]; then
|
||||
echo "Cannot find src or include, are you at the top of EPICS base ?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $EPICS/base
|
||||
|
||||
FULLY_BUILT=NO
|
||||
if [ "${2}" = "-b" ]; then
|
||||
FULLY_BUILT=YES
|
||||
shift
|
||||
fi
|
||||
|
||||
# Retrieve EPICS release string from include/epicsVersion.h
|
||||
grep EPICS_VERSION_STRING include/epicsVersion.h > /dev/null 2>&1 || ERR=1;
|
||||
|
||||
if [ "$ERR" = "1" ];
|
||||
then
|
||||
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
RELS=`grep "EPICS_VERSION_STRING" include/epicsVersion.h \
|
||||
| sed -e 's-.*Version--' \
|
||||
-e 's-[ ][ ]*--g' \
|
||||
-e 's-".*--' \
|
||||
-e 's-\.0$--'`;
|
||||
|
||||
if [ -z "${RELS}" ];
|
||||
then
|
||||
echo "TOP: Cannot retrieve release number from include/epicsVersion.h";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
RELS="R${RELS}";
|
||||
|
||||
echo TOP: Creating ../${RELS}.Tar;
|
||||
|
||||
if [ -f ${RELS}.Tar* ];
|
||||
then
|
||||
echo "TOP: This release has already been created.";
|
||||
echo "TOP: Remove Tar file or edit include/epicsVersion.h.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Create list of files and dirs to include in Tar file
|
||||
|
||||
cd $EPICS
|
||||
|
||||
ls base/README* | xargs tar cvf ${RELS}.Tar
|
||||
|
||||
ls base/Makefile* > /tmp/make_release.out.$$;
|
||||
|
||||
find config base/include base/man base/tools -name CVS -prune -o \
|
||||
! -type d -print >> /tmp/make_release.out.$$;
|
||||
|
||||
# binary / library / default.dctsdr / <rec>Record.h / etc.
|
||||
if [ $FULLY_BUILT = "YES" ];
|
||||
then
|
||||
find base/bin -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
|
||||
find base/lib -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
|
||||
find base/rec -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
fi
|
||||
|
||||
find base/src -name CVS -prune -o -name SCCS -prune -o ! -type d -print \
|
||||
| grep -v '/O\..*$' >> /tmp/make_release.out.$$
|
||||
|
||||
cat /tmp/make_release.out.$$ | xargs tar rvf ${RELS}.Tar
|
||||
|
||||
rm /tmp/make_release.out.$$
|
||||
|
||||
49
Makefile
49
Makefile
@@ -12,6 +12,9 @@
|
||||
# install because the release.% syntax is illegal.
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.23 1995/02/13 15:00:09 jba
|
||||
# Changed include file from CONFIG_SITE to CONFIG
|
||||
#
|
||||
# Revision 1.22 1994/11/14 23:12:17 tang
|
||||
# Replace ARCH_TYPE with .
|
||||
#
|
||||
@@ -74,21 +77,27 @@ depends:
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
|
||||
clean:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
|
||||
uninstall:
|
||||
@(for ARCH in ${BUILD_ARCHS}; \
|
||||
do \
|
||||
ARCH_TYPE=$$ARCH \
|
||||
${MAKE} ${MFLAGS} $@.$$ARCH; \
|
||||
done)
|
||||
|
||||
release:
|
||||
@echo TOP: Creating Release...
|
||||
@tools/MakeRelease
|
||||
@./MakeRelease ${EPICS}
|
||||
|
||||
built_release: install
|
||||
@echo TOP: Creating Fully Built Release...
|
||||
@tools/MakeRelease -b
|
||||
|
||||
clean:
|
||||
@echo "TOP: Cleaning"
|
||||
@tools/Clean
|
||||
|
||||
uninstall:
|
||||
rm -rf bin/* lib/* rec.bak
|
||||
rm -f rec/default.dctsdr rec/default.sdrSum rec/*.h
|
||||
@./MakeRelease ${EPICS} -b
|
||||
|
||||
# Notes for single architecture build rules:
|
||||
# CheckArch only has to be run for dirs.% . That
|
||||
@@ -107,20 +116,15 @@ uninstall:
|
||||
# some things may be included on a per architecture
|
||||
# basis.
|
||||
|
||||
dirs.%:
|
||||
@tools/CheckArch $*
|
||||
@echo $*: Creating Directories
|
||||
@tools/MakeDirs $*
|
||||
|
||||
build.%: dirs.%
|
||||
build.%:
|
||||
@echo $*: Building
|
||||
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs build
|
||||
|
||||
install.%: dirs.%
|
||||
install.%:
|
||||
@echo $*: Installing
|
||||
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs install
|
||||
|
||||
depends.%: dirs.%
|
||||
depends.%:
|
||||
@echo $*: Performing Make Depends
|
||||
@${MAKE} ${MFLAGS} T_A=$* -f Makefile.subdirs depends
|
||||
|
||||
@@ -133,11 +137,10 @@ release.%:
|
||||
@echo
|
||||
|
||||
uninstall.%:
|
||||
@echo
|
||||
@echo "The uninstall.arch syntax is not supported by this build."
|
||||
@echo
|
||||
@echo "TOP: Uninstalling $* "
|
||||
@rm -rf ./bin/$* ./lib/$* rec.bak rec
|
||||
|
||||
clean.%:
|
||||
@echo "$*: Cleaning"
|
||||
@tools/Clean $*
|
||||
@echo "TOP: Cleaning $* "
|
||||
@find src -type d -name "O.$*" -prune -exec rm -rf {} \;
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
# by Matthew Needes and Mike Bordua
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.13 1994/09/09 17:32:29 jba
|
||||
# Cleanup of files
|
||||
#
|
||||
# Revision 1.12 1994/09/08 17:25:41 mcn
|
||||
# Changed clean to tools/Clean. Added "uninstall" dependency.
|
||||
#
|
||||
@@ -27,7 +30,7 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
build: dirs
|
||||
@(for DIR in ${DIRS}; \
|
||||
do \
|
||||
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
|
||||
@@ -35,7 +38,7 @@ build:
|
||||
cd $$TMP; \
|
||||
done)
|
||||
|
||||
install:
|
||||
install: dirs
|
||||
@(for DIR in ${DIRS}; \
|
||||
do \
|
||||
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
|
||||
@@ -43,7 +46,7 @@ install:
|
||||
cd $$TMP; \
|
||||
done)
|
||||
|
||||
depends:
|
||||
depends: dirs
|
||||
@(for DIR in ${DIRS}; \
|
||||
do \
|
||||
TMP=`pwd`; echo "${T_A}: $@: $$DIR"; \
|
||||
@@ -51,3 +54,23 @@ depends:
|
||||
cd $$TMP; \
|
||||
done)
|
||||
|
||||
dirs:
|
||||
@echo ${T_A}: Creating Directories
|
||||
@for DIR in ${DIRS}; \
|
||||
do \
|
||||
TMP=`pwd`; \
|
||||
cd $$DIR ; \
|
||||
if [ -f Makefile.${BUILD_TYPE} ] ; then \
|
||||
test -d O.${T_A} || \
|
||||
mkdir O.${T_A}; \
|
||||
test -f O.${T_A}/Makefile || \
|
||||
ln -s ../Makefile.${BUILD_TYPE} O.${T_A}/Makefile \
|
||||
> /dev/null 2> /dev/null; \
|
||||
test -f O.${T_A}/Target.include || \
|
||||
echo "T_A=${T_A}" > O.${T_A}/Target.include; \
|
||||
test -f O.${T_A}/.DEPENDS || \
|
||||
touch O.${T_A}/.DEPENDS; \
|
||||
fi ; \
|
||||
cd $$TMP; \
|
||||
done
|
||||
|
||||
|
||||
2
README
2
README
@@ -74,7 +74,7 @@ gmake
|
||||
be complete before this can be issued).
|
||||
|
||||
NOTES:
|
||||
1. tools/MakeRelease will create tar files in the directory ABOVE
|
||||
1. base/MakeRelease will create tar files in the directory ABOVE
|
||||
base. These tar files are then meant to be untarred at that level.
|
||||
This release will include the "epics/config" directory.
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
USR_CFLAGS = -DACCESS_SECURITY -D_NO_PROTO
|
||||
|
||||
SRCS.c = ../asDbLib.c ../asCa.c asLib.c
|
||||
OBJS = asDbLib.o asCa.o asLib.o
|
||||
PROD = asLibrary
|
||||
LIBOBJS = asDbLib.o asCa.o asLib.o
|
||||
LIBNAME = asLibrary
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
@@ -18,7 +18,4 @@ asLib.o: asLib_lex.c ../asLibRoutines.c
|
||||
clean::
|
||||
@$(RM) asLib_lex.c asLib.c
|
||||
|
||||
asLibrary : $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
@@ -148,13 +148,16 @@ static long asInitCommon(void)
|
||||
long status;
|
||||
char buffer[BUF_SIZE];
|
||||
|
||||
if(!pacf) return(0);
|
||||
if(asLockInit) {
|
||||
FASTLOCKINIT(&asLock);
|
||||
asLockInit = FALSE;
|
||||
}
|
||||
FASTLOCK(&asLock);
|
||||
if(asActive)asCaStop();
|
||||
if(!pacf) {
|
||||
asActive = FALSE;
|
||||
return(0);
|
||||
}
|
||||
buffer[0] = 0;
|
||||
my_buffer = buffer;
|
||||
my_buffer_ptr = my_buffer;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
integer [0-9]
|
||||
name [a-zA-Z0-9_\.]
|
||||
pvname [a-zA-Z0-9_:\.\[\]<>;]
|
||||
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
|
||||
string [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$]
|
||||
|
||||
%{
|
||||
|
||||
18
src/bdt/Makefile
Normal file
18
src/bdt/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Base Lowest Level Directroy Makefile
|
||||
# by Janet Anderson
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.1 1994/09/07 19:26:22 jba
|
||||
# New file
|
||||
#
|
||||
#
|
||||
|
||||
EPICS=../../..
|
||||
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
include $(EPICS)/config/RULES_ARCHS
|
||||
|
||||
10
src/bdt/Makefile.Unix
Normal file
10
src/bdt/Makefile.Unix
Normal file
@@ -0,0 +1,10 @@
|
||||
EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
|
||||
LIBOBJS += bdt.o
|
||||
|
||||
LIBNAME = libBdt.a
|
||||
|
||||
include $(EPICS)/config/RULES.Unix
|
||||
21
src/bdt/Makefile.Vx
Normal file
21
src/bdt/Makefile.Vx
Normal file
@@ -0,0 +1,21 @@
|
||||
EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
SRCS.c += ../bdt.c
|
||||
SRCS.c += ../bdtServ.c
|
||||
SRCS.c += ../bdtServName.c
|
||||
SRCS.c += ../bdtServPv.c
|
||||
|
||||
OBJS += bdt.o
|
||||
OBJS += bdtServ.o
|
||||
OBJS += bdtServName.o
|
||||
OBJS += bdtServPv.o
|
||||
|
||||
PROD = bdt
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
$(PROD): $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
701
src/bdt/bdt.c
Normal file
701
src/bdt/bdt.c
Normal file
@@ -0,0 +1,701 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef linux
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <in.h>
|
||||
#include <inetLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <selectLib.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bdt.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* server mode functions */
|
||||
|
||||
#ifndef vxWorks /* server mode functions */
|
||||
static char* filename=(char*)NULL;
|
||||
|
||||
/* ----------------------------- */
|
||||
/* signal catcher for the server */
|
||||
/* ----------------------------- */
|
||||
static void catch_sig(int sig)
|
||||
{
|
||||
fprintf(stderr,"\nbdt server exiting\n");
|
||||
unlink(filename);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* -------------------------------- */
|
||||
/* child reaper for the server mode */
|
||||
/* -------------------------------- */
|
||||
static void get_child(int sig)
|
||||
{
|
||||
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
|
||||
#ifdef linux
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* Clear the signals for a process */
|
||||
/* ------------------------------- */
|
||||
int BdtServerClearSignals()
|
||||
{
|
||||
signal(SIGCHLD,SIG_DFL);
|
||||
signal(SIGHUP,SIG_DFL);
|
||||
signal(SIGINT,SIG_DFL);
|
||||
signal(SIGTERM,SIG_DFL);
|
||||
signal(SIGQUIT,SIG_DFL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Make a unix process into a generic background process */
|
||||
/* ----------------------------------------------------- */
|
||||
int BdtMakeServer(char** argv)
|
||||
{
|
||||
FILE* fd;
|
||||
|
||||
if(filename) return -1;
|
||||
|
||||
/* set up signal handling for the server */
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
signal(SIGHUP,catch_sig);
|
||||
signal(SIGINT,catch_sig);
|
||||
signal(SIGTERM,catch_sig);
|
||||
signal(SIGQUIT,catch_sig);
|
||||
|
||||
/* disconnect from parent */
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("Cannot fork");
|
||||
return -1;
|
||||
case 0: /* child */
|
||||
#ifdef linux
|
||||
setpgrp();
|
||||
#else
|
||||
setpgrp(0,0);
|
||||
#endif
|
||||
setsid();
|
||||
break;
|
||||
default: /* parent goes away */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* save process ID */
|
||||
filename=(char*)malloc(strlen(argv[0])+10);
|
||||
sprintf(filename,"%s.%d",argv[0],getpid());
|
||||
fd=fopen(filename,"w");
|
||||
fprintf(fd,"%d",getpid());
|
||||
fprintf(stderr,"\npv server pid: %d\n",getpid());
|
||||
fclose(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* server mode functions */
|
||||
|
||||
/* ------------------------------------------ */
|
||||
/* unimplemented channel access open function */
|
||||
/* ------------------------------------------ */
|
||||
BDT* BdtPvOpen(char *IocName, char* PvName)
|
||||
{
|
||||
BDT *bdt;
|
||||
|
||||
if((bdt = BdtIpOpen(IocName, BDT_TCP_PORT)) == NULL)
|
||||
{
|
||||
fprintf(stderr,"open of address %s failed\n", IocName);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(BdtServiceConnect(bdt, BDT_SERVICE_PV, PvName) < 0)
|
||||
{
|
||||
fprintf(stderr,"connect to PV %s failed\n", PvName);
|
||||
BdtClose(bdt);
|
||||
return(NULL);
|
||||
}
|
||||
return(bdt);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
/* open a bulk data socket to a server given the server IP address */
|
||||
/* --------------------------------------------------------------- */
|
||||
BDT* BdtIpOpen(char* address, int Port)
|
||||
{
|
||||
struct hostent *pHostent;
|
||||
struct sockaddr_in tsin;
|
||||
unsigned long addr;
|
||||
int osoc;
|
||||
BDT *bdt;
|
||||
|
||||
#ifndef vxWorks
|
||||
/* Deal with the name -vs- IP number issue. */
|
||||
if (isdigit(address[0]))
|
||||
#endif
|
||||
addr=inet_addr(address);
|
||||
#ifndef vxWorks
|
||||
else
|
||||
{
|
||||
if ((pHostent = gethostbyname (address)) == NULL)
|
||||
return(NULL);
|
||||
bcopy (pHostent->h_addr, (char *) &addr, sizeof(addr));
|
||||
printf("Converting name >%s< to IP number %08.8X\n", address, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
tsin.sin_port=0;
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
|
||||
{
|
||||
perror("BdtIpOpen: create socket failed");
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BdtIpOpen: local address bind failed");
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
tsin.sin_port=htons(Port);
|
||||
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
|
||||
|
||||
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
|
||||
{
|
||||
perror("BdtIpOpen: connect failed");
|
||||
close(osoc);
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
bdt=(BDT*)malloc(sizeof(BDT));
|
||||
bdt->soc=osoc;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BdtUnbound;
|
||||
|
||||
#ifndef vxWorks
|
||||
{
|
||||
int j;
|
||||
j = fcntl(bdt->soc, F_GETFL, 0);
|
||||
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
|
||||
}
|
||||
#endif
|
||||
/* now connected to the bulk data socket on the IOC */
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* write size bytes from buffer to socket */
|
||||
/* -------------------------------------- */
|
||||
int BdtWrite(int soc,void* buffer,int size)
|
||||
{
|
||||
int rc;
|
||||
int total;
|
||||
unsigned char* data;
|
||||
fd_set fds;
|
||||
struct timeval to;
|
||||
|
||||
data=(unsigned char*)buffer;
|
||||
total=size;
|
||||
|
||||
to.tv_sec = 5;
|
||||
to.tv_usec = 0;
|
||||
|
||||
do
|
||||
{
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc, &fds);
|
||||
if (select(soc+1, NULL, &fds, NULL, &to) != 1)
|
||||
{
|
||||
printf("BdtWrite: timeout waiting to write data\n");
|
||||
return(-1);
|
||||
}
|
||||
/* send block of data */
|
||||
if((rc=send(soc,&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno == EINTR)
|
||||
rc = 0;
|
||||
else
|
||||
perror("BdtWrite: Send to remote failed");
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* send a message header down a BDT socket */
|
||||
/* --------------------------------------- */
|
||||
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
|
||||
{
|
||||
BdtMsgHead buf;
|
||||
|
||||
if(bdt->state!=BdtIdle)
|
||||
{
|
||||
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
|
||||
bdt->state=BdtBad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf.verb=htons(verb);
|
||||
buf.size=htonl((unsigned long)size);
|
||||
|
||||
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't wait for response if data must go out */
|
||||
if(size)
|
||||
{
|
||||
bdt->remaining_send=size;
|
||||
bdt->state=BdtSData;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------- */
|
||||
/* send a message data chunk down a BDT socket */
|
||||
/* ------------------------------------------- */
|
||||
int BdtSendData(BDT* bdt,void* buffer,int size)
|
||||
{
|
||||
int len;
|
||||
int remaining;
|
||||
int rc;
|
||||
|
||||
if(bdt->state!=BdtSData)
|
||||
{
|
||||
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
|
||||
bdt->state=BdtBad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
remaining=bdt->remaining_send-size;
|
||||
|
||||
if(remaining<0)
|
||||
{
|
||||
fprintf(stderr,"WARNING -- BdtSendData: To much data to send\n");
|
||||
len=bdt->remaining_send;
|
||||
}
|
||||
else
|
||||
len=size;
|
||||
|
||||
if (BdtWrite(bdt->soc, buffer, len) < 0)
|
||||
return -1;
|
||||
|
||||
bdt->remaining_send-=len;
|
||||
|
||||
if(bdt->remaining_send<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendData: To much data Sent\n");
|
||||
bdt->remaining_send=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_send==0)
|
||||
bdt->state=BdtIdle;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int BdtFlushOutput(BDT* bdt)
|
||||
{
|
||||
#ifdef vxWorks
|
||||
ioctl(bdt->soc, FIOWFLUSH, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* Read exactly size bytes from remote */
|
||||
/* ------------------------------------- */
|
||||
int BdtRead(int soc,void* buffer,int size)
|
||||
{
|
||||
int rc,total;
|
||||
unsigned char* data;
|
||||
fd_set fds;
|
||||
struct timeval to;
|
||||
|
||||
to.tv_sec = 5;
|
||||
to.tv_usec = 0;
|
||||
|
||||
data=(unsigned char*)buffer;
|
||||
total=size;
|
||||
|
||||
do
|
||||
{
|
||||
#if 1
|
||||
/* wait for data chunk */
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc, &fds);
|
||||
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
|
||||
{
|
||||
printf("BdtRead: timeout waiting for data\n");
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
if((rc=recv(soc,&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno==EINTR)
|
||||
{
|
||||
printf("BdtRead: EINTR");
|
||||
rc=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("BdtRead: Receive data chunk failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* wait for a message header from remote */
|
||||
/* ------------------------------------- */
|
||||
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
|
||||
{
|
||||
BdtMsgHead buf;
|
||||
|
||||
/* can only receive header when in the idle state */
|
||||
if (bdt->state == BdtEof)
|
||||
return -1;
|
||||
|
||||
if(bdt->state != BdtIdle)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
|
||||
bdt->state=BdtBad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy message data to user */
|
||||
*verb=ntohs(buf.verb);
|
||||
*size=ntohl(buf.size);
|
||||
|
||||
if(*size)
|
||||
bdt->state=BdtRData;
|
||||
|
||||
bdt->remaining_recv=*size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Wait for a chunk of data from remote.
|
||||
User can continually call this with a maximum size until it return 0.
|
||||
------------------------------------------------------------------------ */
|
||||
int BdtReceiveData(BDT* bdt,void* buffer,int size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* can only receive data when in the receive data state */
|
||||
switch(bdt->state)
|
||||
{
|
||||
case BdtRData: break;
|
||||
case BdtIdle: return 0;
|
||||
default:
|
||||
fprintf(stderr,"BdtReceiveData: bad receive state\n");
|
||||
bdt->state=BdtBad;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bdt->remaining_recv < size)
|
||||
size = bdt->remaining_recv;
|
||||
|
||||
if(BdtRead(bdt->soc,buffer,size)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveData: Read failed\n");
|
||||
bdt->state = BdtEof;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bdt->remaining_recv-=size;
|
||||
|
||||
if(bdt->remaining_recv<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveData: To much data received\n");
|
||||
bdt->remaining_recv=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_recv==0)
|
||||
bdt->state=BdtIdle;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* connect to a process variable, useful if raw open used */
|
||||
/* ------------------------------------------------------ */
|
||||
int BdtServiceConnect(BDT* bdt, char* Name, char *Args)
|
||||
{
|
||||
int len;
|
||||
int rc;
|
||||
int size;
|
||||
int verb;
|
||||
unsigned char NameLen;
|
||||
unsigned char ArgLen;
|
||||
|
||||
if(bdt->state!=BdtUnbound)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
|
||||
return -1;
|
||||
}
|
||||
bdt->state=BdtIdle;
|
||||
NameLen = strlen(Name)+1;
|
||||
if (Args != NULL)
|
||||
ArgLen = strlen(Args)+1;
|
||||
else
|
||||
ArgLen = 0;
|
||||
|
||||
/* send out connect message */
|
||||
if(BdtSendHeader(bdt, BDT_Connect, NameLen+ArgLen) < 0)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
|
||||
NameLen--;
|
||||
ArgLen--;
|
||||
/* send out the process variable to connect to */
|
||||
if((BdtSendData(bdt, &NameLen, 1) < 0) || (BdtSendData(bdt, Name, NameLen) < 0))
|
||||
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
if (ArgLen > 0)
|
||||
{
|
||||
if ((BdtSendData(bdt, &ArgLen, 1) < 0) || (BdtSendData(bdt, Args, ArgLen) < 0))
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
rc=0;
|
||||
|
||||
/* wait for response from connect to process variable */
|
||||
if(BdtReceiveHeader(bdt,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check response */
|
||||
switch(verb)
|
||||
{
|
||||
case BDT_Ok:
|
||||
rc=0;
|
||||
break;
|
||||
case BDT_Error:
|
||||
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
|
||||
bdt->state=BdtUnbound;
|
||||
rc=-1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
|
||||
bdt->state=BdtUnbound;
|
||||
rc=-1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------- */
|
||||
/* close the connection */
|
||||
/* -------------------- */
|
||||
int BdtClose(BDT* bdt)
|
||||
{
|
||||
int verb,size,done;
|
||||
|
||||
/* send a close message out */
|
||||
if(BdtSendHeader(bdt,BDT_Close,0)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtClose: Cannot send close message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
done=0;
|
||||
|
||||
do
|
||||
{
|
||||
/* check response */
|
||||
if(BdtReceiveHeader(bdt,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtClose: Close message response error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case BDT_Ok:
|
||||
done=1;
|
||||
break;
|
||||
case BDT_Error:
|
||||
fprintf(stderr,"BdtClose: Close rejected\n");
|
||||
return -1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
while(done==0);
|
||||
|
||||
bdt->state=BdtUnbound;
|
||||
free(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for UDP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BdtOpenListenerUDP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
tsin.sin_port=htons(Port);
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
|
||||
{
|
||||
perror("BdtOpenListenerUDP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BdtOpenListenerUDP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for TCP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BdtOpenListenerTCP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
memset (&tsin, 0, sizeof(struct sockaddr_in));
|
||||
tsin.sin_port=htons(Port);
|
||||
tsin.sin_family=htons(AF_INET);
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
|
||||
{
|
||||
perror("BdtOpenListenerTCP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BdtOpenListenerTCP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen(nsoc,5);
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* make BDT from a socket - simple */
|
||||
/* ------------------------------- */
|
||||
BDT* BdtMakeBDT(int soc)
|
||||
{
|
||||
BDT* bdt;
|
||||
bdt=(BDT*)malloc(sizeof(BDT));
|
||||
bdt->soc=soc;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BdtIdle;
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* --------------------------- */
|
||||
/* free a BDT and close socket */
|
||||
/* --------------------------- */
|
||||
int BdtFreeBDT(BDT* bdt)
|
||||
{
|
||||
close(bdt->soc);
|
||||
free(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BdtPvPutArray(BDT *bdt, short DbrType, void *Buf, unsigned long NumElements,
|
||||
unsigned long ElementSize)
|
||||
{
|
||||
int Verb;
|
||||
int Size;
|
||||
unsigned long BufSize;
|
||||
|
||||
BufSize = NumElements * ElementSize;
|
||||
if (BdtSendHeader(bdt, BDT_Put, 6 + BufSize) != 0)
|
||||
return(-1);
|
||||
if (BdtSendData(bdt, &DbrType, 2) < 0)
|
||||
return(-1);
|
||||
if (BdtSendData(bdt, &NumElements, 4) < 0)
|
||||
return(-1);
|
||||
if (BdtSendData(bdt, Buf, BufSize) < 0)
|
||||
return(-1);
|
||||
if (BdtReceiveHeader(bdt, &Verb, &Size) != 0)
|
||||
return(-1);
|
||||
if (Verb != BDT_Ok)
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
392
src/bdt/bdtServ.c
Normal file
392
src/bdt/bdtServ.c
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
*
|
||||
* Author: John Winans
|
||||
* Date: 95-05-22
|
||||
*
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* IOC listener task blocks on accept calls waiting for binders.
|
||||
* If a bind arrives, a receiver task is spawned.
|
||||
*
|
||||
* IOC receiver task blocks on read calls waiting for transactions.
|
||||
* When a transaction arrives it is serviced.
|
||||
* At the end of a transaction service, a response is sent back.
|
||||
* After the response is sent, a chack is made to see if a delta transmission
|
||||
* was blocked by the transaction's use of the socket... if so, it is sent.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <selectLib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <vxWorks.h>
|
||||
#include <sys/socket.h>
|
||||
#include <in.h>
|
||||
#include <inetLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <sysSymTbl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bdt.h"
|
||||
|
||||
#define BDT_TASK_PRIO 200
|
||||
#define BDT_TASK_OPTIONS VX_FP_TASK
|
||||
#define BDT_TASK_STACK 5000
|
||||
#define STATIC static
|
||||
|
||||
/* used for debugging */
|
||||
STATIC char *BdtNames[] = {
|
||||
"BDT_Ok",
|
||||
"BDT_Connect",
|
||||
"BDT_Error",
|
||||
"BDT_Get",
|
||||
"BDT_Put",
|
||||
"BDT_Close",
|
||||
"BDT_Monitor",
|
||||
"BDT_Value",
|
||||
"BDT_Delta",
|
||||
"BDT_Add",
|
||||
"BDT_Delete",
|
||||
"BDT_Ping"
|
||||
};
|
||||
|
||||
STATIC int HexDump(char *ReadBuffer, int rbytes);
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* A debugging routine that hex-dumps a message to the console.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void BDT_DumpMessage(BDT *Bdt)
|
||||
{
|
||||
char Buf[16*4];
|
||||
int RecvLen;
|
||||
|
||||
while(Bdt->remaining_recv)
|
||||
{
|
||||
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
|
||||
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
|
||||
return; /* Got EOF, (EOM handled by the while() */
|
||||
|
||||
HexDump(Buf, RecvLen);
|
||||
}
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Throw away a message.
|
||||
*
|
||||
****************************************************************************/
|
||||
void BDT_DiscardMessage(BDT *Bdt)
|
||||
{
|
||||
char Buf[16*4];
|
||||
int RecvLen;
|
||||
|
||||
while(Bdt->remaining_recv)
|
||||
{
|
||||
RecvLen = (Bdt->remaining_recv > sizeof(Buf)) ? sizeof(Buf): Bdt->remaining_recv;
|
||||
if (BdtReceiveData(Bdt, Buf, RecvLen) != RecvLen)
|
||||
return; /* Got EOF, (EOM handled by the while() */
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Process a single Connect message. And return a response.
|
||||
*
|
||||
******************************************************************************/
|
||||
STATIC int BDT_ProcessConnect(BDT *Bdt)
|
||||
{
|
||||
SYM_TYPE Type;
|
||||
unsigned char length;
|
||||
char Buf[50];
|
||||
char HandlerName[70];
|
||||
|
||||
if (Bdt->remaining_recv > sizeof(Buf))
|
||||
{
|
||||
printf("BDT_ProcessConnect Connect Message too long %d\n", Bdt->remaining_recv);
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
if (Bdt->remaining_recv < 2)
|
||||
{
|
||||
printf("BDT_ProcessConnect Connect Message w/missing service name\n");
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
BdtReceiveData(Bdt, &length, 1);
|
||||
if (length > sizeof(Buf))
|
||||
{
|
||||
printf("BDT_ProcessConnect Connect Message service name too long %d\n", length);
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
BdtReceiveData(Bdt, Buf, length);
|
||||
Buf[length] = '\0';
|
||||
|
||||
sprintf(HandlerName, "_BDT_ServiceHandler_%s", Buf);
|
||||
printf("BDT_ProcessConnect NAME service (%s)\n", HandlerName);
|
||||
|
||||
/*Bdt->pHandlers = (BdthandlerFunc *)(&BDT_NameServicehandlers);*/
|
||||
if (symFindByName(sysSymTbl, HandlerName, (char **)&(Bdt->pHandlers), &Type) != OK)
|
||||
{
|
||||
printf("BDT_ProcessConnect Connect to unknown service (%s)\n", Buf);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bdt->Name = (char *)malloc(strlen(Buf)+1);
|
||||
strcpy(Bdt->Name, Buf);
|
||||
if (Bdt->pHandlers[BDT_Connect] != NULL)
|
||||
return((*(Bdt->pHandlers[BDT_Connect]))(Bdt));
|
||||
else
|
||||
{
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Process a single message. And return a response.
|
||||
*
|
||||
******************************************************************************/
|
||||
STATIC int BDT_ProcMessage(BDT *Bdt, unsigned short Command)
|
||||
{
|
||||
int RecvLen;
|
||||
|
||||
if (Command > BDT_LAST_VERB)
|
||||
{
|
||||
printf("BDT: %s Invalid command %d, length = %d\n", Bdt->Name, Command, Bdt->remaining_recv);
|
||||
BDT_DumpMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (Bdt->pHandlers == NULL)
|
||||
{
|
||||
if (Command == BDT_Connect)
|
||||
BDT_ProcessConnect(Bdt);
|
||||
else
|
||||
{
|
||||
printf("BDT_ProcMessage: %s got %s before connect\n", Bdt->Name, BdtNames[Command]);
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
if (Bdt->pHandlers[Command] == NULL)
|
||||
{
|
||||
printf("BDT_ProcMessage: service %s got %s... invalid\n", Bdt->Name, BdtNames[Command]);
|
||||
}
|
||||
return((*(Bdt->pHandlers[Command]))(Bdt));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Wait on a socket read for a message. When one arrives, read the header,
|
||||
* decode it, and call the message handler routine to process and respond to it.
|
||||
*
|
||||
******************************************************************************/
|
||||
STATIC void BDT_ReceiverTask(int Sock)
|
||||
{
|
||||
int Verb;
|
||||
int Size;
|
||||
BDT Bdt;
|
||||
int MonitorLockTimeout = (BDT_PING_INTERVAL*sysClkRateGet())/2;
|
||||
static char *NoBdtName = "(No Name)";
|
||||
fd_set FdSet;
|
||||
struct timeval TimeVal;
|
||||
int PollStatus;
|
||||
int SocketState;
|
||||
|
||||
Bdt.soc = Sock;
|
||||
Bdt.pMonitor = NULL;
|
||||
Bdt.WriteLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
|
||||
Bdt.MonitorLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
|
||||
Bdt.state = BdtIdle;
|
||||
Bdt.pHandlers = NULL;
|
||||
Bdt.Name = NoBdtName;
|
||||
|
||||
printf("BDT_ReceiverTask(%d) started\n", Sock);
|
||||
|
||||
TimeVal.tv_sec = BDT_CONENCTION_TIMEOUT;
|
||||
TimeVal.tv_usec = 0;
|
||||
FD_ZERO(&FdSet);
|
||||
FD_SET(Bdt.soc, &FdSet);
|
||||
|
||||
SocketState = 0;
|
||||
while (((PollStatus = select(FD_SETSIZE, &FdSet, NULL, NULL, &TimeVal)) > 0) && (BdtReceiveHeader(&Bdt, &Verb, &Size) == 0))
|
||||
{
|
||||
semTake(Bdt.WriteLock, WAIT_FOREVER);
|
||||
|
||||
SocketState = BDT_ProcMessage(&Bdt, Verb);
|
||||
|
||||
if (SocketState != 0)
|
||||
break;
|
||||
|
||||
#if 0
|
||||
if (semTake(Bdt.MonitorLock, MonitorLockTimeout) == OK)
|
||||
{
|
||||
/* Check for delta flag and send if so */
|
||||
|
||||
/* Change this to run thru a delta-message linked list */
|
||||
if (Bdt.pMonitor != NULL)
|
||||
{
|
||||
/* Send delta notifier */
|
||||
}
|
||||
semGive(Bdt.WriteLock); /* Order important for BDT_SendDelta */
|
||||
semGive(Bdt.MonitorLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("BDT_ReceiverTask timeout on monitor semaphore. Monitors are stuck!\n");
|
||||
semGive(Bdt.WriteLock);
|
||||
}
|
||||
#else
|
||||
semGive(Bdt.WriteLock);
|
||||
#endif
|
||||
BdtFlushOutput(&Bdt);
|
||||
|
||||
FD_ZERO(&FdSet);
|
||||
FD_SET(Bdt.soc, &FdSet);
|
||||
}
|
||||
if (SocketState == 0)
|
||||
{
|
||||
if (PollStatus == 0)
|
||||
printf("BDT_ReceiverTask(%d) exiting on client timeout\n", Sock);
|
||||
else
|
||||
printf("BDT_ReceiverTask(%d) exiting on I/O error talking to Client\n", Sock);
|
||||
}
|
||||
else
|
||||
printf("BDT_ReceiverTask(%d) received close from client\n", Sock);
|
||||
|
||||
/* Free up resources */
|
||||
if (Bdt.Name != NoBdtName)
|
||||
free(Bdt.Name);
|
||||
|
||||
close(Sock);
|
||||
semDelete(Bdt.WriteLock);
|
||||
semDelete(Bdt.MonitorLock);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
#if 0
|
||||
int BDT_SendDelta(int Socket, char *Message)
|
||||
{
|
||||
semTake (DeltaFlagLock, WAIT_FOREVER);
|
||||
if (if (semTake(SocketWriteLock, no wait) == failed)
|
||||
{
|
||||
/* Reader task is busy... Post message for future transmission */
|
||||
Bdt.pending_delta = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
write(Message); /* This COULD block */
|
||||
semGive(SocketWriteLock);
|
||||
}
|
||||
semGive(DeltaFlagLock);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This task listens on a port for new connections. When one is made, it
|
||||
* spawns a task to manage it.
|
||||
*
|
||||
******************************************************************************/
|
||||
void BDT_ListenerTask(int Port)
|
||||
{
|
||||
/* Open a socket to listen on */
|
||||
struct sockaddr_in ListenerAddr;
|
||||
struct sockaddr_in ClientAddr;
|
||||
int ListenerSock;
|
||||
int ClientSock;
|
||||
int ClientAddrLen;
|
||||
int SockAddrSize = sizeof(struct sockaddr_in);
|
||||
|
||||
if (Port == 0)
|
||||
Port = BDT_TCP_PORT;
|
||||
|
||||
printf("BDT_Listener(%d) started\n", Port);
|
||||
|
||||
if ((ListenerSock = BdtOpenListenerTCP(Port)) < 0)
|
||||
{
|
||||
printf("BDT_ListenerTask(%d) can't start listener\n", Port);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
ClientAddrLen = sizeof(ClientAddr);
|
||||
if((ClientSock = accept(ListenerSock, (struct sockaddr*)&ClientAddr, &ClientAddrLen)) < 0)
|
||||
{
|
||||
if(errno!=EINTR)
|
||||
{
|
||||
printf("BDT_ListenerTask(%d) accept() failed\n", Port);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Spawn a task to handle the new connection */
|
||||
printf("Accepted a connection\n");
|
||||
taskSpawn("BDT", BDT_TASK_PRIO, BDT_TASK_OPTIONS, BDT_TASK_STACK, (FUNCPTR)BDT_ReceiverTask, ClientSock, 2,3,4,5,6,7,8,9,0);
|
||||
}
|
||||
}
|
||||
/* Never reached */
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* A handy routine to assist in debugging.
|
||||
*
|
||||
******************************************************************************/
|
||||
STATIC int HexDump(char *ReadBuffer, int rbytes)
|
||||
{
|
||||
int c = 0;
|
||||
int i = 0;
|
||||
int firsttime;
|
||||
char ascii[20]; /* To hold printable portion of string */
|
||||
|
||||
if (!rbytes)
|
||||
return(0);
|
||||
|
||||
firsttime = 1;
|
||||
while(c < rbytes)
|
||||
{
|
||||
if ((c % 16) == 0)
|
||||
{
|
||||
if (!firsttime)
|
||||
{
|
||||
ascii[i] = '\0';
|
||||
printf(" *%s*\n", ascii);
|
||||
}
|
||||
firsttime=0;
|
||||
i = 0;
|
||||
}
|
||||
printf(" %02.2X", ReadBuffer[c] & 0xff);
|
||||
ascii[i] = ReadBuffer[c];
|
||||
if (!isprint(ascii[i]))
|
||||
ascii[i] = '.';
|
||||
++i;
|
||||
++c;
|
||||
}
|
||||
while (c%16)
|
||||
{
|
||||
fputs(" ", stdout);
|
||||
++c;
|
||||
}
|
||||
ascii[i] = '\0';
|
||||
printf(" *%s*\n", ascii);
|
||||
return(0);
|
||||
}
|
||||
129
src/bdt/bdtServName.c
Normal file
129
src/bdt/bdtServName.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Author: John Winans
|
||||
* Date: 95-06-05
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* $Log$
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <selectLib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* IOC listener task blocks on accept calls waiting for binders.
|
||||
* If a bind arrives, a receiver task is spawned.
|
||||
*
|
||||
* IOC receiver task blocks on read calls waiting for transactions.
|
||||
* When a transaction arrives it is serviced.
|
||||
* At the end of a transaction service, a response is sent back.
|
||||
* After the response is sent, a chack is made to see if a delta transmission
|
||||
* was blocked by the transaction's use of the socket... if so, it is sent.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <sys/socket.h>
|
||||
#include <in.h>
|
||||
#include <inetLib.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include "bdt.h"
|
||||
|
||||
#define STATIC static
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_NameServiceOk(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceOk \n");
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_NameServiceConnect(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceConnect \n");
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceError(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceError \n");
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceGet(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceGet \n");
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServicePut(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServicePut \n");
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceClose(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceClose \n");
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceMonitor(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceMonitor \n");
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceValue(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceValue \n");
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceDelta(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceDelta \n");
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceAdd(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceAdd \n");
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServiceDelete(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServiceDelete \n");
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
STATIC int BDT_NameServicePing(BDT *Bdt)
|
||||
{
|
||||
printf("BDT_NameServicePing \n");
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
BdtHandlers BDT_ServiceHandler_name =
|
||||
{
|
||||
BDT_NameServiceOk,
|
||||
BDT_NameServiceConnect,
|
||||
BDT_NameServiceError,
|
||||
BDT_NameServiceGet,
|
||||
BDT_NameServicePut,
|
||||
BDT_NameServiceClose,
|
||||
BDT_NameServiceMonitor,
|
||||
BDT_NameServiceValue,
|
||||
BDT_NameServiceDelta,
|
||||
BDT_NameServiceAdd,
|
||||
BDT_NameServiceDelete,
|
||||
BDT_NameServicePing
|
||||
};
|
||||
377
src/bdt/bdtServPv.c
Normal file
377
src/bdt/bdtServPv.c
Normal file
@@ -0,0 +1,377 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Author: John Winans
|
||||
* Date: 95-06-05
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* $Log$
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dbCommon.h>
|
||||
#include <dbAccess.h>
|
||||
|
||||
#include "bdt.h"
|
||||
|
||||
#define STATIC static
|
||||
#define MESSAGE_PREFIX "BDT PV server:"
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* These conversion finctions take care of one of the most insane parts
|
||||
* of dealing with database access... having two different interfaces that
|
||||
* have the same named enumerators in two seperate header files... that
|
||||
* therefore can not be both included in the same file.
|
||||
*
|
||||
* This is so bad, I wanted to vomit when typing it in.
|
||||
*
|
||||
******************************************************************************/
|
||||
STATIC int DbrOld2New(int Old)
|
||||
{
|
||||
switch (Old)
|
||||
{
|
||||
case 0: return(DBR_STRING);
|
||||
case 1: return(DBR_SHORT);
|
||||
case 2: return(DBR_FLOAT);
|
||||
case 3: return(DBR_ENUM);
|
||||
case 4: return(DBR_CHAR);
|
||||
case 5: return(DBR_LONG);
|
||||
case 6: return(DBR_DOUBLE);
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int DbrNew2Old(int New)
|
||||
{
|
||||
switch (New)
|
||||
{
|
||||
case DBR_STRING: return(0);
|
||||
case DBR_CHAR: return(4);
|
||||
case DBR_UCHAR: return(4);
|
||||
case DBR_SHORT: return(1);
|
||||
case DBR_USHORT: return(1);
|
||||
case DBR_LONG: return(5);
|
||||
case DBR_ULONG: return(5);
|
||||
case DBR_FLOAT: return(2);
|
||||
case DBR_DOUBLE: return(6);
|
||||
case DBR_ENUM: return(3);
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of an OK message.
|
||||
*
|
||||
* The OK message is received as a confirmation of the last operation. It is
|
||||
* not normally responded to.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceOk(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Ok message\n", MESSAGE_PREFIX);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Connect message.
|
||||
*
|
||||
* The Connect is received when a new connection is first made.
|
||||
* Any arguments left in the message body have not yet been read.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceConnect(BDT *Bdt)
|
||||
{
|
||||
unsigned char Length;
|
||||
char Buf[100];
|
||||
struct dbAddr *pDbAddr;
|
||||
|
||||
Buf[0] = '\0';
|
||||
if (Bdt->remaining_recv > 0)
|
||||
{
|
||||
BdtReceiveData(Bdt, &Length, 1);
|
||||
if (Length <= sizeof(Buf))
|
||||
{
|
||||
BdtReceiveData(Bdt, Buf, Length);
|
||||
Buf[Length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s Connect message argument list too long\n", MESSAGE_PREFIX);
|
||||
BDT_DiscardMessage(Bdt);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("%s got Connect >%s<\n", MESSAGE_PREFIX, Buf);
|
||||
#endif
|
||||
/* Find the PV in the database */
|
||||
Bdt->pService = malloc(sizeof(struct dbAddr));
|
||||
pDbAddr = (struct dbAddr *)(Bdt->pService);
|
||||
if (dbNameToAddr(Buf, pDbAddr))
|
||||
{
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
free(Bdt->pService);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pDbAddr->dbr_field_type != pDbAddr->field_type)
|
||||
{
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
free(Bdt->pService);
|
||||
}
|
||||
else
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of an Error message.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceError(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Error message\n", MESSAGE_PREFIX);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Get message.
|
||||
*
|
||||
* The response to a Get message is either an Error or a Value:
|
||||
*
|
||||
* Value message body format:
|
||||
* SHORT EPICS data type enumerator (in old format)
|
||||
* LONG Number of elements
|
||||
* CHAR[] Value image
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceGet(BDT *Bdt)
|
||||
{
|
||||
void *Buf;
|
||||
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
|
||||
long NumElements;
|
||||
long Size;
|
||||
long l;
|
||||
short OldType;
|
||||
int stat;
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("%s got a Get message\n", MESSAGE_PREFIX);
|
||||
|
||||
printf("field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
|
||||
#endif
|
||||
|
||||
OldType = DbrNew2Old(pDbAddr->field_type);
|
||||
if (OldType < 0)
|
||||
{
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
/* Allocate a buffer to hold the response message data */
|
||||
Buf = malloc(pDbAddr->field_size * pDbAddr->no_elements);
|
||||
if (Buf == NULL)
|
||||
{
|
||||
printf("Can't allocate %d-byte buffer for get request to %s\n",
|
||||
pDbAddr->field_size * pDbAddr->no_elements,
|
||||
pDbAddr->precord->name);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
/* Get the response message data */
|
||||
NumElements = pDbAddr->no_elements;
|
||||
if (stat=dbGetField(pDbAddr, pDbAddr->field_type, Buf, 0, &NumElements, NULL))
|
||||
{
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
#if 0
|
||||
/* Test hack to transfer HUGE buffers */
|
||||
NumElements = pDbAddr->no_elements;
|
||||
#endif
|
||||
/* Send the response message */
|
||||
Size = NumElements * pDbAddr->field_size;
|
||||
BdtSendHeader(Bdt, BDT_Value, Size + sizeof(long) + sizeof(short));
|
||||
BdtSendData(Bdt, &OldType, sizeof(short));
|
||||
BdtSendData(Bdt, &NumElements, sizeof(long));
|
||||
if (Size)
|
||||
BdtSendData(Bdt, Buf, Size);
|
||||
free(Buf);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Put message.
|
||||
*
|
||||
* Put message body format:
|
||||
* SHORT EPICS data type enumerator
|
||||
* LONG Number of elements
|
||||
* CHAR[] Value image
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServicePut(BDT *Bdt)
|
||||
{
|
||||
long Size;
|
||||
void *Buf;
|
||||
short DbrType;
|
||||
long NumElements;
|
||||
struct dbAddr *pDbAddr = (struct dbAddr *)(Bdt->pService);
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("%s got a Put message\n", MESSAGE_PREFIX);
|
||||
#endif
|
||||
if (BdtGetResidualRead(Bdt) < 6)
|
||||
{
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
if (BdtGetResidualRead(Bdt) == 6)
|
||||
{ /* Do data contents, just toss it */
|
||||
BDT_DiscardMessage(Bdt);
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(0);
|
||||
}
|
||||
Buf = malloc(BdtGetResidualRead(Bdt) - 6);
|
||||
if (Buf == NULL)
|
||||
{
|
||||
printf("Can't allocate %d-byte buffer for put request to %s\n",
|
||||
BdtGetResidualRead(Bdt), pDbAddr->precord->name);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
BdtReceiveData(Bdt, &DbrType, 2);
|
||||
BdtReceiveData(Bdt, &NumElements, 4);
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("record field type=%d, field size=%d, elements=%d\n", pDbAddr->field_type, pDbAddr->field_size, pDbAddr->no_elements);
|
||||
printf("message field type=%d, field size=%d, elements=%d total %d\n", DbrType, pDbAddr->field_type ,NumElements, BdtGetResidualRead(Bdt));
|
||||
#endif
|
||||
|
||||
BdtReceiveData(Bdt, Buf, BdtGetResidualRead(Bdt));
|
||||
DbrType = DbrOld2New(DbrType);
|
||||
|
||||
if (DbrType < 0)
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
else if (dbPutField(pDbAddr, DbrType, Buf, NumElements))
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
else
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
|
||||
free(Buf);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Close message.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceClose(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Close message\n", MESSAGE_PREFIX);
|
||||
free(Bdt->pService);
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(1);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Monitor message.
|
||||
*
|
||||
* Not Supported.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceMonitor(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Monitor message\n", MESSAGE_PREFIX);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Value message.
|
||||
*
|
||||
* Not Supported.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceValue(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Value message\n", MESSAGE_PREFIX);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Delta message.
|
||||
*
|
||||
* Not Supported.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceDelta(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Delta message\n", MESSAGE_PREFIX);
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of an Add message.
|
||||
*
|
||||
* Not Supported.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceAdd(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Add message\n", MESSAGE_PREFIX);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Delete message.
|
||||
*
|
||||
* Not Supported.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServiceDelete(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Delete message\n", MESSAGE_PREFIX);
|
||||
BdtSendHeader(Bdt, BDT_Error, 0);
|
||||
return(0);
|
||||
}
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Handle the receipt of a Ping message.
|
||||
*
|
||||
*****************************************************************************/
|
||||
STATIC int BDT_ServicePing(BDT *Bdt)
|
||||
{
|
||||
printf("%s got a Ping message\n", MESSAGE_PREFIX);
|
||||
BdtSendHeader(Bdt, BDT_Ok, 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
BdtHandlers BDT_ServiceHandler_pv =
|
||||
{
|
||||
BDT_ServiceOk,
|
||||
BDT_ServiceConnect,
|
||||
BDT_ServiceError,
|
||||
BDT_ServiceGet,
|
||||
BDT_ServicePut,
|
||||
BDT_ServiceClose,
|
||||
BDT_ServiceMonitor,
|
||||
BDT_ServiceValue,
|
||||
BDT_ServiceDelta,
|
||||
BDT_ServiceAdd,
|
||||
BDT_ServiceDelete,
|
||||
BDT_ServicePing
|
||||
};
|
||||
@@ -5,11 +5,10 @@ $!
|
||||
$! Purpose : To build the CHANNEL_ACCESS library and test programs for
|
||||
$! VAX/VMS. This procedure assumes the following:
|
||||
$! - You have copied *.c and *.h from the Epics channel access
|
||||
$! source directory (.../src/ca) into this VMS directory
|
||||
$! - You have copied envSubr.c, ellLib.c, and bucketLib.c
|
||||
$! from the Epics
|
||||
$! source directory (base/src/ca) into this VMS directory
|
||||
$! - You have copied *.c and *.h from the Epics
|
||||
$! libCom directory into this VMS directory
|
||||
$! - You have copied *.h from the /src/epicsH directory into this
|
||||
$! - You have copied *.h from the base/include directory into this
|
||||
$! VMS directory
|
||||
$! - You are using Multinet for TCP/IP access. If not, the logical
|
||||
$! name definitions below will need to be changed
|
||||
|
||||
@@ -34,13 +34,7 @@ include $(EPICS)/config/RULES.Unix
|
||||
acctst: acctst.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
|
||||
acctst.o: ../acctst.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
catime: catime.o $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
$(LINK.c) -o $@ $< $(LIBOBJS) $(DEPLIBS_BASE)/libCom.a
|
||||
|
||||
catime.o: ../catime.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
|
||||
|
||||
@@ -8,21 +8,11 @@ SRCS.c = \
|
||||
../if_depen.c ../bsd_depen.c ../vxWorks_depen.c ../acctst.c \
|
||||
../catime.c
|
||||
|
||||
OBJS = \
|
||||
LIBOBJS = \
|
||||
iocinf.o access.o test_event.o service.o flow_control.o \
|
||||
repeater.o conn.o syncgrp.o if_depen.o bsd_depen.o vxWorks_depen.o
|
||||
|
||||
PROD = caLib
|
||||
LIBNAME = caLib
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
caLib: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
acctst.o: ../acctst.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
catime.o: ../catime.c
|
||||
$(COMPILE.c) $<
|
||||
|
||||
|
||||
254
src/ca/access.c
254
src/ca/access.c
@@ -92,7 +92,24 @@
|
||||
/* 011394 joh fixed bucketLib level memory leak (vxWorks) */
|
||||
/* 020494 joh Added user name protocol */
|
||||
/* 022294 joh fixed recv task id verify at exit (vxWorks) */
|
||||
/* */
|
||||
/* 072895 joh fixed problem resulting from unsigned long */
|
||||
/* tv_sec var in struct timeval in sys/time.h */
|
||||
/* under HPUX */
|
||||
/************************************************************************/
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.74 1995/08/22 00:12:07 jhill
|
||||
* *** empty log message ***
|
||||
*
|
||||
* Revision 1.73 1995/08/14 19:26:10 jhill
|
||||
* epicsAPI => epicsShareAPI
|
||||
*
|
||||
* Revision 1.72 1995/08/12 00:23:32 jhill
|
||||
* check for res id in use, epicsEntry, dont wait for itsy bitsy delay
|
||||
* in ca_pend_event(), better clean up when monitor is deleted and
|
||||
* we are disconnected
|
||||
*
|
||||
*/
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
@@ -443,7 +460,7 @@ LOCAL void cac_add_msg (IIU *piiu)
|
||||
/*
|
||||
* CA_TASK_INITIALIZE
|
||||
*/
|
||||
int APIENTRY ca_task_initialize(void)
|
||||
int epicsShareAPI ca_task_initialize(void)
|
||||
{
|
||||
int status;
|
||||
struct ca_static *ca_temp;
|
||||
@@ -566,6 +583,7 @@ LOCAL void create_udp_fd()
|
||||
status = create_net_chan(
|
||||
&ca_static->ca_piiuCast,
|
||||
NULL,
|
||||
ca_static->ca_server_port,
|
||||
IPPROTO_UDP);
|
||||
if (~status & CA_M_SUCCESS) {
|
||||
ca_static->ca_piiuCast = NULL;
|
||||
@@ -620,7 +638,7 @@ LOCAL void create_udp_fd()
|
||||
* Modify or override the default
|
||||
* client host name.
|
||||
*/
|
||||
int APIENTRY ca_modify_host_name(char *pHostName)
|
||||
int epicsShareAPI ca_modify_host_name(char *pHostName)
|
||||
{
|
||||
char *pTmp;
|
||||
unsigned size;
|
||||
@@ -675,7 +693,7 @@ int APIENTRY ca_modify_host_name(char *pHostName)
|
||||
* Modify or override the default
|
||||
* client user name.
|
||||
*/
|
||||
int APIENTRY ca_modify_user_name(char *pClientName)
|
||||
int epicsShareAPI ca_modify_user_name(char *pClientName)
|
||||
{
|
||||
char *pTmp;
|
||||
unsigned size;
|
||||
@@ -730,7 +748,7 @@ int APIENTRY ca_modify_user_name(char *pClientName)
|
||||
* call this routine if you wish to free resources prior to task
|
||||
* exit- ca_task_exit() is also executed routinely at task exit.
|
||||
*/
|
||||
int APIENTRY ca_task_exit (void)
|
||||
int epicsShareAPI ca_task_exit (void)
|
||||
{
|
||||
/*
|
||||
* This indirectly calls ca_process_exit() below
|
||||
@@ -858,10 +876,10 @@ void ca_process_exit()
|
||||
/*
|
||||
* free hash tables
|
||||
*/
|
||||
status = bucketFree(ca_static->ca_pSlowBucket);
|
||||
assert(status == BUCKET_SUCCESS);
|
||||
status = bucketFree(ca_static->ca_pFastBucket);
|
||||
assert(status == BUCKET_SUCCESS);
|
||||
status = bucketFree (ca_static->ca_pSlowBucket);
|
||||
assert (status == S_bucket_success);
|
||||
status = bucketFree (ca_static->ca_pFastBucket);
|
||||
assert (status == S_bucket_success);
|
||||
|
||||
/*
|
||||
* free beacon hash table
|
||||
@@ -880,7 +898,7 @@ void ca_process_exit()
|
||||
*
|
||||
* backwards compatible entry point to ca_search_and_connect()
|
||||
*/
|
||||
int APIENTRY ca_build_and_connect
|
||||
int epicsShareAPI ca_build_and_connect
|
||||
(
|
||||
char *name_str,
|
||||
chtype get_type,
|
||||
@@ -905,7 +923,7 @@ int APIENTRY ca_build_and_connect
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_search_and_connect
|
||||
int epicsShareAPI ca_search_and_connect
|
||||
(
|
||||
char *name_str,
|
||||
chid *chixptr,
|
||||
@@ -1010,13 +1028,20 @@ int APIENTRY ca_search_and_connect
|
||||
}
|
||||
|
||||
LOCK;
|
||||
chix->cid = CLIENT_SLOW_ID_ALLOC;
|
||||
status = bucketAddItemUnsignedId(pSlowBucket, &chix->cid, chix);
|
||||
if(status != BUCKET_SUCCESS){
|
||||
do {
|
||||
chix->cid = CLIENT_SLOW_ID_ALLOC;
|
||||
status = bucketAddItemUnsignedId (pSlowBucket,
|
||||
&chix->cid, chix);
|
||||
} while (status == S_bucket_idInUse);
|
||||
|
||||
if (status != S_bucket_success) {
|
||||
*chixptr = (chid) NULL;
|
||||
free((char *) chix);
|
||||
UNLOCK;
|
||||
return ECA_ALLOCMEM;
|
||||
if (status == S_bucket_noMemory) {
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
return ECA_INTERNAL;
|
||||
}
|
||||
|
||||
chix->puser = puser;
|
||||
@@ -1127,7 +1152,7 @@ int reply_type
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_array_get
|
||||
int epicsShareAPI ca_array_get
|
||||
(
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -1195,8 +1220,10 @@ void *pvalue
|
||||
}
|
||||
else {
|
||||
LOCK;
|
||||
ellDelete (&pend_read_list, &monix->node);
|
||||
caIOBlockFree (monix);
|
||||
if (ca_state(chix)==cs_conn) {
|
||||
ellDelete (&pend_read_list, &monix->node);
|
||||
caIOBlockFree (monix);
|
||||
}
|
||||
UNLOCK;
|
||||
}
|
||||
}
|
||||
@@ -1212,7 +1239,7 @@ void *pvalue
|
||||
/*
|
||||
* CA_ARRAY_GET_CALLBACK()
|
||||
*/
|
||||
int APIENTRY ca_array_get_callback
|
||||
int epicsShareAPI ca_array_get_callback
|
||||
(
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -1273,8 +1300,10 @@ void *arg
|
||||
status = issue_get_callback (monix, IOC_READ_NOTIFY);
|
||||
if (status != ECA_NORMAL) {
|
||||
LOCK;
|
||||
ellDelete (&pend_read_list, &monix->node);
|
||||
caIOBlockFree (monix);
|
||||
if (ca_state(chix)==cs_conn) {
|
||||
ellDelete (&pend_read_list, &monix->node);
|
||||
caIOBlockFree (monix);
|
||||
}
|
||||
UNLOCK;
|
||||
}
|
||||
}
|
||||
@@ -1305,12 +1334,15 @@ LOCAL evid caIOBlockCreate(void)
|
||||
}
|
||||
|
||||
if (pIOBlock) {
|
||||
pIOBlock->id = CLIENT_FAST_ID_ALLOC;
|
||||
status = bucketAddItemUnsignedId(
|
||||
pFastBucket,
|
||||
&pIOBlock->id,
|
||||
pIOBlock);
|
||||
if(status != BUCKET_SUCCESS){
|
||||
do {
|
||||
pIOBlock->id = CLIENT_FAST_ID_ALLOC;
|
||||
status = bucketAddItemUnsignedId(
|
||||
pFastBucket,
|
||||
&pIOBlock->id,
|
||||
pIOBlock);
|
||||
} while (status == S_bucket_idInUse);
|
||||
|
||||
if(status != S_bucket_success){
|
||||
free(pIOBlock);
|
||||
pIOBlock = NULL;
|
||||
}
|
||||
@@ -1333,7 +1365,7 @@ void caIOBlockFree(evid pIOBlock)
|
||||
status = bucketRemoveItemUnsignedId(
|
||||
ca_static->ca_pFastBucket,
|
||||
&pIOBlock->id);
|
||||
assert (status == BUCKET_SUCCESS);
|
||||
assert (status == S_bucket_success);
|
||||
pIOBlock->id = ~0U; /* this id always invalid */
|
||||
ellAdd (&free_event_list, &pIOBlock->node);
|
||||
UNLOCK;
|
||||
@@ -1433,7 +1465,7 @@ LOCAL int issue_get_callback(evid monix, unsigned cmmd)
|
||||
* CA_ARRAY_PUT_CALLBACK()
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_array_put_callback
|
||||
int epicsShareAPI ca_array_put_callback
|
||||
(
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -1537,7 +1569,7 @@ void *usrarg
|
||||
}
|
||||
status = dbPutNotify(&ppn->dbPutNotify);
|
||||
UNLOCK;
|
||||
if(status){
|
||||
if(status && status != S_db_Pending){
|
||||
if(status==S_db_Blocked){
|
||||
return ECA_PUTCBINPROG;
|
||||
}
|
||||
@@ -1577,8 +1609,10 @@ void *usrarg
|
||||
pvalue);
|
||||
if(status != ECA_NORMAL){
|
||||
LOCK;
|
||||
ellDelete (&pend_write_list, &monix->node);
|
||||
caIOBlockFree(monix);
|
||||
if (ca_state(chix)==cs_conn) {
|
||||
ellDelete (&pend_write_list, &monix->node);
|
||||
caIOBlockFree(monix);
|
||||
}
|
||||
UNLOCK;
|
||||
return status;
|
||||
}
|
||||
@@ -1642,7 +1676,7 @@ LOCAL void ca_put_notify_action(PUTNOTIFY *ppn)
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_array_put (
|
||||
int epicsShareAPI ca_array_put (
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
chid chix,
|
||||
@@ -1883,7 +1917,7 @@ LOCAL void free_put_convert(void *pBuf)
|
||||
* Specify an event subroutine to be run for connection events
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_change_connection_event
|
||||
int epicsShareAPI ca_change_connection_event
|
||||
(
|
||||
chid chix,
|
||||
void (*pfunc)(struct connection_handler_args)
|
||||
@@ -1915,7 +1949,7 @@ void (*pfunc)(struct connection_handler_args)
|
||||
/*
|
||||
* ca_replace_access_rights_event
|
||||
*/
|
||||
int APIENTRY ca_replace_access_rights_event(
|
||||
int epicsShareAPI ca_replace_access_rights_event(
|
||||
chid chan,
|
||||
void (*pfunc)(struct access_rights_handler_args))
|
||||
{
|
||||
@@ -1943,7 +1977,7 @@ void (*pfunc)(struct access_rights_handler_args))
|
||||
* Specify an event subroutine to be run for asynch exceptions
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_add_exception_event
|
||||
int epicsShareAPI ca_add_exception_event
|
||||
(
|
||||
void (*pfunc)(struct exception_handler_args),
|
||||
void *arg
|
||||
@@ -1975,7 +2009,7 @@ void *arg
|
||||
* Undocumented entry for the VAX OPI which may vanish in the future.
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_add_io_event
|
||||
int epicsShareAPI ca_add_io_event
|
||||
(
|
||||
void (*ast)(),
|
||||
void *astarg
|
||||
@@ -2010,7 +2044,7 @@ void *astarg
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_add_masked_array_event
|
||||
int epicsShareAPI ca_add_masked_array_event
|
||||
(
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -2140,8 +2174,10 @@ long mask
|
||||
status = ca_request_event(monix);
|
||||
if (status != ECA_NORMAL) {
|
||||
LOCK;
|
||||
ellDelete (&chix->eventq, &monix->node);
|
||||
caIOBlockFree(monix);
|
||||
if (ca_state(chix)==cs_conn) {
|
||||
ellDelete (&chix->eventq, &monix->node);
|
||||
caIOBlockFree(monix);
|
||||
}
|
||||
UNLOCK
|
||||
}
|
||||
return status;
|
||||
@@ -2373,7 +2409,7 @@ void *pfl
|
||||
* after leaving this routine.
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_clear_event (evid monix)
|
||||
int epicsShareAPI ca_clear_event (evid monix)
|
||||
{
|
||||
int status;
|
||||
chid chix = monix->chan;
|
||||
@@ -2448,6 +2484,7 @@ int APIENTRY ca_clear_event (evid monix)
|
||||
else{
|
||||
LOCK;
|
||||
ellDelete(&monix->chan->eventq, &monix->node);
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
status = ECA_NORMAL;
|
||||
}
|
||||
@@ -2471,7 +2508,7 @@ int APIENTRY ca_clear_event (evid monix)
|
||||
* (from this source) after leaving this routine.
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_clear_channel (chid chix)
|
||||
int epicsShareAPI ca_clear_channel (chid chix)
|
||||
{
|
||||
int status;
|
||||
evid monix;
|
||||
@@ -2614,7 +2651,7 @@ void clearChannelResources(unsigned id)
|
||||
ellDelete (&piiu->chidlist, &chix->node);
|
||||
status = bucketRemoveItemUnsignedId (
|
||||
ca_static->ca_pSlowBucket, &chix->cid);
|
||||
assert (status == BUCKET_SUCCESS);
|
||||
assert (status == S_bucket_success);
|
||||
free (chix);
|
||||
if (piiu!=piiuCast && !piiu->chidlist.count){
|
||||
TAG_CONN_DOWN(piiu);
|
||||
@@ -2633,7 +2670,7 @@ void clearChannelResources(unsigned id)
|
||||
/* IO completes. */
|
||||
/* ca_flush_io() is called by this routine. */
|
||||
/************************************************************************/
|
||||
int APIENTRY ca_pend(ca_real timeout, int early)
|
||||
int epicsShareAPI ca_pend (ca_real timeout, int early)
|
||||
{
|
||||
struct timeval beg_time;
|
||||
ca_real delay;
|
||||
@@ -2648,13 +2685,12 @@ int APIENTRY ca_pend(ca_real timeout, int early)
|
||||
return ECA_EVDISALLOW;
|
||||
}
|
||||
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
|
||||
/*
|
||||
* Flush the send buffers
|
||||
* (guarantees that we wait for all send buffer to be
|
||||
* flushed even if this requires blocking)
|
||||
*
|
||||
* Also takes care of outstanding recvs
|
||||
* for single threaded clients
|
||||
*/
|
||||
ca_flush_io();
|
||||
|
||||
@@ -2662,10 +2698,6 @@ int APIENTRY ca_pend(ca_real timeout, int early)
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* the current time set iderectly within ca_flush_io()
|
||||
* above.
|
||||
*/
|
||||
beg_time = ca_static->currentTime;
|
||||
delay = 0.0;
|
||||
while(TRUE){
|
||||
@@ -2681,29 +2713,46 @@ int APIENTRY ca_pend(ca_real timeout, int early)
|
||||
}
|
||||
else{
|
||||
remaining = timeout-delay;
|
||||
if(remaining<=0.0){
|
||||
if(early){
|
||||
ca_pend_io_cleanup();
|
||||
}
|
||||
ca_flush_io();
|
||||
return ECA_TIMEOUT;
|
||||
}
|
||||
/*
|
||||
* Allow for CA background labor
|
||||
*/
|
||||
remaining = min(SELECT_POLL, remaining);
|
||||
}
|
||||
|
||||
tmo.tv_sec = (long) remaining;
|
||||
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
|
||||
cac_block_for_io_completion(&tmo);
|
||||
|
||||
/*
|
||||
* the current time set within cac_block_for_io_completion()
|
||||
* above.
|
||||
* If we are no longer waiting any significant
|
||||
* delay then return
|
||||
* (dont wait forever for an itsy bitsy
|
||||
* delay which will no be updated if
|
||||
* select is called with no delay)
|
||||
*
|
||||
* current time is only updated by
|
||||
* cac_select_io() if we specify
|
||||
* at least 1 usec to wait
|
||||
*
|
||||
*/
|
||||
if (remaining <= (1.0/USEC_PER_SEC)) {
|
||||
if(early){
|
||||
ca_pend_io_cleanup();
|
||||
ca_flush_io();
|
||||
}
|
||||
/*
|
||||
* be certain that we processed
|
||||
* recv backlog at least once
|
||||
*/
|
||||
tmo.tv_sec = 0L;
|
||||
tmo.tv_usec = 0L;
|
||||
cac_block_for_io_completion (&tmo);
|
||||
return ECA_TIMEOUT;
|
||||
}
|
||||
tmo.tv_sec = (long) remaining;
|
||||
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
|
||||
cac_block_for_io_completion (&tmo);
|
||||
|
||||
if (timeout != 0.0) {
|
||||
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
|
||||
delay = cac_time_diff (&ca_static->currentTime,
|
||||
&beg_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2714,20 +2763,31 @@ int APIENTRY ca_pend(ca_real timeout, int early)
|
||||
*/
|
||||
ca_real cac_time_diff (ca_time *pTVA, ca_time *pTVB)
|
||||
{
|
||||
ca_real delay;
|
||||
ca_real delay;
|
||||
ca_real udelay;
|
||||
|
||||
if(pTVA->tv_usec>pTVB->tv_usec){
|
||||
delay = pTVA->tv_sec - pTVB->tv_sec;
|
||||
delay += (pTVA->tv_usec - pTVB->tv_usec) /
|
||||
(ca_real)(USEC_PER_SEC);
|
||||
}
|
||||
else{
|
||||
delay = pTVA->tv_sec - pTVB->tv_sec - 1L;
|
||||
delay += (USEC_PER_SEC - pTVB->tv_usec + pTVA->tv_usec) /
|
||||
(ca_real)(USEC_PER_SEC);
|
||||
}
|
||||
/*
|
||||
* works with unsigned tv_sec in struct timeval
|
||||
* under HPUX
|
||||
*/
|
||||
if (pTVA->tv_sec>pTVB->tv_sec) {
|
||||
delay = pTVA->tv_sec - pTVB->tv_sec;
|
||||
}
|
||||
else {
|
||||
delay = pTVB->tv_sec - pTVA->tv_sec;
|
||||
delay = -delay;
|
||||
}
|
||||
|
||||
return delay;
|
||||
if(pTVA->tv_usec>pTVB->tv_usec){
|
||||
udelay = pTVA->tv_usec - pTVB->tv_usec;
|
||||
}
|
||||
else{
|
||||
delay -= 1.0;
|
||||
udelay = (USEC_PER_SEC - pTVB->tv_usec) + pTVA->tv_usec;
|
||||
}
|
||||
delay += udelay / USEC_PER_SEC;
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
|
||||
@@ -2791,28 +2851,19 @@ LOCAL void ca_pend_io_cleanup()
|
||||
/*
|
||||
* CA_FLUSH_IO()
|
||||
*
|
||||
* Flush the send buffer
|
||||
* flush the send buffer
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_flush_io()
|
||||
int epicsShareAPI ca_flush_io()
|
||||
{
|
||||
struct ioc_in_use *piiu;
|
||||
struct timeval timeout;
|
||||
int pending;
|
||||
unsigned long bytesPending;
|
||||
|
||||
INITCHK;
|
||||
|
||||
pending = TRUE;
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 0;
|
||||
while(pending){
|
||||
|
||||
/*
|
||||
* perform socket io
|
||||
* and process recv backlog
|
||||
*/
|
||||
cac_mux_io(&timeout);
|
||||
while (TRUE) {
|
||||
int pending;
|
||||
|
||||
/*
|
||||
* wait for all buffers to flush
|
||||
@@ -2837,7 +2888,16 @@ int APIENTRY ca_flush_io()
|
||||
}
|
||||
UNLOCK;
|
||||
|
||||
if (!pending) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* perform socket io
|
||||
* and process recv backlog
|
||||
*/
|
||||
LD_CA_TIME (SELECT_POLL, &timeout);
|
||||
cac_mux_io (&timeout);
|
||||
}
|
||||
|
||||
return ECA_NORMAL;
|
||||
@@ -2848,7 +2908,7 @@ int APIENTRY ca_flush_io()
|
||||
* CA_TEST_IO ()
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_test_io()
|
||||
int epicsShareAPI ca_test_io()
|
||||
{
|
||||
if(pndrecvcnt<1){
|
||||
return ECA_IODONE;
|
||||
@@ -2864,7 +2924,7 @@ int APIENTRY ca_test_io()
|
||||
*
|
||||
*
|
||||
*/
|
||||
void APIENTRY ca_signal(long ca_status,char *message)
|
||||
void epicsShareAPI ca_signal(long ca_status,char *message)
|
||||
{
|
||||
ca_signal_with_file_and_lineno(ca_status, message, NULL, 0);
|
||||
}
|
||||
@@ -2873,7 +2933,7 @@ void APIENTRY ca_signal(long ca_status,char *message)
|
||||
/*
|
||||
* ca_signal_with_file_and_lineno()
|
||||
*/
|
||||
void APIENTRY ca_signal_with_file_and_lineno(
|
||||
void epicsShareAPI ca_signal_with_file_and_lineno(
|
||||
long ca_status,
|
||||
char *message,
|
||||
char *pfilenm,
|
||||
@@ -3236,7 +3296,7 @@ LOCAL void ca_default_exception_handler(struct exception_handler_args args)
|
||||
* (for a manager of the select system call under UNIX)
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_add_fd_registration(CAFDHANDLER *func, void *arg)
|
||||
int epicsShareAPI ca_add_fd_registration(CAFDHANDLER *func, void *arg)
|
||||
{
|
||||
fd_register_func = func;
|
||||
fd_register_arg = arg;
|
||||
@@ -3267,7 +3327,7 @@ int ca_defunct()
|
||||
* currently implemented as a function
|
||||
* (may be implemented as a MACRO in the future)
|
||||
*/
|
||||
char * APIENTRY ca_host_name_function(chid chix)
|
||||
char * epicsShareAPI ca_host_name_function(chid chix)
|
||||
{
|
||||
IIU *piiu;
|
||||
|
||||
@@ -3283,7 +3343,7 @@ char * APIENTRY ca_host_name_function(chid chix)
|
||||
/*
|
||||
* ca_v42_ok(chid chan)
|
||||
*/
|
||||
int APIENTRY ca_v42_ok(chid chan)
|
||||
int epicsShareAPI ca_v42_ok(chid chan)
|
||||
{
|
||||
int v42;
|
||||
IIU *piiu;
|
||||
@@ -3360,10 +3420,12 @@ int ca_channel_status(int tid)
|
||||
/*
|
||||
* ca_replace_printf_handler ()
|
||||
*/
|
||||
int APIENTRY ca_replace_printf_handler (
|
||||
int epicsShareAPI ca_replace_printf_handler (
|
||||
int (*ca_printf_func)(const char *pformat, va_list args)
|
||||
)
|
||||
{
|
||||
INITCHK;
|
||||
|
||||
if (ca_printf_func) {
|
||||
ca_static->ca_printf_func = ca_printf_func;
|
||||
}
|
||||
|
||||
187
src/ca/acctst.c
187
src/ca/acctst.c
@@ -5,6 +5,10 @@
|
||||
|
||||
static char *sccsId = "@(#) $Id$";
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#include <LIB$ROUTINES.H>
|
||||
#endif
|
||||
@@ -19,7 +23,7 @@ static char *sccsId = "@(#) $Id$";
|
||||
|
||||
#include "os_depen.h"
|
||||
|
||||
#include <epicsAssert.h>
|
||||
#include <assert.h>
|
||||
#include <cadef.h>
|
||||
|
||||
#define EVENT_ROUTINE null_event
|
||||
@@ -27,7 +31,11 @@ static char *sccsId = "@(#) $Id$";
|
||||
|
||||
#define NUM 1
|
||||
|
||||
int conn_get_cb_count;
|
||||
int conn_cb_count;
|
||||
|
||||
#ifndef min
|
||||
#define min(A,B) ((A)>(B)?(B):(A))
|
||||
#endif
|
||||
|
||||
int doacctst(char *pname);
|
||||
void test_sync_groups(chid chix);
|
||||
@@ -35,9 +43,22 @@ void multiple_sg_requests(chid chix, CA_SYNC_GID gid);
|
||||
void null_event(struct event_handler_args args);
|
||||
void write_event(struct event_handler_args args);
|
||||
void conn(struct connection_handler_args args);
|
||||
void conn_cb(struct event_handler_args args);
|
||||
void get_cb(struct event_handler_args args);
|
||||
void accessSecurity_cb(struct access_rights_handler_args args);
|
||||
|
||||
void doubleTest(
|
||||
chid chan,
|
||||
dbr_double_t beginValue,
|
||||
dbr_double_t increment,
|
||||
dbr_double_t epsilon,
|
||||
unsigned iterations);
|
||||
|
||||
void floatTest(
|
||||
chid chan,
|
||||
dbr_float_t beginValue,
|
||||
dbr_float_t increment,
|
||||
dbr_float_t epsilon,
|
||||
unsigned iterations);
|
||||
|
||||
#ifdef vxWorks
|
||||
int acctst(char *pname)
|
||||
@@ -92,13 +113,33 @@ int doacctst(char *pname)
|
||||
|
||||
SEVCHK(ca_task_initialize(), "Unable to initialize");
|
||||
|
||||
conn_get_cb_count = 0;
|
||||
conn_cb_count = 0;
|
||||
|
||||
printf("begin\n");
|
||||
#ifdef VMS
|
||||
lib$init_timer();
|
||||
#endif /*VMS*/
|
||||
|
||||
{
|
||||
TS_STAMP end_time;
|
||||
TS_STAMP start_time;
|
||||
double delay;
|
||||
double request = 0.5;
|
||||
double accuracy;
|
||||
|
||||
tsLocalTime(&start_time);
|
||||
status = ca_pend_event(request);
|
||||
if (status != ECA_TIMEOUT) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
tsLocalTime(&end_time);
|
||||
TsDiffAsDouble(&delay,&end_time,&start_time);
|
||||
accuracy = 100.0*(delay-request)/request;
|
||||
printf("CA pend event delay accuracy = %f %%\n",
|
||||
accuracy);
|
||||
assert (abs(accuracy) < 10.0);
|
||||
}
|
||||
|
||||
ptr = (struct dbr_gr_float *)
|
||||
malloc(dbr_size_n(DBR_GR_FLOAT, NUM));
|
||||
|
||||
@@ -213,34 +254,74 @@ int doacctst(char *pname)
|
||||
ca_read_access(chix1),
|
||||
ca_write_access(chix1));
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Verify that we can write and then read back
|
||||
* the same value
|
||||
* the same analog value
|
||||
*/
|
||||
if( (ca_field_type(chix1)==DBR_FLOAT ||
|
||||
ca_field_type(chix1)==DBR_DOUBLE) &&
|
||||
ca_read_access(chix1) &&
|
||||
ca_write_access(chix1)){
|
||||
|
||||
double dval = 3.3;
|
||||
float fval = -8893.3;
|
||||
double dret = DBL_MAX;
|
||||
float fret = FLT_MAX;
|
||||
double incr;
|
||||
double epsil;
|
||||
double base;
|
||||
unsigned long iter;
|
||||
|
||||
status = ca_put(DBR_DOUBLE, chix1, &dval);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_get(DBR_DOUBLE, chix1, &dret);
|
||||
SEVCHK(status, NULL);
|
||||
ca_pend_io(30.0);
|
||||
assert( fabs(dval-dret) < DBL_EPSILON*4);
|
||||
printf ("float test ...");
|
||||
fflush(stdout);
|
||||
epsil = FLT_EPSILON*4;
|
||||
base = FLT_MIN;
|
||||
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = FLT_MAX/fabs(incr);
|
||||
iter = min (iter,10);
|
||||
floatTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = FLT_MAX;
|
||||
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
|
||||
incr = - ldexp (0.5,i);
|
||||
iter = FLT_MAX/fabs(incr);
|
||||
iter = min (iter,10);
|
||||
floatTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = - FLT_MAX;
|
||||
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i++) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = FLT_MAX/fabs(incr);
|
||||
iter = min (iter,10);
|
||||
floatTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
printf ("done\n");
|
||||
|
||||
status = ca_put(DBR_FLOAT, chix1, &fval);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_get(DBR_FLOAT, chix1, &fret);
|
||||
SEVCHK(status, NULL);
|
||||
ca_pend_io(30.0);
|
||||
assert( fabs(fval-fret) < FLT_EPSILON*4);
|
||||
printf ("double test ...");
|
||||
fflush(stdout);
|
||||
epsil = DBL_EPSILON*4;
|
||||
base = DBL_MIN;
|
||||
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = DBL_MAX/fabs(incr);
|
||||
iter = min (iter,10);
|
||||
doubleTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = DBL_MAX;
|
||||
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
|
||||
incr = - ldexp (0.5,i);
|
||||
iter = DBL_MAX/fabs(incr);
|
||||
iter = min (iter,10);
|
||||
doubleTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = - DBL_MAX;
|
||||
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i++) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = DBL_MAX/fabs(incr);
|
||||
iter = min (iter,10);
|
||||
doubleTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
printf ("done\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* verify we dont jam up on many uninterrupted
|
||||
@@ -475,13 +556,13 @@ int doacctst(char *pname)
|
||||
SEVCHK(ca_modify_user_name("Willma"), NULL);
|
||||
SEVCHK(ca_modify_host_name("Bed Rock"), NULL);
|
||||
|
||||
if (conn_get_cb_count != 3){
|
||||
if (conn_cb_count != 3){
|
||||
printf ("!!!! Connect cb count = %d expected = 3 !!!!\n",
|
||||
conn_get_cb_count);
|
||||
conn_cb_count);
|
||||
}
|
||||
|
||||
printf("-- Put/Gets done- waiting for Events --\n");
|
||||
status = ca_pend_event(10.0);
|
||||
status = ca_pend_event(1000.0);
|
||||
if (status != ECA_TIMEOUT) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
@@ -505,7 +586,59 @@ int doacctst(char *pname)
|
||||
return(0);
|
||||
}
|
||||
|
||||
void floatTest(
|
||||
chid chan,
|
||||
dbr_float_t beginValue,
|
||||
dbr_float_t increment,
|
||||
dbr_float_t epsilon,
|
||||
unsigned iterations)
|
||||
{
|
||||
unsigned i;
|
||||
dbr_float_t fval;
|
||||
dbr_float_t fretval;
|
||||
int status;
|
||||
|
||||
fval = beginValue;
|
||||
for (i=0; i<iterations; i++) {
|
||||
fretval = FLT_MAX;
|
||||
status = ca_put (DBR_FLOAT, chan, &fval);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_get (DBR_FLOAT, chan, &fretval);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_pend_io (100.0);
|
||||
SEVCHK (status, NULL);
|
||||
assert (fabs(fval-fretval) < epsilon);
|
||||
|
||||
fval += increment;
|
||||
}
|
||||
}
|
||||
|
||||
void doubleTest(
|
||||
chid chan,
|
||||
dbr_double_t beginValue,
|
||||
dbr_double_t increment,
|
||||
dbr_double_t epsilon,
|
||||
unsigned iterations)
|
||||
{
|
||||
unsigned i;
|
||||
dbr_double_t fval;
|
||||
dbr_double_t fretval;
|
||||
int status;
|
||||
|
||||
fval = beginValue;
|
||||
for (i=0; i<iterations; i++) {
|
||||
fretval = DBL_MAX;
|
||||
status = ca_put (DBR_DOUBLE, chan, &fval);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_get (DBR_DOUBLE, chan, &fretval);
|
||||
SEVCHK (status, NULL);
|
||||
status = ca_pend_io (100.0);
|
||||
SEVCHK (status, NULL);
|
||||
assert (fabs(fval-fretval) < epsilon);
|
||||
|
||||
fval += increment;
|
||||
}
|
||||
}
|
||||
|
||||
void null_event(struct event_handler_args args)
|
||||
{
|
||||
@@ -544,15 +677,15 @@ void conn(struct connection_handler_args args)
|
||||
else
|
||||
printf("Ukn conn ev\n");
|
||||
|
||||
ca_get_callback(DBR_GR_FLOAT, args.chid, conn_cb, NULL);
|
||||
ca_get_callback(DBR_GR_FLOAT, args.chid, get_cb, NULL);
|
||||
}
|
||||
|
||||
void conn_cb(struct event_handler_args args)
|
||||
void get_cb(struct event_handler_args args)
|
||||
{
|
||||
if(!(args.status & CA_M_SUCCESS)){
|
||||
printf("Get cb failed because \"%s\"\n", ca_message(args.status));
|
||||
}
|
||||
conn_get_cb_count++;
|
||||
conn_cb_count++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -115,7 +115,13 @@ int cac_select_io(struct timeval *ptimeout, int flags)
|
||||
&autoTimeOut);
|
||||
# endif
|
||||
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
/*
|
||||
* get a new time stamp if we have been waiting
|
||||
* for any significant length of time
|
||||
*/
|
||||
if (ptimeout->tv_sec || ptimeout->tv_usec) {
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
}
|
||||
|
||||
if (status<0) {
|
||||
if (MYERRNO == EINTR) {
|
||||
|
||||
@@ -59,6 +59,7 @@ LOCAL void test (
|
||||
unsigned iterations
|
||||
);
|
||||
|
||||
LOCAL tf test_pend;
|
||||
LOCAL tf test_search;
|
||||
LOCAL tf test_free;
|
||||
LOCAL tf test_wait;
|
||||
@@ -82,7 +83,7 @@ int main(int argc, char **argv)
|
||||
catime(pname);
|
||||
}
|
||||
else{
|
||||
printf("usage: %s <channel name>", argv[0]);
|
||||
printf("usage: %s <channel name>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -119,6 +120,9 @@ int catime (char *channelName)
|
||||
ca_field_type(itemList[0].chix),
|
||||
ca_element_count(itemList[0].chix));
|
||||
|
||||
printf ("\tpend event test\n");
|
||||
timeIt (test_pend, NULL, 100);
|
||||
|
||||
for (i=0; i<NELEMENTS(itemList); i++) {
|
||||
itemList[i].val.fltval = 0.0;
|
||||
itemList[i].type = DBR_FLOAT;
|
||||
@@ -183,14 +187,56 @@ void timeIt(
|
||||
unsigned inlineIter;
|
||||
|
||||
status = tsLocalTime(&start_time);
|
||||
#if 0
|
||||
assert (status == S_ts_OK);
|
||||
#endif
|
||||
(*pfunc) (pItems, iterations, &inlineIter);
|
||||
status = tsLocalTime(&end_time);
|
||||
#if 0
|
||||
assert (status == S_ts_OK);
|
||||
#endif
|
||||
TsDiffAsDouble(&delay,&end_time,&start_time);
|
||||
printf ("Elapsed Per Item = %f\n", delay/(iterations*inlineIter));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* test_search ()
|
||||
*/
|
||||
LOCAL void test_pend(
|
||||
ti *pItems,
|
||||
unsigned iterations,
|
||||
unsigned *pInlineIter
|
||||
)
|
||||
{
|
||||
unsigned i;
|
||||
int status;
|
||||
|
||||
for (i=0; i<iterations; i++) {
|
||||
status = ca_pend_event(1e-9);
|
||||
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
status = ca_pend_event(1e-9);
|
||||
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
status = ca_pend_event(1e-9);
|
||||
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
status = ca_pend_event(1e-9);
|
||||
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
status = ca_pend_event(1e-9);
|
||||
if (status != ECA_TIMEOUT && status != ECA_NORMAL) {
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
}
|
||||
*pInlineIter = 5;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* test_search ()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* $Id$ */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* L O S A L A M O S */
|
||||
/* Los Alamos National Laboratory */
|
||||
/* Los Alamos, New Mexico 87545 */
|
||||
@@ -28,6 +29,7 @@
|
||||
/* .12 110194 joh improved search scheduling */
|
||||
/* (dont send all chans in a block) */
|
||||
/* */
|
||||
/* $Log$ */
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
@@ -349,7 +351,7 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno)
|
||||
/*
|
||||
* MARK_SERVER_AVAILABLE
|
||||
*/
|
||||
void mark_server_available(struct in_addr *pnet_addr)
|
||||
void mark_server_available(const struct in_addr *pnet_addr)
|
||||
{
|
||||
chid chan;
|
||||
ca_real currentPeriod;
|
||||
@@ -502,7 +504,7 @@ void mark_server_available(struct in_addr *pnet_addr)
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
|
||||
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr)
|
||||
{
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
@@ -535,7 +537,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
|
||||
* start the average at zero
|
||||
*/
|
||||
pBHE->averagePeriod = 0.0;
|
||||
cac_gettimeval(&pBHE->timeStamp);
|
||||
pBHE->timeStamp = ca_static->currentTime;
|
||||
|
||||
/*
|
||||
* install in the hash table
|
||||
@@ -552,7 +554,7 @@ bhe *createBeaconHashEntry(struct in_addr *pnet_addr)
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
|
||||
bhe *lookupBeaconInetAddr (const struct in_addr *pnet_addr)
|
||||
{
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
@@ -579,7 +581,7 @@ bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr)
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
void removeBeaconInetAddr (struct in_addr *pnet_addr)
|
||||
void removeBeaconInetAddr (const struct in_addr *pnet_addr)
|
||||
{
|
||||
bhe *pBHE;
|
||||
bhe **ppBHE;
|
||||
|
||||
@@ -94,8 +94,9 @@ LOCAL char *getToken(char **ppString);
|
||||
*
|
||||
*/
|
||||
int alloc_ioc(
|
||||
struct in_addr *pnet_addr,
|
||||
struct ioc_in_use **ppiiu
|
||||
const struct in_addr *pnet_addr,
|
||||
int port,
|
||||
struct ioc_in_use **ppiiu
|
||||
)
|
||||
{
|
||||
int status;
|
||||
@@ -127,6 +128,7 @@ struct ioc_in_use **ppiiu
|
||||
status = create_net_chan(
|
||||
ppiiu,
|
||||
pnet_addr,
|
||||
port,
|
||||
IPPROTO_TCP);
|
||||
if(status == ECA_NORMAL){
|
||||
pBHE->piiu = *ppiiu;
|
||||
@@ -145,7 +147,8 @@ struct ioc_in_use **ppiiu
|
||||
*/
|
||||
int create_net_chan(
|
||||
struct ioc_in_use **ppiiu,
|
||||
struct in_addr *pnet_addr, /* only used by TCP connections */
|
||||
const struct in_addr *pnet_addr, /* only used by TCP connections */
|
||||
int port,
|
||||
int net_proto
|
||||
)
|
||||
{
|
||||
@@ -190,8 +193,7 @@ int net_proto
|
||||
memset((char *)&pNode->destAddr,0,sizeof(pNode->destAddr));
|
||||
pNode->destAddr.inetAddr.sin_family = AF_INET;
|
||||
pNode->destAddr.inetAddr.sin_addr = *pnet_addr;
|
||||
pNode->destAddr.inetAddr.sin_port =
|
||||
htons (ca_static->ca_server_port);
|
||||
pNode->destAddr.inetAddr.sin_port = htons (port);
|
||||
ellAdd(&piiu->destAddr, &pNode->node);
|
||||
piiu->recvBytes = tcp_recv_msg;
|
||||
piiu->sendBytes = cac_tcp_send_msg_piiu;
|
||||
@@ -593,7 +595,7 @@ void notify_ca_repeater()
|
||||
|
||||
status = sendto(
|
||||
piiuCast->sock_chan,
|
||||
(char *)&msg, /* UCX requires a valid address here */
|
||||
(char *)&msg,
|
||||
len,
|
||||
0,
|
||||
(struct sockaddr *)&saddr,
|
||||
@@ -601,11 +603,16 @@ void notify_ca_repeater()
|
||||
if(status < 0){
|
||||
if( MYERRNO != EINTR &&
|
||||
MYERRNO != ENOBUFS &&
|
||||
MYERRNO != EWOULDBLOCK){
|
||||
MYERRNO != EWOULDBLOCK &&
|
||||
/*
|
||||
* This is returned from Linux when
|
||||
* the repeater isnt running
|
||||
*/
|
||||
MYERRNO != ECONNREFUSED
|
||||
){
|
||||
ca_printf(
|
||||
"send error => %s\n",
|
||||
strerror(MYERRNO));
|
||||
assert(0);
|
||||
"CAC: error sending to repeater is \"%s\"\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -659,29 +666,24 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
0,
|
||||
&pNode->destAddr.sockAddr,
|
||||
sizeof(pNode->destAddr.sockAddr));
|
||||
if(status<0){
|
||||
if(status>=0){
|
||||
actualSendCnt = (unsigned long) status;
|
||||
assert (actualSendCnt == sendCnt);
|
||||
pNode = (caAddrNode *) pNode->node.next;
|
||||
}
|
||||
else {
|
||||
int localErrno;
|
||||
|
||||
localErrno = MYERRNO;
|
||||
|
||||
if( localErrno == EWOULDBLOCK &&
|
||||
localErrno == ENOBUFS &&
|
||||
localErrno == EINTR){
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if( localErrno != EWOULDBLOCK &&
|
||||
localErrno != ENOBUFS &&
|
||||
localErrno != EINTR){
|
||||
ca_printf(
|
||||
"CAC: error on socket send() %s\n",
|
||||
"CAC: UDP send error = \"%s\"\n",
|
||||
strerror(localErrno));
|
||||
}
|
||||
|
||||
TAG_CONN_DOWN(piiu);
|
||||
break;
|
||||
}
|
||||
actualSendCnt = (unsigned long) status;
|
||||
assert (actualSendCnt == sendCnt);
|
||||
pNode = (caAddrNode *) pNode->node.next;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1043,7 +1045,6 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu)
|
||||
return;
|
||||
}
|
||||
ca_printf("Unexpected UDP failure %s\n", strerror(MYERRNO));
|
||||
TAG_CONN_DOWN(piiu);
|
||||
}
|
||||
else if(status > 0){
|
||||
unsigned long bytesActual;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* $Id */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* L O S A L A M O S */
|
||||
@@ -28,6 +29,7 @@
|
||||
/* .17 121892 joh added TCP send buf size var */
|
||||
/* .18 122192 joh added outstanding ack var */
|
||||
/* .19 012094 joh added minor version (for each server) */
|
||||
/* $Log$ */
|
||||
/* */
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
@@ -86,6 +88,7 @@ HDRVERSIONID(iocinfh, "$Id$")
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
/*
|
||||
* OS dependent includes
|
||||
@@ -511,7 +514,7 @@ void issue_client_host_name(struct ioc_in_use *piiu);
|
||||
int ca_defunct(void);
|
||||
int ca_printf(char *pformat, ...);
|
||||
void manage_conn(int silent);
|
||||
void mark_server_available(struct in_addr *pnet_addr);
|
||||
void mark_server_available(const struct in_addr *pnet_addr);
|
||||
void flow_control(struct ioc_in_use *piiu);
|
||||
int broadcast_addr(struct in_addr *pcastaddr);
|
||||
void ca_repeater(void);
|
||||
@@ -521,18 +524,19 @@ void ca_sg_init(void);
|
||||
void ca_sg_shutdown(struct ca_static *ca_temp);
|
||||
int cac_select_io(struct timeval *ptimeout, int flags);
|
||||
void caHostFromInetAddr(
|
||||
struct in_addr *pnet_addr,
|
||||
char *pBuf,
|
||||
unsigned size
|
||||
const struct in_addr *pnet_addr,
|
||||
char *pBuf,
|
||||
unsigned size
|
||||
);
|
||||
int post_msg(
|
||||
struct ioc_in_use *piiu,
|
||||
struct in_addr *pnet_addr,
|
||||
const struct in_addr *pnet_addr,
|
||||
char *pInBuf,
|
||||
unsigned long blockSize
|
||||
);
|
||||
int alloc_ioc(
|
||||
struct in_addr *pnet_addr,
|
||||
const struct in_addr *pnet_addr,
|
||||
int port,
|
||||
struct ioc_in_use **ppiiu
|
||||
);
|
||||
unsigned long cacRingBufferWrite(
|
||||
@@ -565,7 +569,8 @@ char *localHostName(void);
|
||||
|
||||
int create_net_chan(
|
||||
struct ioc_in_use **ppiiu,
|
||||
struct in_addr *pnet_addr, /* only used by TCP connections */
|
||||
const struct in_addr *pnet_addr, /* only used by TCP connections */
|
||||
int port,
|
||||
int net_proto
|
||||
);
|
||||
|
||||
@@ -576,9 +581,9 @@ void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port);
|
||||
int ca_os_independent_init (void);
|
||||
|
||||
void freeBeaconHash(struct ca_static *ca_temp);
|
||||
void removeBeaconInetAddr(struct in_addr *pnet_addr);
|
||||
bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr);
|
||||
bhe *createBeaconHashEntry(struct in_addr *pnet_addr);
|
||||
void removeBeaconInetAddr(const struct in_addr *pnet_addr);
|
||||
bhe *lookupBeaconInetAddr(const struct in_addr *pnet_addr);
|
||||
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr);
|
||||
void close_ioc(IIU *piiu);
|
||||
void notify_ca_repeater(void);
|
||||
void cac_clean_iiu_list(void);
|
||||
@@ -613,5 +618,6 @@ void caSetDefaultPrintfHandler ();
|
||||
*/
|
||||
#define M_dbAccess (501 <<16) /*Database Access Routines */
|
||||
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
|
||||
#define S_db_Pending (M_dbAccess|37) /*Request is pending*/
|
||||
|
||||
#endif /* this must be the last line in this file */
|
||||
|
||||
@@ -31,23 +31,26 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
|
||||
|
||||
/* TCP/UDP port number (bumped each protocol change) */
|
||||
#define CA_PROTOCOL_VERSION 4
|
||||
#define CA_MINOR_VERSION 4
|
||||
#define CA_MINOR_VERSION 5
|
||||
#define CA_UKN_MINOR_VERSION 0 /* unknown minor version */
|
||||
#if CA_PROTOCOL_VERSION == 4
|
||||
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1)
|
||||
#define CA_V42(MAJOR,MINOR) ((MINOR)>=2)
|
||||
#define CA_V43(MAJOR,MINOR) ((MINOR)>=3)
|
||||
#define CA_V44(MAJOR,MINOR) ((MINOR)>=4)
|
||||
#define CA_V45(MAJOR,MINOR) ((MINOR)>=5)
|
||||
#elif CA_PROTOCOL_VERSION > 4
|
||||
#define CA_V41(MAJOR,MINOR) ( 1 )
|
||||
#define CA_V42(MAJOR,MINOR) ( 1 )
|
||||
#define CA_V43(MAJOR,MINOR) ( 1 )
|
||||
#define CA_V44(MAJOR,MINOR) ( 1 )
|
||||
#define CA_V45(MAJOR,MINOR) ( 1 )
|
||||
#else
|
||||
#define CA_V41(MAJOR,MINOR) ( 0 )
|
||||
#define CA_V42(MAJOR,MINOR) ( 0 )
|
||||
#define CA_V43(MAJOR,MINOR) ( 0 )
|
||||
#define CA_V44(MAJOR,MINOR) ( 0 )
|
||||
#define CA_V45(MAJOR,MINOR) ( 0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -72,7 +75,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
|
||||
typedef unsigned short ca_uint16_t;
|
||||
typedef unsigned int ca_uint32_t;
|
||||
typedef float ca_float32_t;
|
||||
|
||||
typedef ca_uint32_t caResId;
|
||||
|
||||
/* values for m_cmmd */
|
||||
#define IOC_NOOP 0 /* do nothing, but verify TCP */
|
||||
@@ -169,4 +172,5 @@ struct monops { /* monitor req opi to ioc */
|
||||
struct mon_info m_info;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* __IOCMSG__ */
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ static char *sccsId = "@(#) $Id$";
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# include <winsock.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
@@ -54,7 +54,10 @@ static char *sccsId = "@(#) $Id$";
|
||||
/*
|
||||
* caHostFromInetAddr()
|
||||
*/
|
||||
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
|
||||
void caHostFromInetAddr(
|
||||
const struct in_addr *pnet_addr,
|
||||
char *pBuf,
|
||||
unsigned size)
|
||||
{
|
||||
char *pString;
|
||||
struct hostent *ent;
|
||||
|
||||
@@ -51,6 +51,9 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# include <netinet/tcp.h>
|
||||
# include <net/if.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <netdb.h>
|
||||
# include <sys/filio.h>
|
||||
# include <sys/sockio.h>
|
||||
# define CA_OS_CONFIGURED
|
||||
#endif
|
||||
|
||||
@@ -123,16 +126,16 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# define CA_OS_CONFIGURED
|
||||
#endif /*VMS*/
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# include <errno.h>
|
||||
# include <time.h>
|
||||
# include <windows.h>
|
||||
# include <winsock.h>
|
||||
# define CA_OS_CONFIGURED
|
||||
#endif /*_WINDOWS*/
|
||||
#endif /*WIN32*/
|
||||
|
||||
#ifndef CA_OS_CONFIGURED
|
||||
#error Please define one of vxWorks, UNIX VMS, or _WINDOWS
|
||||
#error Please define one of vxWorks, UNIX, VMS, or WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -213,6 +216,13 @@ static char *os_depenhSccsId = "$Id$";
|
||||
#define DELAYTICKS 50L /* (adjust units below) */
|
||||
#define TICKSPERSEC 1000L /* mili sec per sec */
|
||||
|
||||
/*
|
||||
* BSD prototypes missing from SUNOS4, MULTINET and
|
||||
* perhaps other environments
|
||||
*/
|
||||
#include <epicsTypes.h>
|
||||
#include <bsdProto.h>
|
||||
|
||||
/*
|
||||
* order of ops is important here
|
||||
*
|
||||
@@ -290,7 +300,7 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# define INVALID_SOCKET (-1)
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# define LOCK
|
||||
# define UNLOCK
|
||||
# define LOCKEVENTS
|
||||
@@ -308,7 +318,7 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# define MYERRNO WSAGetLastError()
|
||||
# define POST_IO_EV
|
||||
# define SYSFREQ 1000000L /* 1 MHz */
|
||||
#endif /*_WINDOWS*/
|
||||
#endif /*WIN32*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -70,6 +71,11 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
|
||||
cac_clean_iiu_list();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
@@ -77,12 +83,6 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
CA_DO_RECVS | CA_DO_SENDS);
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
@@ -95,7 +95,15 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
*/
|
||||
void cac_block_for_io_completion(struct timeval *pTV)
|
||||
{
|
||||
cac_mux_io(pTV);
|
||||
cac_mux_io (pTV);
|
||||
}
|
||||
|
||||
/*
|
||||
* cac_block_for_sg_completion()
|
||||
*/
|
||||
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
{
|
||||
cac_mux_io (pTV);
|
||||
}
|
||||
|
||||
|
||||
@@ -117,12 +125,6 @@ void os_specific_sg_delete(CASG *pcasg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
{
|
||||
cac_mux_io(pTV);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CAC_ADD_TASK_VARIABLE()
|
||||
@@ -140,17 +142,36 @@ int cac_add_task_variable(struct ca_static *ca_temp)
|
||||
int cac_os_depen_init(struct ca_static *pcas)
|
||||
{
|
||||
int status;
|
||||
struct sigaction sa;
|
||||
|
||||
ca_static = pcas;
|
||||
|
||||
/*
|
||||
* dont allow disconnect to terminate process
|
||||
* when running in UNIX enviroment
|
||||
* when running in UNIX environment
|
||||
*
|
||||
* allow error to be returned to sendto()
|
||||
* instead of handling disconnect at interrupt
|
||||
*/
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
status = sigaction(SIGPIPE, NULL, &sa);
|
||||
if (status==0) {
|
||||
if (sa.sa_handler == SIG_DFL) {
|
||||
sa.sa_handler = SIG_IGN;
|
||||
status = sigaction(SIGPIPE, &sa, NULL);
|
||||
if (status) {
|
||||
ca_printf(
|
||||
"%s: Error from signal replace was \"%s\"\n",
|
||||
__FILE__,
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ca_printf(
|
||||
"%s: Error from signal query was \"%s\"\n",
|
||||
__FILE__,
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
|
||||
status = ca_os_independent_init ();
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* PURPOSE:
|
||||
* Broadcasts fan out over the LAN, but UDP does not allow
|
||||
* two processes on the same machine to get the same broadcast.
|
||||
* This code takes extends the broadcast model from the net to within
|
||||
* This code extends the broadcast model from the net to within
|
||||
* the OS.
|
||||
*
|
||||
* NOTES:
|
||||
@@ -57,29 +57,37 @@
|
||||
* .06 120492 joh removed unnecessary includes
|
||||
* .07 120992 joh now uses dll list routines
|
||||
* .08 102993 joh toggle set sock opt to set
|
||||
*
|
||||
* .09 070195 joh discover client has vanished by connecting its
|
||||
* datagram socket (and watching for ECONNREFUSED)
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)$Id$";
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
/*
|
||||
* one socket per client so we will get the ECONNREFUSED
|
||||
* error code (and then delete the client)
|
||||
*/
|
||||
struct one_client{
|
||||
ELLNODE node;
|
||||
struct sockaddr_in from;
|
||||
SOCKET sock;
|
||||
};
|
||||
|
||||
/*
|
||||
* these can be external since there is only one instance
|
||||
* per machine so we dont care about reentrancy
|
||||
*/
|
||||
struct one_client{
|
||||
ELLNODE node;
|
||||
struct sockaddr_in from;
|
||||
};
|
||||
|
||||
static ELLLIST client_list;
|
||||
|
||||
static char buf[MAX_UDP];
|
||||
|
||||
LOCAL int clean_client(struct one_client *pclient);
|
||||
LOCAL void register_new_client(SOCKET sock, struct sockaddr_in *pLocal,
|
||||
LOCAL void register_new_client(struct sockaddr_in *pLocal,
|
||||
struct sockaddr_in *pFrom);
|
||||
#define PORT_ANY 0
|
||||
LOCAL int makeSocket(int port);
|
||||
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize);
|
||||
|
||||
|
||||
/*
|
||||
@@ -93,13 +101,9 @@ void ca_repeater()
|
||||
int status;
|
||||
int size;
|
||||
SOCKET sock;
|
||||
int true = 1;
|
||||
struct sockaddr_in from;
|
||||
struct sockaddr_in bd;
|
||||
struct sockaddr_in local;
|
||||
int from_size = sizeof from;
|
||||
struct one_client *pclient;
|
||||
struct one_client *pnxtclient;
|
||||
short port;
|
||||
|
||||
port = caFetchPortConfig(
|
||||
@@ -108,37 +112,20 @@ void ca_repeater()
|
||||
|
||||
ellInit(&client_list);
|
||||
|
||||
/* allocate a socket */
|
||||
sock = socket( AF_INET, /* domain */
|
||||
SOCK_DGRAM, /* type */
|
||||
0); /* deflt proto */
|
||||
assert(sock != INVALID_SOCKET);
|
||||
|
||||
|
||||
memset((char *)&bd, 0, sizeof(bd));
|
||||
bd.sin_family = AF_INET;
|
||||
bd.sin_addr.s_addr = INADDR_ANY;
|
||||
bd.sin_port = htons(port);
|
||||
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
|
||||
if(status<0){
|
||||
if(MYERRNO != EADDRINUSE){
|
||||
ca_printf("CA Repeater: unexpected bind fail %s\n",
|
||||
strerror(MYERRNO));
|
||||
sock = makeSocket(port);
|
||||
if (sock==INVALID_SOCKET) {
|
||||
/*
|
||||
* test for server was already started
|
||||
*/
|
||||
if (MYERRNO==EADDRINUSE) {
|
||||
exit(0);
|
||||
}
|
||||
socket_close(sock);
|
||||
ca_printf("%s: Unable to create repeater socket because \"%s\"\n",
|
||||
__FILE__,
|
||||
strerror(MYERRNO));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
status = setsockopt( sock,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
(char *)&true,
|
||||
sizeof(true));
|
||||
if(status<0){
|
||||
ca_printf( "%s: set socket option failed\n",
|
||||
__FILE__);
|
||||
}
|
||||
|
||||
status = local_addr(sock, &local);
|
||||
if(status != OK){
|
||||
ca_printf(
|
||||
@@ -164,78 +151,131 @@ void ca_repeater()
|
||||
if(size < 0){
|
||||
ca_printf("CA Repeater: recv err %s\n",
|
||||
strerror(MYERRNO));
|
||||
continue;
|
||||
}
|
||||
|
||||
pMsg = (struct extmsg *) buf;
|
||||
|
||||
/*
|
||||
* both zero leng message and a registartion message
|
||||
* both zero length message and a registration message
|
||||
* will register a new client
|
||||
*/
|
||||
if(size >= sizeof(*pMsg)){
|
||||
if(ntohs(pMsg->m_cmmd) == REPEATER_REGISTER){
|
||||
register_new_client(sock, &local, &from);
|
||||
register_new_client(&local, &from);
|
||||
|
||||
/*
|
||||
* strip register client message
|
||||
*/
|
||||
pMsg++;
|
||||
size -= sizeof(*pMsg);
|
||||
if (size==0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(size == 0){
|
||||
register_new_client(sock, &local, &from);
|
||||
register_new_client(&local, &from);
|
||||
continue;
|
||||
}
|
||||
|
||||
fanOut(&from, (char *) pMsg, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fanOut()
|
||||
*/
|
||||
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize)
|
||||
{
|
||||
ELLLIST theClients;
|
||||
struct one_client *pclient;
|
||||
int status;
|
||||
|
||||
ellInit(&theClients);
|
||||
while (pclient=(struct one_client *)ellGet(&client_list)) {
|
||||
ellAdd(&theClients, &pclient->node);
|
||||
|
||||
/*
|
||||
* size may have been adjusted above
|
||||
* Dont reflect back to sender
|
||||
*/
|
||||
if(size){
|
||||
for( pclient = (struct one_client *)
|
||||
client_list.node.next;
|
||||
pclient;
|
||||
pclient = (struct one_client *)
|
||||
pclient->node.next){
|
||||
if(pFrom->sin_port == pclient->from.sin_port &&
|
||||
pFrom->sin_addr.s_addr == pclient->from.sin_addr.s_addr){
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dont reflect back to sender
|
||||
*/
|
||||
if(from.sin_port == pclient->from.sin_port &&
|
||||
from.sin_addr.s_addr ==
|
||||
pclient->from.sin_addr.s_addr){
|
||||
continue;
|
||||
}
|
||||
|
||||
status = sendto(
|
||||
sock,
|
||||
(char *)pMsg,
|
||||
size,
|
||||
0,
|
||||
(struct sockaddr *)&pclient->from,
|
||||
sizeof pclient->from);
|
||||
if(status < 0){
|
||||
ca_printf("CA Repeater: fanout err %s\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
status = send(
|
||||
pclient->sock,
|
||||
(char *)pMsg,
|
||||
msgSize,
|
||||
0);
|
||||
if (status>=0) {
|
||||
#ifdef DEBUG
|
||||
ca_printf("Sent\n");
|
||||
ca_printf("Sent to %d\n",
|
||||
pclient->from.sin_port);
|
||||
#endif
|
||||
}
|
||||
if(status < 0){
|
||||
if (MYERRNO == ECONNREFUSED) {
|
||||
#ifdef DEBUG
|
||||
ca_printf("Deleted client %d\n",
|
||||
pclient->from.sin_port);
|
||||
#endif
|
||||
ellDelete(&theClients,
|
||||
&pclient->node);
|
||||
socket_close(pclient->sock);
|
||||
free(pclient);
|
||||
}
|
||||
else {
|
||||
ca_printf(
|
||||
"CA Repeater: fan out err was \"%s\"\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove any dead wood prior to pending
|
||||
*/
|
||||
for( pclient = (struct one_client *)
|
||||
client_list.node.next;
|
||||
pclient;
|
||||
pclient = pnxtclient){
|
||||
/* do it now in case item deleted */
|
||||
pnxtclient = (struct one_client *)
|
||||
pclient->node.next;
|
||||
clean_client(pclient);
|
||||
}
|
||||
}
|
||||
ellConcat(&client_list, &theClients);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* makeSocket()
|
||||
*/
|
||||
LOCAL int makeSocket(int port)
|
||||
{
|
||||
int status;
|
||||
struct sockaddr_in bd;
|
||||
int sock;
|
||||
int true = 1;
|
||||
|
||||
sock = socket( AF_INET, /* domain */
|
||||
SOCK_DGRAM, /* type */
|
||||
0); /* deflt proto */
|
||||
if (sock == INVALID_SOCKET) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
status = setsockopt( sock,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
(char *)&true,
|
||||
sizeof(true));
|
||||
if(status<0){
|
||||
ca_printf( "%s: set socket option failed\n",
|
||||
__FILE__);
|
||||
}
|
||||
|
||||
memset((char *)&bd, 0, sizeof(bd));
|
||||
bd.sin_family = AF_INET;
|
||||
bd.sin_addr.s_addr = INADDR_ANY;
|
||||
bd.sin_port = htons(port);
|
||||
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
|
||||
if(status<0){
|
||||
socket_close(sock);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,17 +283,17 @@ void ca_repeater()
|
||||
* register_new_client()
|
||||
*/
|
||||
LOCAL void register_new_client(
|
||||
SOCKET sock,
|
||||
struct sockaddr_in *pLocal,
|
||||
struct sockaddr_in *pFrom)
|
||||
{
|
||||
int status;
|
||||
struct one_client *pclient;
|
||||
struct extmsg confirm;
|
||||
struct extmsg noop;
|
||||
|
||||
for( pclient = (struct one_client *) client_list.node.next;
|
||||
for( pclient = (struct one_client *) ellFirst(&client_list);
|
||||
pclient;
|
||||
pclient = (struct one_client *) pclient->node.next){
|
||||
pclient = (struct one_client *) ellNext(&pclient->node)){
|
||||
|
||||
if( pFrom->sin_port == pclient->from.sin_port &&
|
||||
pFrom->sin_addr.s_addr == pclient->from.sin_addr.s_addr)
|
||||
@@ -262,101 +302,73 @@ struct sockaddr_in *pFrom)
|
||||
|
||||
if(!pclient){
|
||||
pclient = (struct one_client *)calloc (1, sizeof(*pclient));
|
||||
if(pclient){
|
||||
pclient->from = *pFrom;
|
||||
ellAdd (&client_list, &pclient->node);
|
||||
#ifdef DEBUG
|
||||
ca_printf (
|
||||
"Added %d\n",
|
||||
pFrom->sin_port);
|
||||
#endif
|
||||
if(!pclient){
|
||||
ca_printf("%s: no memory for new client\n",
|
||||
__FILE__);
|
||||
return;
|
||||
}
|
||||
|
||||
pclient->sock = makeSocket(PORT_ANY);
|
||||
if (!pclient->sock) {
|
||||
free(pclient);
|
||||
ca_printf("%s: no client sock because \"%s\"\n",
|
||||
__FILE__,
|
||||
strerror(MYERRNO));
|
||||
return;
|
||||
}
|
||||
|
||||
status = connect(pclient->sock,
|
||||
(struct sockaddr *)pFrom,
|
||||
sizeof(*pFrom));
|
||||
if (status<0) {
|
||||
socket_close(pclient->sock);
|
||||
free(pclient);
|
||||
ca_printf("%s: unable to connect client sock\n",
|
||||
__FILE__);
|
||||
return;
|
||||
}
|
||||
|
||||
pclient->from = *pFrom;
|
||||
|
||||
ellAdd (&client_list, &pclient->node);
|
||||
#ifdef DEBUG
|
||||
ca_printf (
|
||||
"Added %d\n",
|
||||
pFrom->sin_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
memset((char *)&confirm, 0, sizeof confirm);
|
||||
memset((char *)&confirm, '\0', sizeof(confirm));
|
||||
confirm.m_cmmd = htons(REPEATER_CONFIRM);
|
||||
confirm.m_available = pLocal->sin_addr.s_addr;
|
||||
status = sendto(
|
||||
sock,
|
||||
status = send(
|
||||
pclient->sock,
|
||||
(char *)&confirm,
|
||||
sizeof(confirm),
|
||||
0,
|
||||
(struct sockaddr *)pFrom, /* back to sender */
|
||||
sizeof(*pFrom));
|
||||
if(status != sizeof(confirm)){
|
||||
ca_printf("CA Repeater: confirm err %s\n",
|
||||
strerror(MYERRNO));
|
||||
0);
|
||||
if(status >= 0){
|
||||
assert(status == sizeof(confirm));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* check to see if this client is still around
|
||||
*
|
||||
* NOTE:
|
||||
* This closes the socket only whenever we are
|
||||
* able to bind so that we free the port.
|
||||
*/
|
||||
LOCAL int clean_client(struct one_client *pclient)
|
||||
{
|
||||
static int sockExists;
|
||||
static SOCKET sock;
|
||||
int port = pclient->from.sin_port;
|
||||
struct sockaddr_in bd;
|
||||
int status;
|
||||
int present = FALSE;
|
||||
|
||||
/*
|
||||
* allocate a socket
|
||||
* (no lock required because this is implemented with
|
||||
* a single thread)
|
||||
*/
|
||||
if(!sockExists){
|
||||
sock = socket(
|
||||
AF_INET, /* domain */
|
||||
SOCK_DGRAM, /* type */
|
||||
0); /* deflt proto */
|
||||
if(sock != INVALID_SOCKET){
|
||||
sockExists = TRUE;
|
||||
}
|
||||
else{
|
||||
ca_printf("CA Repeater: no bind test sock err %s\n",
|
||||
strerror(MYERRNO));
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
memset((char *)&bd, 0, sizeof(bd));
|
||||
bd.sin_family = AF_INET;
|
||||
bd.sin_addr.s_addr = INADDR_ANY;
|
||||
bd.sin_port = port;
|
||||
status = bind(sock, (struct sockaddr *)&bd, sizeof(bd));
|
||||
if(status>=0){
|
||||
socket_close (sock);
|
||||
sockExists = FALSE;
|
||||
}
|
||||
else{
|
||||
if(MYERRNO == EADDRINUSE){
|
||||
present = TRUE;
|
||||
}
|
||||
else{
|
||||
ca_printf("CA Repeater: client cleanup err %s\n",
|
||||
strerror(MYERRNO));
|
||||
ca_printf("CA Repeater: sock=%d family=%d addr=%x port=%d\n",
|
||||
sock, bd.sin_family, bd.sin_addr.s_addr,
|
||||
bd.sin_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!present){
|
||||
else if (MYERRNO == ECONNREFUSED){
|
||||
#ifdef DEBUG
|
||||
ca_printf("Deleted %d\n", pclient->from.sin_port);
|
||||
ca_printf("Deleted repeater client=%d sending ack\n",
|
||||
pFrom->sin_port);
|
||||
#endif
|
||||
ellDelete(&client_list, &pclient->node);
|
||||
socket_close(pclient->sock);
|
||||
free(pclient);
|
||||
}
|
||||
else {
|
||||
ca_printf("CA Repeater: confirm err was \"%s\"\n",
|
||||
strerror(MYERRNO));
|
||||
}
|
||||
|
||||
return OK;
|
||||
/*
|
||||
* send a noop message to all other clients so that we dont
|
||||
* accumulate sockets when there are no beacons
|
||||
*/
|
||||
memset((char *)&noop, '\0', sizeof(noop));
|
||||
confirm.m_cmmd = htons(IOC_NOOP);
|
||||
fanOut(pFrom, (char *)&noop, sizeof(noop));
|
||||
}
|
||||
|
||||
|
||||
@@ -81,12 +81,12 @@ chid chan
|
||||
|
||||
LOCAL int cacMsg(
|
||||
struct ioc_in_use *piiu,
|
||||
struct in_addr *pnet_addr
|
||||
const struct in_addr *pnet_addr
|
||||
);
|
||||
|
||||
LOCAL void perform_claim_channel(
|
||||
IIU *piiu,
|
||||
struct in_addr *pnet_addr
|
||||
const struct in_addr *pnet_addr
|
||||
);
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
@@ -103,7 +103,7 @@ extern CACVRTFUNC *cac_dbr_cvrt[];
|
||||
*/
|
||||
int post_msg(
|
||||
struct ioc_in_use *piiu,
|
||||
struct in_addr *pnet_addr,
|
||||
const struct in_addr *pnet_addr,
|
||||
char *pInBuf,
|
||||
unsigned long blockSize
|
||||
)
|
||||
@@ -236,7 +236,7 @@ unsigned long blockSize
|
||||
*/
|
||||
LOCAL int cacMsg(
|
||||
struct ioc_in_use *piiu,
|
||||
struct in_addr *pnet_addr
|
||||
const struct in_addr *pnet_addr
|
||||
)
|
||||
{
|
||||
evid monix;
|
||||
@@ -293,9 +293,8 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
LOCK;
|
||||
ellDelete(&pend_write_list, &monix->node);
|
||||
UNLOCK;
|
||||
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
|
||||
break;
|
||||
|
||||
@@ -366,8 +365,8 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
LOCK;
|
||||
ellDelete(&pend_read_list, &monix->node);
|
||||
UNLOCK;
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -398,8 +397,8 @@ struct in_addr *pnet_addr
|
||||
if (!piiu->curMsg.m_postsize) {
|
||||
LOCK;
|
||||
ellDelete(&monix->chan->eventq, &monix->node);
|
||||
UNLOCK;
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -509,8 +508,8 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
LOCK;
|
||||
ellDelete(&pend_read_list, &pIOBlock->node);
|
||||
UNLOCK;
|
||||
caIOBlockFree(pIOBlock);
|
||||
UNLOCK;
|
||||
break;
|
||||
}
|
||||
case IOC_SEARCH:
|
||||
@@ -548,6 +547,7 @@ struct in_addr *pnet_addr
|
||||
|
||||
case IOC_ERROR:
|
||||
{
|
||||
ELLLIST *pList = NULL;
|
||||
evid monix;
|
||||
char nameBuf[64];
|
||||
char context[255];
|
||||
@@ -584,32 +584,30 @@ struct in_addr *pnet_addr
|
||||
*/
|
||||
monix = NULL;
|
||||
args.addr = NULL;
|
||||
LOCK;
|
||||
switch (ntohs(req->m_cmmd)) {
|
||||
case IOC_READ_NOTIFY:
|
||||
LOCK;
|
||||
monix = (evid) bucketLookupItemUnsignedId(
|
||||
pFastBucket,
|
||||
&req->m_available);
|
||||
UNLOCK;
|
||||
pList = &pend_read_list;
|
||||
op = CA_OP_GET;
|
||||
break;
|
||||
case IOC_READ:
|
||||
LOCK;
|
||||
monix = (evid) bucketLookupItemUnsignedId(
|
||||
pFastBucket,
|
||||
&req->m_available);
|
||||
UNLOCK;
|
||||
if(monix){
|
||||
args.addr = monix->usr_arg;
|
||||
}
|
||||
pList = &pend_read_list;
|
||||
op = CA_OP_GET;
|
||||
break;
|
||||
case IOC_WRITE_NOTIFY:
|
||||
LOCK;
|
||||
monix = (evid) bucketLookupItemUnsignedId(
|
||||
pFastBucket,
|
||||
&req->m_available);
|
||||
UNLOCK;
|
||||
pList = &pend_write_list;
|
||||
op = CA_OP_PUT;
|
||||
break;
|
||||
case IOC_WRITE:
|
||||
@@ -619,19 +617,18 @@ struct in_addr *pnet_addr
|
||||
op = CA_OP_SEARCH;
|
||||
break;
|
||||
case IOC_EVENT_ADD:
|
||||
LOCK;
|
||||
monix = (evid) bucketLookupItemUnsignedId(
|
||||
pFastBucket,
|
||||
&req->m_available);
|
||||
UNLOCK;
|
||||
op = CA_OP_ADD_EVENT;
|
||||
if (monix) {
|
||||
pList = &monix->chan->eventq;
|
||||
}
|
||||
break;
|
||||
case IOC_EVENT_CANCEL:
|
||||
LOCK;
|
||||
monix = (evid) bucketLookupItemUnsignedId(
|
||||
pFastBucket,
|
||||
&req->m_available);
|
||||
UNLOCK;
|
||||
op = CA_OP_CLEAR_EVENT;
|
||||
break;
|
||||
default:
|
||||
@@ -640,10 +637,15 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
|
||||
if (monix) {
|
||||
if (pList) {
|
||||
ellDelete(pList, &monix->node);
|
||||
}
|
||||
else {
|
||||
printf ("CAC - Protocol err - no list for IO blk\n");
|
||||
}
|
||||
caIOBlockFree(monix);
|
||||
}
|
||||
|
||||
LOCK;
|
||||
args.chid = bucketLookupItemUnsignedId
|
||||
(pSlowBucket, &piiu->curMsg.m_cid);
|
||||
UNLOCK;
|
||||
@@ -728,16 +730,18 @@ struct in_addr *pnet_addr
|
||||
*/
|
||||
LOCAL void perform_claim_channel(
|
||||
IIU *piiu,
|
||||
struct in_addr *pnet_addr
|
||||
const struct in_addr *pnet_addr
|
||||
)
|
||||
{
|
||||
int v42;
|
||||
int port;
|
||||
char rej[64];
|
||||
chid chan;
|
||||
int status;
|
||||
IIU *allocpiiu;
|
||||
IIU *chpiiu;
|
||||
unsigned short *pMinorVersion;
|
||||
unsigned minorVersion;
|
||||
|
||||
/*
|
||||
* ignore broadcast replies for deleted channels
|
||||
@@ -792,8 +796,31 @@ struct in_addr *pnet_addr
|
||||
return;
|
||||
}
|
||||
|
||||
status = alloc_ioc(pnet_addr, &allocpiiu);
|
||||
switch(status){
|
||||
/*
|
||||
* Starting with CA V4.1 the minor version number
|
||||
* is appended to the end of each search reply.
|
||||
* This value is ignored by earlier clients.
|
||||
*/
|
||||
if(piiu->curMsg.m_postsize >= sizeof(*pMinorVersion)){
|
||||
pMinorVersion = (unsigned short *)(piiu->pCurData);
|
||||
minorVersion = ntohs(*pMinorVersion);
|
||||
}
|
||||
else{
|
||||
minorVersion = CA_UKN_MINOR_VERSION;
|
||||
}
|
||||
|
||||
/*
|
||||
* the type field is abused to carry the port number
|
||||
* so that we can have multiple servers on one host
|
||||
*/
|
||||
if (CA_V45 (CA_PROTOCOL_VERSION,minorVersion)) {
|
||||
port = piiu->curMsg.m_type;
|
||||
}
|
||||
else {
|
||||
port = ca_static->ca_server_port;
|
||||
}
|
||||
status = alloc_ioc (pnet_addr, port, &allocpiiu);
|
||||
switch (status) {
|
||||
|
||||
case ECA_NORMAL:
|
||||
break;
|
||||
@@ -818,22 +845,11 @@ struct in_addr *pnet_addr
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Starting with CA V4.1 the minor version number
|
||||
* is appended to the end of each search reply.
|
||||
* This value is ignored by earlier clients.
|
||||
*/
|
||||
if(piiu->curMsg.m_postsize >= sizeof(*pMinorVersion)){
|
||||
pMinorVersion = (unsigned short *)(piiu->pCurData);
|
||||
allocpiiu->minor_version_number = ntohs(*pMinorVersion);
|
||||
}
|
||||
else{
|
||||
allocpiiu->minor_version_number = CA_UKN_MINOR_VERSION;
|
||||
}
|
||||
allocpiiu->minor_version_number = minorVersion;
|
||||
|
||||
ellDelete(&chpiiu->chidlist, &chan->node);
|
||||
ellDelete (&chpiiu->chidlist, &chan->node);
|
||||
chan->piiu = allocpiiu;
|
||||
ellAdd(&allocpiiu->chidlist, &chan->node);
|
||||
ellAdd (&allocpiiu->chidlist, &chan->node);
|
||||
ca_static->ca_search_responses++;
|
||||
|
||||
/*
|
||||
@@ -842,7 +858,7 @@ struct in_addr *pnet_addr
|
||||
* the client's name to the server.
|
||||
* (CA V4.1 or higher)
|
||||
*/
|
||||
if(ellCount(&allocpiiu->chidlist)==1){
|
||||
if (ellCount(&allocpiiu->chidlist)==1) {
|
||||
issue_identify_client(allocpiiu);
|
||||
issue_client_host_name(allocpiiu);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*
|
||||
* NOTES:
|
||||
* 1) Need to fix if the OP is on a FD that
|
||||
@@ -97,7 +98,7 @@ void ca_sg_shutdown(struct ca_static *ca_temp)
|
||||
/*
|
||||
* ca_sg_create()
|
||||
*/
|
||||
int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
|
||||
int epicsShareAPI ca_sg_create(CA_SYNC_GID *pgid)
|
||||
{
|
||||
int status;
|
||||
CASG *pcasg;
|
||||
@@ -130,29 +131,38 @@ int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
|
||||
*/
|
||||
memset((char *)pcasg,0,sizeof(*pcasg));
|
||||
pcasg->magic = CASG_MAGIC;
|
||||
pcasg->id = CLIENT_SLOW_ID_ALLOC;
|
||||
pcasg->opPendCount = 0;
|
||||
pcasg->seqNo = 0;
|
||||
|
||||
os_specific_sg_create(pcasg);
|
||||
|
||||
status = bucketAddItemUnsignedId(pSlowBucket, &pcasg->id, pcasg);
|
||||
if(status == BUCKET_SUCCESS){
|
||||
do {
|
||||
pcasg->id = CLIENT_SLOW_ID_ALLOC;
|
||||
status = bucketAddItemUnsignedId (pSlowBucket,
|
||||
&pcasg->id, pcasg);
|
||||
} while (status == S_bucket_idInUse);
|
||||
|
||||
if (status == S_bucket_success) {
|
||||
/*
|
||||
* place it on the active sync group list
|
||||
*/
|
||||
ellAdd(&ca_static->activeCASG, &pcasg->node);
|
||||
* place it on the active sync group list
|
||||
*/
|
||||
ellAdd (&ca_static->activeCASG, &pcasg->node);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
/*
|
||||
* place it back on the free sync group list
|
||||
*/
|
||||
ellAdd(&ca_static->freeCASG, &pcasg->node);
|
||||
ellAdd (&ca_static->freeCASG, &pcasg->node);
|
||||
UNLOCK;
|
||||
if (status == S_bucket_noMemory) {
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
else {
|
||||
return ECA_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
if(status != BUCKET_SUCCESS){
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
|
||||
*(WRITEABLE_CA_SYNC_GID *)pgid = pcasg->id;
|
||||
return ECA_NORMAL;
|
||||
@@ -162,7 +172,7 @@ int APIENTRY ca_sg_create(CA_SYNC_GID *pgid)
|
||||
/*
|
||||
* ca_sg_delete()
|
||||
*/
|
||||
int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
|
||||
int epicsShareAPI ca_sg_delete(CA_SYNC_GID gid)
|
||||
{
|
||||
int status;
|
||||
CASG *pcasg;
|
||||
@@ -183,7 +193,7 @@ int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
|
||||
}
|
||||
|
||||
status = bucketRemoveItemUnsignedId(pSlowBucket, &gid);
|
||||
assert(status == BUCKET_SUCCESS);
|
||||
assert (status == S_bucket_success);
|
||||
|
||||
os_specific_sg_delete(pcasg);
|
||||
|
||||
@@ -200,7 +210,7 @@ int APIENTRY ca_sg_delete(CA_SYNC_GID gid)
|
||||
/*
|
||||
* ca_sg_block()
|
||||
*/
|
||||
int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
int epicsShareAPI ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
{
|
||||
struct timeval beg_time;
|
||||
ca_real delay;
|
||||
@@ -237,16 +247,11 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
UNLOCK;
|
||||
|
||||
/*
|
||||
* always flush and take care
|
||||
* of connection management
|
||||
* at least once.
|
||||
* always flush at least once.
|
||||
*/
|
||||
ca_flush_io();
|
||||
|
||||
/*
|
||||
* the current time set within ca_flush_io()
|
||||
* above.
|
||||
*/
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
beg_time = ca_static->currentTime;
|
||||
delay = 0.0;
|
||||
|
||||
@@ -257,9 +262,23 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
|
||||
/*
|
||||
* Exit if the timeout has expired
|
||||
* (dont wait forever for an itsy bitsy
|
||||
* delay which will no be updated if
|
||||
* select is called with no delay)
|
||||
*
|
||||
* current time is only updated by
|
||||
* cac_select_io() if we specify
|
||||
* at least 1 usec to wait
|
||||
*/
|
||||
remaining = timeout-delay;
|
||||
if (remaining<=0.0) {
|
||||
if (remaining<=(1.0/USEC_PER_SEC)) {
|
||||
/*
|
||||
* Make sure that we take care of
|
||||
* recv backlog at least once
|
||||
*/
|
||||
tmo.tv_sec = 0L;
|
||||
tmo.tv_usec = 0L;
|
||||
cac_mux_io (&tmo);
|
||||
status = ECA_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
@@ -276,10 +295,6 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
tmo.tv_usec = (long) ((remaining-tmo.tv_sec)*USEC_PER_SEC);
|
||||
cac_block_for_sg_completion (pcasg, &tmo);
|
||||
|
||||
/*
|
||||
* the current time set within cac_block_for_sg_completion()
|
||||
* above.
|
||||
*/
|
||||
delay = cac_time_diff (&ca_static->currentTime, &beg_time);
|
||||
}
|
||||
pcasg->opPendCount = 0;
|
||||
@@ -291,7 +306,7 @@ int APIENTRY ca_sg_block(CA_SYNC_GID gid, ca_real timeout)
|
||||
/*
|
||||
* ca_sg_reset
|
||||
*/
|
||||
int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
|
||||
int epicsShareAPI ca_sg_reset(CA_SYNC_GID gid)
|
||||
{
|
||||
CASG *pcasg;
|
||||
|
||||
@@ -313,7 +328,7 @@ int APIENTRY ca_sg_reset(CA_SYNC_GID gid)
|
||||
/*
|
||||
* ca_sg_test
|
||||
*/
|
||||
int APIENTRY ca_sg_test(CA_SYNC_GID gid)
|
||||
int epicsShareAPI ca_sg_test(CA_SYNC_GID gid)
|
||||
{
|
||||
CASG *pcasg;
|
||||
|
||||
@@ -339,7 +354,7 @@ int APIENTRY ca_sg_test(CA_SYNC_GID gid)
|
||||
/*
|
||||
* ca_sg_array_put()
|
||||
*/
|
||||
int APIENTRY ca_sg_array_put(
|
||||
int epicsShareAPI ca_sg_array_put(
|
||||
CA_SYNC_GID gid,
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -404,7 +419,7 @@ void *pvalue)
|
||||
/*
|
||||
* ca_sg_array_get()
|
||||
*/
|
||||
int APIENTRY ca_sg_array_get(
|
||||
int epicsShareAPI ca_sg_array_get(
|
||||
CA_SYNC_GID gid,
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
|
||||
@@ -19,7 +19,7 @@ static char *sccsId = "$Id$";
|
||||
#include "iocinf.h"
|
||||
|
||||
|
||||
void APIENTRY ca_test_event(struct event_handler_args args)
|
||||
void epicsShareAPI ca_test_event(struct event_handler_args args)
|
||||
{
|
||||
ca_printf("CAC: ~~~### in test event for [%s] ###~~~\n",args.chid+1);
|
||||
ca_printf("CAC: User argument\t%x\n", args.usr);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -72,6 +73,11 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
|
||||
cac_clean_iiu_list();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
@@ -80,11 +86,6 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
@@ -286,7 +287,8 @@ void ca_spawn_repeater()
|
||||
* gethostbyaddr(). This makes gethostbyaddr()
|
||||
* hang when it is called from AST level.
|
||||
*/
|
||||
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
|
||||
void caHostFromInetAddr(const struct in_addr *pnet_addr,
|
||||
char *pBuf, unsigned size)
|
||||
{
|
||||
char *pString;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -144,6 +145,12 @@ void cac_block_for_io_completion(struct timeval *pTV)
|
||||
ticks = min(LOCALTICKS, ticks);
|
||||
|
||||
semTake(io_done_sem, ticks);
|
||||
/*
|
||||
* force a time update because we are not
|
||||
* going to get one with a nill timeout in
|
||||
* ca_mux_io()
|
||||
*/
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -206,6 +213,12 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
ticks = min(LOCALTICKS, ticks);
|
||||
|
||||
semTake (pcasg->sem, ticks);
|
||||
/*
|
||||
* force a time update because we are not
|
||||
* going to get one with a nill timeout in
|
||||
* ca_mux_io()
|
||||
*/
|
||||
cac_gettimeval (&ca_static->currentTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -601,7 +614,10 @@ char *localUserName()
|
||||
/*
|
||||
* caHostFromInetAddr()
|
||||
*/
|
||||
void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size)
|
||||
void caHostFromInetAddr(
|
||||
const struct in_addr *pnet_addr,
|
||||
char *pBuf,
|
||||
unsigned size)
|
||||
{
|
||||
char str[INET_ADDR_LEN];
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -39,8 +40,8 @@
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
#ifndef _WINDOWS
|
||||
#error This source is specific to DOS/WINDOS
|
||||
#ifndef WIN32
|
||||
#error This source is specific to WIN32
|
||||
#endif
|
||||
|
||||
static int get_subnet_mask ( char SubNetMaskStr[256]);
|
||||
@@ -79,6 +80,11 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
|
||||
cac_clean_iiu_list();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout = *ptimeout;
|
||||
do{
|
||||
count = cac_select_io(
|
||||
@@ -87,11 +93,6 @@ void cac_mux_io(struct timeval *ptimeout)
|
||||
|
||||
ca_process_input_queue();
|
||||
|
||||
/*
|
||||
* manage search timers and detect disconnects
|
||||
*/
|
||||
manage_conn(TRUE);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
@@ -434,7 +435,7 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
|
||||
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
BOOL epicsShareAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
int status;
|
||||
WSADATA WsaData;
|
||||
@@ -445,11 +446,13 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
|
||||
if ((status = WSAStartup(MAKEWORD(1,1), &WsaData)) != 0)
|
||||
return FALSE;
|
||||
#if _DEBUG
|
||||
if (AllocConsole()) {
|
||||
SetConsoleTitle("Channel Access Status");
|
||||
freopen( "CONOUT$", "a", stderr );
|
||||
fprintf(stderr, "Process attached to ca.dll R12\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
||||
@@ -2,27 +2,25 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
USR_CFLAGS = -ansi
|
||||
VX_WARN_YES = -Wall -pedantic
|
||||
|
||||
SRCS.c = \
|
||||
../dbAccess.c ../dbBkpt.c ../dbFastLinkConv.c ../dbLink.c \
|
||||
../dbNotify.c ../dbStaticLib.c ../iocInit.c ../drvTS.c ../dbScan.c \
|
||||
../dbEvent.c ../dbTest.c ../dbls.c ../db_access.c \
|
||||
../db_test.c ../recGbl.c ../callback.c ../taskwd.c \
|
||||
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c
|
||||
../dbCaLink.c ../dbCaDblink.c ../devLib.c ../initHooks.c ../cvtBpt.c
|
||||
|
||||
OBJSdbLib = \
|
||||
LIBOBJS = \
|
||||
dbAccess.o dbBkpt.o dbFastLinkConv.o dbLink.o dbNotify.o \
|
||||
dbStaticLib.o iocInit.o drvTS.o dbScan.o dbEvent.o dbTest.o dbls.o \
|
||||
db_access.o db_test.o recGbl.o callback.o taskwd.o dbCaLink.o \
|
||||
dbCaDblink.o devLib.o
|
||||
dbCaDblink.o devLib.o cvtBpt.o
|
||||
|
||||
PROD = initHooks.o
|
||||
|
||||
PROD = initHooks.o dbLib
|
||||
LIBNAME = dbLib
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
dbLib: $(OBJSdbLib)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJSdbLib) $(LDLIBS)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ words:
|
||||
else if((p=strstr($2,".PP.NMS"))) {p[0]=' ';p[3]=' ';}
|
||||
else if((p=strstr($2,".NPP.MS"))) {p[0]=' ';p[4]=' ';}
|
||||
else if((p=strstr($2,".NPP.NMS"))) {p[0]=' ';p[4]=' ';}
|
||||
else if(strlen(curr_value)>0) { strcat(curr_value," "); }
|
||||
else if(strlen(curr_value)>(size_t)0) { strcat(curr_value," "); }
|
||||
strcat(curr_value,$2);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* cvtBpt.c - Convert using breakpoint table
|
||||
/* cvtBpt.c - Convert using breakpoint table */
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 9-19-91
|
||||
@@ -94,6 +94,7 @@
|
||||
#include <errMdef.h>
|
||||
#include <recSup.h>
|
||||
#include <special.h>
|
||||
#include <asLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
extern long lset_stack_not_empty;
|
||||
@@ -297,8 +298,6 @@ long dbProcess(struct dbCommon *precord)
|
||||
static char trace=0;
|
||||
static int trace_lset=0;
|
||||
int set_trace=FALSE;
|
||||
long options=0;
|
||||
long nRequest=1;
|
||||
|
||||
/*
|
||||
* Note that it is likely that if any changes are made
|
||||
@@ -377,7 +376,7 @@ long dbProcess(struct dbCommon *precord)
|
||||
/*take care of caching and notifyCompletion*/
|
||||
precord->rpro = FALSE;
|
||||
if (precord->ppn)
|
||||
dbNotifyCompletion(precord->ppn);
|
||||
dbNotifyCompletion(precord);
|
||||
|
||||
/* raise disable alarm */
|
||||
if (precord->stat==DISABLE_ALARM)
|
||||
@@ -681,7 +680,7 @@ long dbFastLinkPut(
|
||||
}
|
||||
}
|
||||
else if (special == SPC_AS) {
|
||||
asChangeGroup(&pdest->asp, pdest->asg);
|
||||
asChangeGroup((ASMEMBERPVT *)&pdest->asp, pdest->asg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
#include <errMdef.h>
|
||||
#include <recSup.h>
|
||||
#include <special.h>
|
||||
#include <asLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
|
||||
@@ -186,6 +187,7 @@ long dbPutField(
|
||||
if((paddr->pfield==(void *)&precord->proc)
|
||||
||(pfldDes->process_passive && precord->scan==0 && dbrType<DBR_PUT_ACKT)) {
|
||||
if(precord->pact) {
|
||||
if(precord->tpro) printf("active: %s\n",precord->name);
|
||||
precord->rpro = TRUE;
|
||||
} else {
|
||||
/*indicate that dbPutField called dbProcess*/
|
||||
@@ -2810,7 +2812,7 @@ void *pflin
|
||||
memset(pbuffer,'\0',dbr_units_size);
|
||||
*options = (*options) ^ DBR_UNITS; /*Turn off DBR_UNITS*/
|
||||
}
|
||||
pbuffer += dbr_units_size;
|
||||
pbuffer = (char *)pbuffer + dbr_units_size;
|
||||
}
|
||||
if( (*options) & DBR_PRECISION ) {
|
||||
struct dbr_precision *pdbr_precision=( struct dbr_precision *)pbuffer;
|
||||
@@ -2823,7 +2825,7 @@ void *pflin
|
||||
memset(pbuffer,'\0',dbr_precision_size);
|
||||
*options = (*options) ^ DBR_PRECISION; /*Turn off DBR_PRECISION*/
|
||||
}
|
||||
pbuffer += dbr_precision_size;
|
||||
pbuffer = (char *)pbuffer + dbr_precision_size;
|
||||
}
|
||||
if( (*options) & DBR_TIME ) {
|
||||
if(pfl!=NULL) {
|
||||
@@ -2961,7 +2963,7 @@ choice_common:
|
||||
*options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
|
||||
break;
|
||||
}
|
||||
*ppbuffer += dbr_enumStrs_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2986,7 +2988,7 @@ static void get_graphics(struct dbAddr *paddr,void **ppbuffer,
|
||||
memset(pbuffer,'\0',dbr_grLong_size);
|
||||
*options = (*options) ^ DBR_GR_LONG; /*Turn off option*/
|
||||
}
|
||||
*ppbuffer += dbr_grLong_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_grLong_size;
|
||||
}
|
||||
if( (*options) & (DBR_GR_DOUBLE) ) {
|
||||
char *pbuffer=*ppbuffer;
|
||||
@@ -2999,7 +3001,7 @@ static void get_graphics(struct dbAddr *paddr,void **ppbuffer,
|
||||
memset(pbuffer,'\0',dbr_grDouble_size);
|
||||
*options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option*/
|
||||
}
|
||||
*ppbuffer += dbr_grDouble_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_grDouble_size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3025,7 +3027,7 @@ static void get_control(struct dbAddr *paddr,void **ppbuffer,
|
||||
memset(pbuffer,'\0',dbr_ctrlLong_size);
|
||||
*options = (*options) ^ DBR_CTRL_LONG; /*Turn off option*/
|
||||
}
|
||||
*ppbuffer += dbr_ctrlLong_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_ctrlLong_size;
|
||||
}
|
||||
if( (*options) & (DBR_CTRL_DOUBLE) ) {
|
||||
char *pbuffer=*ppbuffer;
|
||||
@@ -3038,7 +3040,7 @@ static void get_control(struct dbAddr *paddr,void **ppbuffer,
|
||||
memset(pbuffer,'\0',dbr_ctrlDouble_size);
|
||||
*options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option*/
|
||||
}
|
||||
*ppbuffer += dbr_ctrlDouble_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_ctrlDouble_size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3066,7 +3068,7 @@ static void get_alarm(struct dbAddr *paddr,void **ppbuffer,
|
||||
memset(pbuffer,'\0',dbr_alLong_size);
|
||||
*options = (*options) ^ DBR_AL_LONG; /*Turn off option*/
|
||||
}
|
||||
*ppbuffer += dbr_alLong_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_alLong_size;
|
||||
}
|
||||
if( (*options) & (DBR_AL_DOUBLE) ) {
|
||||
char *pbuffer=*ppbuffer;
|
||||
@@ -3081,7 +3083,7 @@ static void get_alarm(struct dbAddr *paddr,void **ppbuffer,
|
||||
memset(pbuffer,'\0',dbr_alDouble_size);
|
||||
*options = (*options) ^ DBR_AL_DOUBLE; /*Turn off option*/
|
||||
}
|
||||
*ppbuffer += dbr_alDouble_size;
|
||||
*ppbuffer = ((char *)*ppbuffer) + dbr_alDouble_size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3227,19 +3229,21 @@ long no_elements;
|
||||
long offset;
|
||||
{
|
||||
unsigned short *pdest=(unsigned short *)paddr->pfield;
|
||||
unsigned short value;
|
||||
float value;
|
||||
|
||||
/*Convert to float first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned short as float*/
|
||||
if(nRequest==1 && offset==0) {
|
||||
if(sscanf(pbuffer,"%hu",&value) == 1) {
|
||||
*pdest = value;
|
||||
if(sscanf(pbuffer,"%f",&value) == 1) {
|
||||
*pdest = (unsigned short)value;
|
||||
return(0);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(pbuffer,"%hu",&value) == 1) {
|
||||
*pdest = value;
|
||||
if(sscanf(pbuffer,"%f",&value) == 1) {
|
||||
*pdest = (unsigned short)value;
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
@@ -3295,19 +3299,21 @@ long no_elements;
|
||||
long offset;
|
||||
{
|
||||
unsigned long *pdest=(unsigned long *)paddr->pfield;
|
||||
unsigned long value;
|
||||
double value;
|
||||
|
||||
/*Convert to double first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned long as double*/
|
||||
if(nRequest==1 && offset==0) {
|
||||
if(sscanf(pbuffer,"%lu",&value) == 1) {
|
||||
*pdest = value;
|
||||
if(sscanf(pbuffer,"%lf",&value) == 1) {
|
||||
*pdest = (unsigned long)value;
|
||||
return(0);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(pbuffer,"%lu",&value) == 1) {
|
||||
*pdest = value;
|
||||
if(sscanf(pbuffer,"%lf",&value) == 1) {
|
||||
*pdest = (unsigned long)value;
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
@@ -5675,7 +5681,6 @@ long no_elements;
|
||||
long offset;
|
||||
{
|
||||
struct dbCommon *precord=(struct dbCommon *)(paddr->precord);
|
||||
unsigned short acks=precord->acks;
|
||||
|
||||
if(*pbuffer >= precord->acks) {
|
||||
precord->acks = 0;
|
||||
@@ -5831,7 +5836,7 @@ long dbPut(
|
||||
if(special==SPC_SCAN) {
|
||||
scanAdd(precord);
|
||||
} else if(special==SPC_AS) {
|
||||
asChangeGroup(&precord->asp,precord->asg);
|
||||
asChangeGroup((ASMEMBERPVT *)&precord->asp,precord->asg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -35,7 +35,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <taskLib.h>
|
||||
#include <semLib.h>
|
||||
#include <sysLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <fast_lock.h>
|
||||
@@ -45,185 +48,325 @@
|
||||
#include <dbScan.h>
|
||||
#include <dbCommon.h>
|
||||
#include <errMdef.h>
|
||||
#include <ellLib.h>
|
||||
|
||||
/*NODE structure attached to ppnn field of each record in list*/
|
||||
typedef struct {
|
||||
ELLNODE node;
|
||||
struct dbCommon *precord;
|
||||
} PNWAITNODE;
|
||||
|
||||
/*Local routines*/
|
||||
static void restartAdd(PUTNOTIFY *ppnto, PUTNOTIFY *ppnfrom);
|
||||
static void waitAdd(struct dbCommon *precord,PUTNOTIFY *ppn);
|
||||
static long putNotify(PUTNOTIFY *ppn);
|
||||
static void notifyCallback(CALLBACK *pcallback);
|
||||
static void notifyCancel(PUTNOTIFY *ppn);
|
||||
static void issueCallback(PUTNOTIFY *ppn);
|
||||
|
||||
/*callbackState values */
|
||||
typedef enum {
|
||||
callbackNotActive,callbackActive,callbackCanceled}callbackState;
|
||||
|
||||
static void notifyCallback(CALLBACK *pcallback)
|
||||
{
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
long status;
|
||||
/* This module provides code to handle put notify. If a put causes a record to
|
||||
* be processed, then a user supplied callback is called when that record
|
||||
* and all records processed because of that record complete processing.
|
||||
* For asynchronous records completion means completion of the asyn phase.
|
||||
*
|
||||
* User code calls dbPutNotify and dbNotifyCancel.
|
||||
*
|
||||
* The other global routines (dbNotifyAdd and dbNotifyCompletion) are called by:
|
||||
*
|
||||
* dbAccess.c
|
||||
* dbScanPassive and dbScanLink
|
||||
* call dbNotifyAdd just before calling dbProcess
|
||||
* dbProcess
|
||||
* Calls dbNotifyCompletion if record is disabled.
|
||||
* recGbl
|
||||
* recGblFwdLink calls dbNotifyCompletion
|
||||
*/
|
||||
|
||||
callbackGetUser(ppn,pcallback);
|
||||
if(ppn->cmd==notifyCmdRepeat) {
|
||||
status = dbPutNotify(ppn);
|
||||
} else if(ppn->cmd==notifyCmdCallUser) {
|
||||
ppn->cmd = notifyUserCalled;
|
||||
(ppn->userCallback)(ppn);
|
||||
} else {/*illegal request*/
|
||||
recGblRecordError(-1,ppn->paddr->precord,
|
||||
"dbNotifyCompletion: illegal callback request");
|
||||
}
|
||||
}
|
||||
|
||||
static void notifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
|
||||
while(precord) {
|
||||
void *pnext;
|
||||
|
||||
if(precord->rpro) {
|
||||
precord->rpro = FALSE;
|
||||
scanOnce(precord);
|
||||
}
|
||||
precord->ppn = NULL;
|
||||
pnext = precord->ppnn;
|
||||
precord->ppnn = NULL;
|
||||
precord = pnext;
|
||||
}
|
||||
ppn->list = NULL;
|
||||
}
|
||||
|
||||
void dbNotifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
|
||||
if(!precord) return;
|
||||
dbScanLock(precord);
|
||||
notifyCancel(ppn);
|
||||
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
|
||||
/*Bad lets try one time to wait*/
|
||||
dbScanUnlock(precord);
|
||||
taskDelay(10);
|
||||
dbScanLock(precord);
|
||||
}
|
||||
if(ppn->cmd!=notifyCmdNull && ppn->cmd!=notifyUserCalled) {
|
||||
epicsPrintf("dbNotifyCancel called while callback requested"
|
||||
" but not called\n");
|
||||
}
|
||||
dbScanUnlock(precord);
|
||||
}
|
||||
|
||||
static void issueCallback(PUTNOTIFY *ppn, notifyCmd cmd)
|
||||
{
|
||||
if(ppn->cmd!=notifyCmdNull) return;
|
||||
ppn->cmd = cmd;
|
||||
notifyCancel(ppn);
|
||||
callbackRequest(&ppn->callback);
|
||||
}
|
||||
/* Two fields in dbCommon are used for put notify.
|
||||
* ppn
|
||||
* If a record is part of a put notify group,
|
||||
* This field is tha address of the associated PUTNOTIFY.
|
||||
* As soon as a record completes processing the field is set NULL
|
||||
* ppnn
|
||||
* Address of an PNWAITNODE for keeping list of records in a
|
||||
* put notify group. Once an PNWAITNODE is allocated for a record,
|
||||
* it is never freed under the assumption that once a record
|
||||
* becomes part of a put notify group it is likely to become
|
||||
* one again in the future.
|
||||
*/
|
||||
|
||||
static void restartAdd(PUTNOTIFY *ppnto, PUTNOTIFY *ppnfrom)
|
||||
{
|
||||
ppnfrom->restartNode.ppn = ppnfrom;
|
||||
ppnfrom->restartNode.ppnrestartList = ppnto;
|
||||
ppnfrom->restart = TRUE;
|
||||
ellAdd(&ppnto->restartList,&ppnfrom->restartNode.node);
|
||||
}
|
||||
|
||||
static void waitAdd(struct dbCommon *precord,PUTNOTIFY *ppn)
|
||||
{
|
||||
PNWAITNODE *ppnnode;
|
||||
|
||||
if(!precord->ppnn) precord->ppnn = dbCalloc(1,sizeof(PNWAITNODE));
|
||||
ppnnode = (PNWAITNODE *)precord->ppnn;
|
||||
ppnnode->precord = precord;
|
||||
precord->ppn = ppn;
|
||||
ellAdd(&ppn->waitList,&ppnnode->node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
long dbPutNotify(PUTNOTIFY *ppn)
|
||||
{
|
||||
long status;
|
||||
struct dbCommon *precord = ppn->paddr->precord;
|
||||
|
||||
dbScanLock(precord);
|
||||
ellInit(&ppn->restartList);
|
||||
memset(&ppn->restartNode,'\0',sizeof(PNRESTARTNODE));
|
||||
status = putNotify(ppn);
|
||||
dbScanUnlock(precord);
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long putNotify(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbAddr *paddr = ppn->paddr;
|
||||
short dbrType = ppn->dbrType;
|
||||
void *pbuffer = ppn->pbuffer;
|
||||
long nRequest = ppn->nRequest;
|
||||
long status=0;
|
||||
short dbrType = ppn->dbrType;
|
||||
void *pbuffer = ppn->pbuffer;
|
||||
long nRequest = ppn->nRequest;
|
||||
long status=0;
|
||||
struct fldDes *pfldDes=(struct fldDes *)(paddr->pfldDes);
|
||||
struct dbCommon *precord = (struct dbCommon *)(paddr->precord);
|
||||
|
||||
if(precord->ppn == ppn) {
|
||||
return(S_db_Blocked);
|
||||
}
|
||||
/*Initialize everything in PUTNOTIFY except restart list and node*/
|
||||
callbackSetCallback(notifyCallback,&ppn->callback);
|
||||
callbackSetUser(ppn,&ppn->callback);
|
||||
callbackSetPriority(priorityLow,&ppn->callback);
|
||||
ppn->status = 0;
|
||||
ppn->restart = FALSE;
|
||||
ppn->callbackState = callbackNotActive;
|
||||
ellInit(&ppn->waitList);
|
||||
/*check for putField disabled*/
|
||||
if(precord->disp) {
|
||||
if((void *)(&precord->disp) != paddr->pfield) {
|
||||
ppn->status = S_db_putDisabled;
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
return(S_db_putDisabled);
|
||||
issueCallback(ppn);
|
||||
goto ret_pending;
|
||||
}
|
||||
}
|
||||
ppn->status = 0;
|
||||
ppn->cmd = notifyCmdNull;
|
||||
ppn->nwaiting = 1;
|
||||
ppn->rescan = FALSE;
|
||||
dbScanLock(precord);
|
||||
if(precord->ppn) {/*Another put notify is in progress*/
|
||||
restartAdd(precord->ppn,ppn);
|
||||
goto ret_pending;
|
||||
}
|
||||
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
|
||||
precord->ppn = ppn;
|
||||
waitAdd(precord,ppn);
|
||||
restartAdd(precord->ppn,ppn);
|
||||
goto ret_pending;
|
||||
}
|
||||
status=dbPut(paddr,dbrType,pbuffer,nRequest);
|
||||
ppn->status = status;
|
||||
if(status==0){
|
||||
if((paddr->pfield==(void *)&precord->proc)
|
||||
||(pfldDes->process_passive && precord->scan==0)) {
|
||||
if(precord->ppn) {
|
||||
/*record already has attached ppn. Blocked*/
|
||||
|
||||
ppn->status = status = S_db_Blocked;
|
||||
dbScanUnlock(precord);
|
||||
return(status);
|
||||
}
|
||||
precord->ppn = ppn;
|
||||
precord->ppnn = NULL;
|
||||
ppn->list = precord;
|
||||
if(precord->pact) {/*blocked wait for dbNotifyCompletion*/
|
||||
ppn->rescan = TRUE;
|
||||
dbScanUnlock(precord);
|
||||
return(S_db_Pending);
|
||||
}
|
||||
status=dbProcess(precord);
|
||||
if(status!=0) {
|
||||
ppn->status = status;
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
}
|
||||
} else { /*Make callback immediately*/
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
}
|
||||
if(status) {
|
||||
ppn->status = status;
|
||||
issueCallback(ppn);
|
||||
goto ret_pending;
|
||||
}
|
||||
/*check for no processing required*/
|
||||
if(!(paddr->pfield==(void *)&precord->proc)
|
||||
&& (!pfldDes->process_passive || precord->scan!=0)) {
|
||||
issueCallback(ppn);
|
||||
goto ret_pending;
|
||||
}
|
||||
dbScanUnlock(precord);
|
||||
/*Add record to waitlist*/
|
||||
waitAdd(precord,ppn);
|
||||
status=dbProcess(precord);
|
||||
if(status!=0) {
|
||||
ppn->status = status;
|
||||
issueCallback(ppn);
|
||||
}
|
||||
ret_pending:
|
||||
return(S_db_Pending);
|
||||
}
|
||||
|
||||
void dbNotifyCompletion(PUTNOTIFY *ppn)
|
||||
static void notifyCallback(CALLBACK *pcallback)
|
||||
{
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
struct dbCommon *precord;
|
||||
|
||||
if(ppn->status!=0) {
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
callbackGetUser(ppn,pcallback);
|
||||
precord = ppn->paddr->precord;
|
||||
dbScanLock(precord);
|
||||
if(ppn->callbackState==callbackCanceled) {
|
||||
dbScanUnlock(precord);
|
||||
ppn->restart = FALSE;
|
||||
ppn->callbackState = callbackNotActive;
|
||||
semGive((SEM_ID)ppn->waitForCallback);
|
||||
return;
|
||||
}
|
||||
/*decrement number of records being waited on*/
|
||||
if(ppn->nwaiting<=0) {
|
||||
recGblRecordError(-1,ppn->paddr->precord,"dbNotifyCompletion: nwaiting<-0 LOGIC");
|
||||
return;
|
||||
}
|
||||
if(--ppn->nwaiting == 0) {/*original request completed*/
|
||||
if(ppn->rescan) {
|
||||
issueCallback(ppn,notifyCmdRepeat);
|
||||
if(ppn->callbackState==callbackActive) {
|
||||
if(ppn->restart) {
|
||||
putNotify(ppn);
|
||||
dbScanUnlock(precord);
|
||||
} else {
|
||||
issueCallback(ppn,notifyCmdCallUser);
|
||||
dbScanUnlock(precord);
|
||||
(ppn->userCallback)(ppn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Remove all nonactive records from put notify list*/
|
||||
void cleanPpList(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->list;
|
||||
struct dbCommon *pnext;
|
||||
struct dbCommon *pprev=NULL;
|
||||
|
||||
while(precord) {
|
||||
pnext = precord->ppnn;
|
||||
if(!precord->pact) {
|
||||
if(!pprev) ppn->list = pnext; else pprev->ppnn = pnext;
|
||||
precord->ppn = NULL;
|
||||
precord->ppnn = NULL;
|
||||
} else {
|
||||
pprev = precord;
|
||||
static void issueCallback(PUTNOTIFY *ppn)
|
||||
{
|
||||
notifyCancel(ppn);
|
||||
ppn->callbackState = callbackActive;
|
||||
callbackRequest(&ppn->callback);
|
||||
}
|
||||
|
||||
void dbNotifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
struct dbCommon *precord = ppn->paddr->precord;;
|
||||
|
||||
dbScanLock(precord);
|
||||
notifyCancel(ppn);
|
||||
if(ppn->callbackState == callbackActive) {
|
||||
ppn->waitForCallback = (void *)semBCreate(SEM_Q_FIFO,SEM_FULL);
|
||||
ppn->callbackState = callbackCanceled;
|
||||
dbScanUnlock(precord);
|
||||
if(semTake((SEM_ID)ppn->waitForCallback,sysClkRateGet()*10)!=OK) {
|
||||
errMessage(0,"dbNotifyCancel had semTake timeout");
|
||||
ppn->callbackState = callbackNotActive;
|
||||
}
|
||||
precord = pnext;
|
||||
semDelete((SEM_ID)ppn->waitForCallback);
|
||||
} else {
|
||||
dbScanUnlock(precord);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void notifyCancel(PUTNOTIFY *ppn)
|
||||
{
|
||||
PNWAITNODE *ppnnode;
|
||||
struct dbCommon *precord;
|
||||
PNRESTARTNODE *pfirst;
|
||||
|
||||
/*Remove everything on waitList*/
|
||||
while(ppnnode = (PNWAITNODE *)ellLast(&ppn->waitList)) {
|
||||
precord = ppnnode->precord;
|
||||
precord->ppn = NULL;
|
||||
ellDelete(&ppn->waitList,&ppnnode->node);
|
||||
}
|
||||
/*If on restartList remove it*/
|
||||
if(ppn->restartNode.ppnrestartList)
|
||||
ellDelete(&ppn->restartNode.ppnrestartList->restartList,
|
||||
&ppn->restartNode.node);
|
||||
/*If this ppn has a restartList move it */
|
||||
if(pfirst = (PNRESTARTNODE *)ellFirst(&ppn->restartList)) {
|
||||
PNRESTARTNODE *pnext;
|
||||
PUTNOTIFY *pfirstppn;
|
||||
|
||||
pfirstppn = pfirst->ppn;
|
||||
ellConcat(&pfirstppn->restartList,&ppn->restartList);
|
||||
pnext = (PNRESTARTNODE *)ellFirst(&pfirstppn->restartList);
|
||||
while(pnext) {
|
||||
pnext->ppnrestartList = pfirstppn;
|
||||
pnext = (PNRESTARTNODE *)ellNext(&pnext->node);
|
||||
}
|
||||
pfirstppn->restart = TRUE;
|
||||
pfirstppn->callbackState = callbackActive;
|
||||
callbackRequest(&pfirstppn->callback);
|
||||
}
|
||||
memset(&ppn->restartNode,'\0',sizeof(PNRESTARTNODE));
|
||||
}
|
||||
|
||||
void dbNotifyCompletion(struct dbCommon *precord)
|
||||
{
|
||||
PUTNOTIFY *ppn = (PUTNOTIFY *)precord->ppn;
|
||||
PNWAITNODE *ppnnode = (PNWAITNODE *)precord->ppnn;;
|
||||
|
||||
ellDelete(&ppn->waitList,&ppnnode->node);
|
||||
precord->ppn = NULL;
|
||||
if((ppn->status!=0) || (ellCount(&ppn->waitList)==0))
|
||||
issueCallback(ppn);
|
||||
}
|
||||
|
||||
void dbNotifyAdd(struct dbCommon *pfrom, struct dbCommon *pto)
|
||||
{
|
||||
PUTNOTIFY *ppn = pfrom->ppn;
|
||||
PUTNOTIFY *pfromppn = (PUTNOTIFY *)pfrom->ppn;
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
|
||||
if(pto->ppn) cleanPpList(pto->ppn); /* clean list before giving up*/
|
||||
if(pto->ppn == pfrom->ppn) return; /*Aready in same set*/
|
||||
if (pto->ppn) { /*already being used. Abandon request*/
|
||||
ppn->status = S_db_Blocked;
|
||||
dbNotifyCompletion(ppn);
|
||||
notifyCancel(pfrom->ppn);
|
||||
restartAdd(pto->ppn,pfromppn);
|
||||
return;
|
||||
} else {
|
||||
ppn->nwaiting++;
|
||||
pto->ppn = pfrom->ppn;
|
||||
pto->ppnn = ppn->list;
|
||||
ppn->list = pto;
|
||||
/*If already active must redo*/
|
||||
if(pto->pact) ppn->rescan = TRUE;
|
||||
/*If already active must redo*/
|
||||
if(pto->pact) {
|
||||
ppn = pfrom->ppn;
|
||||
notifyCancel(pfrom->ppn);
|
||||
waitAdd(pto,ppn);
|
||||
restartAdd(pto->ppn,ppn);
|
||||
} else {
|
||||
waitAdd(pto,pfrom->ppn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dbtpnCallback(PUTNOTIFY *ppn)
|
||||
{
|
||||
DBADDR *pdbaddr = ppn->paddr;
|
||||
long status = ppn->status;
|
||||
|
||||
if(status==S_db_Blocked)
|
||||
printf("dbtpnCallback: blocked record=%s\n",ppn->paddr->precord->name);
|
||||
else if(status==0)
|
||||
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord->name);
|
||||
else
|
||||
recGblRecordError(status,pdbaddr->precord,"dbtpnCallback");
|
||||
free((void *)pdbaddr);
|
||||
free(ppn);
|
||||
}
|
||||
|
||||
long dbtpn(char *pname,char *pvalue)
|
||||
{
|
||||
long status;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
char *psavevalue;
|
||||
int len;
|
||||
|
||||
len = strlen(pvalue);
|
||||
/*allocate space for value immediately following DBADDR*/
|
||||
pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1);
|
||||
psavevalue = (char *)(pdbaddr + 1);
|
||||
strcpy(psavevalue,pvalue);
|
||||
status = dbNameToAddr(pname,pdbaddr);
|
||||
if(status) {
|
||||
errMessage(status, "dbtpn: dbNameToAddr");
|
||||
free((void *)pdbaddr);
|
||||
return(-1);
|
||||
}
|
||||
ppn = dbCalloc(1,sizeof(PUTNOTIFY));
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->pbuffer = psavevalue;
|
||||
ppn->nRequest = 1;
|
||||
ppn->dbrType = DBR_STRING;
|
||||
ppn->userCallback = dbtpnCallback;
|
||||
status = dbPutNotify(ppn);
|
||||
if(status==S_db_Pending) {
|
||||
printf("dbtpn: Pending nwaiting=%d\n",ellCount(&ppn->waitList));
|
||||
return(0);
|
||||
}
|
||||
if(status==S_db_Blocked) {
|
||||
printf("dbtpn: blocked record=%s\n",pname);
|
||||
} else if(status) {
|
||||
errMessage(status, "dbtpn");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
#include <dbStaticLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
extern volatile int interruptAccept;
|
||||
|
||||
/* SCAN ONCE */
|
||||
#define ONCE_QUEUE_SIZE 256
|
||||
@@ -146,7 +145,7 @@ long scanInit()
|
||||
void post_event(int event)
|
||||
{
|
||||
unsigned char evnt;
|
||||
int status;
|
||||
static int newOverflow=TRUE;
|
||||
|
||||
if (!interruptAccept) return; /* not awake yet */
|
||||
if(event<0 || event>=MAX_EVENTS) {
|
||||
@@ -156,14 +155,13 @@ void post_event(int event)
|
||||
evnt = (unsigned)event;
|
||||
/*multiple writers can exist. Thus if evnt is ever changed to use*/
|
||||
/*something bigger than a character interrupts will have to be blocked*/
|
||||
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))!=sizeof(unsigned char))
|
||||
errMessage(0,"rngBufPut overflow in post_event");
|
||||
if((status=semGive(eventSem))!=OK){
|
||||
/*semGive randomly returns garbage value*/
|
||||
/*
|
||||
errMessage(0,"semGive returned error in post_event");
|
||||
*/
|
||||
}
|
||||
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))!=sizeof(unsigned char)) {
|
||||
if(newOverflow) errMessage(0,"rngBufPut overflow in post_event");
|
||||
newOverflow = FALSE;
|
||||
} else {
|
||||
newOverflow = TRUE;
|
||||
}
|
||||
semGive(eventSem);
|
||||
}
|
||||
|
||||
|
||||
@@ -382,8 +380,14 @@ void scanIoRequest(IOSCANPVT pioscanpvt)
|
||||
|
||||
void scanOnce(void *precord)
|
||||
{
|
||||
if(rngBufPut(onceQ,(void *)&precord,sizeof(precord))!=sizeof(precord))
|
||||
errMessage(0,"rngBufPut overflow in scanOnce");
|
||||
static int newOverflow=TRUE;
|
||||
|
||||
if(rngBufPut(onceQ,(void *)&precord,sizeof(precord))!=sizeof(precord)) {
|
||||
if(newOverflow)errMessage(0,"rngBufPut overflow in scanOnce");
|
||||
newOverflow = FALSE;
|
||||
}else {
|
||||
newOverflow = TRUE;
|
||||
}
|
||||
semGive(onceSem);
|
||||
}
|
||||
|
||||
@@ -598,7 +602,7 @@ static void printList(struct scan_list *psl,char *message)
|
||||
struct scan_element *pse;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
(void *)pse = ellFirst(&psl->list);
|
||||
pse = (struct scan_element *)ellFirst(&psl->list);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
if(pse==NULL) return;
|
||||
printf("%s\n",message);
|
||||
@@ -610,7 +614,7 @@ static void printList(struct scan_list *psl,char *message)
|
||||
printf("Returning because list changed while processing.");
|
||||
return;
|
||||
}
|
||||
(void *)pse = ellNext((void *)pse);
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
}
|
||||
}
|
||||
@@ -624,9 +628,9 @@ static void scanList(struct scan_list *psl)
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
psl->modified = FALSE;
|
||||
(void *)pse = ellFirst(&psl->list);
|
||||
pse = (struct scan_element *)ellFirst(&psl->list);
|
||||
prev = NULL;
|
||||
(void *)next = ellNext((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
while(pse!=NULL) {
|
||||
struct dbCommon *precord = pse->precord;
|
||||
@@ -637,27 +641,27 @@ static void scanList(struct scan_list *psl)
|
||||
FASTLOCK(&psl->lock);
|
||||
if(!psl->modified) {
|
||||
prev = pse;
|
||||
(void *)pse = ellNext((void *)pse);
|
||||
if(pse!=NULL) (void *)next = ellNext((void *)pse);
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
|
||||
} else if (pse->pscan_list==psl) {
|
||||
/*This scan element is still in same scan list*/
|
||||
prev = pse;
|
||||
(void *)pse = ellNext((void *)pse);
|
||||
if(pse!=NULL) (void *)next = ellNext((void *)pse);
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else if (prev!=NULL && prev->pscan_list==psl) {
|
||||
/*Previous scan element is still in same scan list*/
|
||||
(void *)pse = ellNext((void *)prev);
|
||||
pse = (struct scan_element *)ellNext((void *)prev);
|
||||
if(pse!=NULL) {
|
||||
(void *)prev = ellPrevious((void *)pse);
|
||||
(void *)next = ellNext((void *)pse);
|
||||
prev = (struct scan_element *)ellPrevious((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
}
|
||||
psl->modified = FALSE;
|
||||
} else if (next!=NULL && next->pscan_list==psl) {
|
||||
/*Next scan element is still in same scan list*/
|
||||
pse = next;
|
||||
(void *)prev = ellPrevious((void *)pse);
|
||||
(void *)next = ellNext((void *)pse);
|
||||
prev = (struct scan_element *)ellPrevious((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else {
|
||||
/*Too many changes. Just wait till next period*/
|
||||
@@ -703,17 +707,17 @@ static void addToList(struct dbCommon *precord,struct scan_list *psl)
|
||||
if(pse==NULL) {
|
||||
pse = dbCalloc(1,sizeof(struct scan_element));
|
||||
precord->spvt = (void *)pse;
|
||||
(void *)pse->precord = precord;
|
||||
pse->precord = precord;
|
||||
}
|
||||
pse ->pscan_list = psl;
|
||||
(void *)ptemp = ellFirst(&psl->list);
|
||||
ptemp = (struct scan_element *)ellFirst(&psl->list);
|
||||
while(ptemp!=NULL) {
|
||||
if(ptemp->precord->phas>precord->phas) {
|
||||
ellInsert(&psl->list,
|
||||
ellPrevious((void *)ptemp),(void *)pse);
|
||||
break;
|
||||
}
|
||||
(void *)ptemp = ellNext((void *)ptemp);
|
||||
ptemp = (struct scan_element *)ellNext((void *)ptemp);
|
||||
}
|
||||
if(ptemp==NULL) ellAdd(&psl->list,(void *)pse);
|
||||
psl->modified = TRUE;
|
||||
|
||||
@@ -57,6 +57,15 @@
|
||||
|
||||
#define messagesize 100
|
||||
#define RPCL_LEN 184
|
||||
|
||||
#if defined(EPICS_LITTLE_ENDIAN)
|
||||
#define BYTE_SWAP_4(A) \
|
||||
( (((A) & 0xFF) << 24 ) | \
|
||||
(((A) & 0xFF00) << 8) | \
|
||||
(((A) & 0xFF0000) >> 8) | \
|
||||
(((A) & 0xFF000000) >> 24) )
|
||||
#endif
|
||||
|
||||
long postfix(char *pinfix, char *ppostfix,short *perror);
|
||||
|
||||
static char *ppstring[2]={"NPP","PP"};
|
||||
@@ -740,7 +749,7 @@ char *precordName;
|
||||
struct recLoc *precLoc = NULL;
|
||||
short rec_size;
|
||||
|
||||
if(strlen(precordName)>PVNAME_SZ) return(S_dbLib_nameLength);
|
||||
if(strlen(precordName)>(size_t)PVNAME_SZ) return(S_dbLib_nameLength);
|
||||
/* clear callers entry */
|
||||
zeroDbentry(pdbentry);
|
||||
if(!dbFindRecord(pdbentry,precordName)) return (S_dbLib_recExists);
|
||||
@@ -938,7 +947,7 @@ char *newName;
|
||||
long status;
|
||||
DBENTRY dbentry;
|
||||
|
||||
if(strlen(newName)>PVNAME_SZ) return(S_dbLib_nameLength);
|
||||
if(strlen(newName)>(size_t)PVNAME_SZ) return(S_dbLib_nameLength);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
dbInitEntry(pdbentry->pdbbase,&dbentry);
|
||||
status = dbFindRecord(&dbentry,newName);
|
||||
@@ -1008,15 +1017,23 @@ char *pfieldName;
|
||||
bottom = 0;
|
||||
test = (top + bottom) / 2;
|
||||
while (1) {
|
||||
unsigned int t1, t2;
|
||||
|
||||
/* check the field name */
|
||||
if (sortFldName[test] == *(unsigned long *) pconvName) {
|
||||
t1 = (unsigned int) sortFldName[ test];
|
||||
t2 = (unsigned int) *(unsigned int*)pconvName;
|
||||
#if defined(EPICS_LITTLE_ENDIAN)
|
||||
t1 = BYTE_SWAP_4( t1);
|
||||
t2 = BYTE_SWAP_4( t2);
|
||||
#endif
|
||||
if(t1 == t2) {
|
||||
if(!(pflddes=GET_PFLDDES(precTypDes,sortFldInd[test])))
|
||||
return(S_dbLib_recdesNotFound);
|
||||
pdbentry->pflddes = pflddes;
|
||||
pdbentry->pfield = precord + pflddes->offset;
|
||||
pdbentry->indfield = sortFldInd[test];
|
||||
return (0);
|
||||
} else if (sortFldName[test] > *(unsigned long *) pconvName) {
|
||||
} else if (t1 > t2) {
|
||||
top = test - 1;
|
||||
if (top < bottom) return (S_dbLib_fieldNotFound);
|
||||
test = (top + bottom) / 2;
|
||||
@@ -1591,7 +1608,7 @@ char *pstring;
|
||||
if (!(pchoice = pdevChoiceSet->papDevChoice[i]->pchoice))
|
||||
continue;
|
||||
if (strcmp(pchoice, pstring) == 0) {
|
||||
long link_type,status;
|
||||
long link_type;
|
||||
|
||||
link_type = pdevChoiceSet->papDevChoice[i]->link_type;
|
||||
/*If no INP or OUT OK */
|
||||
@@ -1623,7 +1640,7 @@ char *pstring;
|
||||
if(pstr[ind]!=' ' && pstr[ind]!='\t') break;
|
||||
pstr[ind] = '\0';
|
||||
}
|
||||
if(!pstr || strlen(pstr)<=0 ) {
|
||||
if(!pstr || strlen(pstr)==0 ) {
|
||||
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
|
||||
if(plink->type!=CONSTANT) return(S_dbLib_badField);
|
||||
return(0);
|
||||
@@ -1689,12 +1706,18 @@ char *pstring;
|
||||
if(!(end = strchr(pstr,'N'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.camacio.n);
|
||||
if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.camacio.a);
|
||||
if(!(end = strchr(pstr,'F'))) return (S_dbLib_badField);
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.camacio.f);
|
||||
if(!(end = strchr(pstr,'A'))) {
|
||||
plink->value.camacio.a = 0;
|
||||
} else {
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.camacio.a);
|
||||
}
|
||||
if(!(end = strchr(pstr,'F'))) {
|
||||
plink->value.camacio.f = 0;
|
||||
} else {
|
||||
pstr = end + 1;
|
||||
sscanf(pstr,"%hd",&plink->value.camacio.f);
|
||||
}
|
||||
plink->value.camacio.parm[0] = 0;
|
||||
if(end = strchr(pstr,'@')) {
|
||||
pstr = end + 1;
|
||||
@@ -4127,16 +4150,29 @@ FILE *fp;
|
||||
}
|
||||
|
||||
/* Beginning of Process Variable Directory Routines*/
|
||||
#define HASH_NO 512 /* number of hash table entries */
|
||||
|
||||
|
||||
int dbPvdHashTableSize = 512;
|
||||
static int dbPvdHashTableShift;
|
||||
#define NTABLESIZES 9
|
||||
static struct {
|
||||
unsigned int tablesize;
|
||||
int shift;
|
||||
}hashTableParms[9] = {
|
||||
{256,0},
|
||||
{512,1},
|
||||
{1024,2},
|
||||
{2048,3},
|
||||
{4096,4},
|
||||
{8192,5},
|
||||
{16384,6},
|
||||
{32768,7},
|
||||
{65536,8}
|
||||
};
|
||||
/*The hash algorithm is a modification of the algorithm described in */
|
||||
/* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */
|
||||
/* Communications of the ACM, June 1990 */
|
||||
/* The modifications were desdigned by Marty Kraimer and Ben Chin Cha */
|
||||
/* The mods were implemented and tested by Ben Chin Cha */
|
||||
/* The modifications were designed by Marty Kraimer */
|
||||
|
||||
static unsigned char T0[256] = {
|
||||
static unsigned char T[256] = {
|
||||
39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69,
|
||||
157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160,
|
||||
176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77,
|
||||
@@ -4155,45 +4191,24 @@ static unsigned char T0[256] = {
|
||||
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47
|
||||
};
|
||||
|
||||
static unsigned char T1[256] = {
|
||||
9,139,209, 40, 31,202, 58,179,116, 33,207,146, 76, 60,242,124,
|
||||
254,197, 80,167,153,145,129,233,132, 48,246, 86,156,177, 36,187,
|
||||
45, 1, 96, 18, 19, 62,185,234, 99, 16,218, 95,128,224,123,253,
|
||||
42,109, 4,247, 72, 5,151,136, 0,152,148,127,204,133, 17, 14,
|
||||
182,217, 54,199,119,174, 82, 57,215, 41,114,208,206,110,239, 23,
|
||||
189, 15, 3, 22,188, 79,113,172, 28, 2,222, 21,251,225,237,105,
|
||||
102, 32, 56,181,126, 83,230, 53,158, 52, 59,213,118,100, 67,142,
|
||||
220,170,144,115,205, 26,125,168,249, 66,175, 97,255, 92,229, 91,
|
||||
214,236,178,243, 46, 44,201,250,135,186,150,221,163,216,162, 43,
|
||||
11,101, 34, 37,194, 25, 50, 12, 87,198,173,240,193,171,143,231,
|
||||
111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238,
|
||||
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47,
|
||||
39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69,
|
||||
157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160,
|
||||
176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77,
|
||||
75,107,169,138,195,184, 70, 90, 61,166, 7,244,165,108,219, 51,
|
||||
};
|
||||
|
||||
#ifdef __STDC__
|
||||
static unsigned short hash( char *pname, int length)
|
||||
#else
|
||||
static unsigned short hash( pname, length)
|
||||
char *pname;
|
||||
int length;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
unsigned short h=0;
|
||||
unsigned short hret;
|
||||
unsigned char *h0=(unsigned char *)&h;
|
||||
unsigned char *h1= h0 + 1;
|
||||
unsigned char h0=0;
|
||||
unsigned char h1=0;
|
||||
unsigned short ind0,ind1;
|
||||
int even = TRUE;
|
||||
unsigned char c;
|
||||
int i;
|
||||
|
||||
for(i=0; i<length; i+=2, pname+=2) {
|
||||
*h0 = T0[*h0 ^ *pname];
|
||||
*h1 = T1[*h1 ^ *(pname+1)];
|
||||
for(i=0; i<length; i++, pname++) {
|
||||
c = *pname;
|
||||
if(even) {h0 = T[h0^c]; even = FALSE;}
|
||||
else {h1 = T[h1^c]; even = TRUE;}
|
||||
}
|
||||
hret = *h0;
|
||||
return(hret + *h1);
|
||||
ind0 = (unsigned short)h0;
|
||||
ind1 = (unsigned short)h1;
|
||||
return((ind1<<dbPvdHashTableShift) ^ ind0);
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
@@ -4203,9 +4218,19 @@ void dbPvdInitPvt(pdbbase)
|
||||
DBBASE *pdbbase;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
ELLLIST **ppvd;
|
||||
ELLLIST **ppvd;
|
||||
int i;
|
||||
|
||||
ppvd = dbCalloc(HASH_NO, sizeof(ELLLIST *));
|
||||
for(i=0; i< NTABLESIZES; i++) {
|
||||
if((i==NTABLESIZES-1)
|
||||
||((dbPvdHashTableSize>=hashTableParms[i].tablesize)
|
||||
&& (dbPvdHashTableSize<hashTableParms[i+1].tablesize))) {
|
||||
dbPvdHashTableSize = hashTableParms[i].tablesize;
|
||||
dbPvdHashTableShift = hashTableParms[i].shift;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ppvd = dbCalloc(dbPvdHashTableSize, sizeof(ELLLIST *));
|
||||
pdbbase->ppvd = (void *) ppvd;
|
||||
return;
|
||||
}
|
||||
@@ -4315,7 +4340,7 @@ DBBASE *pdbbase;
|
||||
PVDENTRY *next;
|
||||
|
||||
if (ppvd == NULL) return;
|
||||
for (hashInd=0; hashInd<HASH_NO; hashInd++) {
|
||||
for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) {
|
||||
if(ppvd[hashInd] == NULL) continue;
|
||||
ppvdlist=ppvd[hashInd];
|
||||
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
|
||||
@@ -4331,10 +4356,11 @@ DBBASE *pdbbase;
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
void dbPvdDump(DBBASE *pdbbase)
|
||||
void dbPvdDump(DBBASE *pdbbase,int verbose)
|
||||
#else
|
||||
void dbPvdDump(pdbbase)
|
||||
void dbPvdDump(pdbbase,verbose)
|
||||
DBBASE *pdbbase;
|
||||
int verbose;
|
||||
#endif /*__STDC__*/
|
||||
{
|
||||
unsigned short hashInd;
|
||||
@@ -4344,14 +4370,16 @@ DBBASE *pdbbase;
|
||||
int number;
|
||||
|
||||
if (ppvd == NULL) return;
|
||||
printf("Process Variable Directory\n");
|
||||
for (hashInd=0; hashInd<HASH_NO; hashInd++) {
|
||||
printf("Process Variable Directory ");
|
||||
printf("dbPvdHashTableSize %d dbPvdHashTableShift %d\n",
|
||||
dbPvdHashTableSize,dbPvdHashTableShift);
|
||||
for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) {
|
||||
if(ppvd[hashInd] == NULL) continue;
|
||||
ppvdlist=ppvd[hashInd];
|
||||
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
|
||||
printf(" %3.3hd=%3.3d\n",hashInd,ellCount(ppvdlist));
|
||||
printf("\n%3.3hd=%3.3d ",hashInd,ellCount(ppvdlist));
|
||||
number=0;
|
||||
while(ppvdNode) {
|
||||
while(ppvdNode && verbose) {
|
||||
printf(" %s",(char *)ppvdNode->precnode->precord);
|
||||
if(number++ ==2) {number=0;printf("\n ");}
|
||||
ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode);
|
||||
|
||||
154
src/db/dbTest.c
154
src/db/dbTest.c
@@ -40,6 +40,7 @@
|
||||
* .09 09-24-93 jbk adjusted dbpr to print vxi links correctly
|
||||
* .10 02-02-94 mrk added dbtpn (test dbPutNotify)
|
||||
* .11 03-18-94 mcn added dbgrep and timing routines.
|
||||
* .12 08-14-95 mrk Moved dbtpn to dbNotify
|
||||
*/
|
||||
|
||||
/* Global Database Test Routines - All can be invoked via vxWorks shell
|
||||
@@ -76,10 +77,6 @@
|
||||
* char *pname;
|
||||
* char *pvalue
|
||||
*
|
||||
* dbtpn(pname,pvalue) test put notify
|
||||
* char *pname;
|
||||
* char *pvalue
|
||||
*
|
||||
* dbior(pname,type) io_report
|
||||
* char *pname Driver name. If null all drivers
|
||||
* int type <0,1> => <short, full> report
|
||||
@@ -292,8 +289,6 @@ long dbgrep(char *pmask)
|
||||
int rectype, beg, end;
|
||||
struct recLoc *precLoc;
|
||||
struct dbCommon *precord;
|
||||
char *pstr;
|
||||
char name[PVNAME_SZ+1];
|
||||
struct recType *precType;
|
||||
struct recHeader *precHeader;
|
||||
RECNODE *precNode;
|
||||
@@ -699,59 +694,6 @@ long dbtpf(char *pname,char *pvalue)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void dbtpnCallback(PUTNOTIFY *ppn)
|
||||
{
|
||||
DBADDR *pdbaddr = ppn->paddr;
|
||||
long status = ppn->status;
|
||||
|
||||
if(status==S_db_Blocked)
|
||||
printf("dbtpnCallback: blocked record=%s\n",ppn->paddr->precord);
|
||||
else if(status==0)
|
||||
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord);
|
||||
else
|
||||
recGblRecordError(status,pdbaddr->precord,"dbtpnCallback");
|
||||
free((void *)pdbaddr);
|
||||
free(ppn);
|
||||
}
|
||||
|
||||
long dbtpn(char *pname,char *pvalue)
|
||||
{
|
||||
long status;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
PUTNOTIFY *ppn=NULL;
|
||||
char *psavevalue;
|
||||
int len;
|
||||
|
||||
len = strlen(pvalue);
|
||||
/*allocate space for value immediately following DBADDR*/
|
||||
pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1);
|
||||
psavevalue = (char *)(pdbaddr + 1);
|
||||
strcpy(psavevalue,pvalue);
|
||||
status = dbNameToAddr(pname,pdbaddr);
|
||||
if(status) {
|
||||
errMessage(status, "dbtpn: dbNameToAddr");
|
||||
free((void *)pdbaddr);
|
||||
return(-1);
|
||||
}
|
||||
ppn = dbCalloc(1,sizeof(PUTNOTIFY));
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->pbuffer = psavevalue;
|
||||
ppn->nRequest = 1;
|
||||
ppn->dbrType = DBR_STRING;
|
||||
ppn->userCallback = dbtpnCallback;
|
||||
status = dbPutNotify(ppn);
|
||||
if(status==S_db_Pending) {
|
||||
printf("dbtpn: Pending nwaiting=%d\n",ppn->nwaiting);
|
||||
return(0);
|
||||
}
|
||||
if(status==S_db_Blocked) {
|
||||
printf("dbtpn: blocked record=%s\n",pname);
|
||||
} else if(status) {
|
||||
errMessage(status, "dbtpn");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbior(char *pdrvName,int type)
|
||||
{
|
||||
int i,j;
|
||||
@@ -914,7 +856,7 @@ static void printBuffer(
|
||||
pdbr_status->status, pdbr_status->severity);
|
||||
} else
|
||||
printf("status and severity not returned\n");
|
||||
pbuffer += dbr_status_size;
|
||||
pbuffer = (char *)pbuffer + dbr_status_size;
|
||||
}
|
||||
if (reqOptions & DBR_UNITS) {
|
||||
if (retOptions & DBR_UNITS) {
|
||||
@@ -924,7 +866,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("units not returned\n");
|
||||
}
|
||||
pbuffer += dbr_units_size;
|
||||
pbuffer = (char *)pbuffer + dbr_units_size;
|
||||
}
|
||||
if (reqOptions & DBR_PRECISION) {
|
||||
precision = *((long *) pbuffer);
|
||||
@@ -935,7 +877,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("precision not returned\n");
|
||||
}
|
||||
pbuffer += dbr_precision_size;
|
||||
pbuffer = (char *)pbuffer + dbr_precision_size;
|
||||
}
|
||||
if (reqOptions & DBR_TIME) {
|
||||
if (retOptions & DBR_TIME) {
|
||||
@@ -946,7 +888,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("time not returned\n");
|
||||
}
|
||||
pbuffer += dbr_time_size;
|
||||
pbuffer = (char *)pbuffer + dbr_time_size;
|
||||
}
|
||||
if (reqOptions & DBR_ENUM_STRS) {
|
||||
if (retOptions & DBR_ENUM_STRS) {
|
||||
@@ -957,7 +899,7 @@ static void printBuffer(
|
||||
printf("%s\n",&pdbr_enumStrs->strs[i][0]);
|
||||
} else
|
||||
printf("enum strings not returned\n");
|
||||
pbuffer += dbr_enumStrs_size;
|
||||
pbuffer = (char *)pbuffer + dbr_enumStrs_size;
|
||||
}
|
||||
if (reqOptions & DBR_GR_LONG) {
|
||||
if (retOptions & DBR_GR_LONG) {
|
||||
@@ -968,7 +910,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("DBRgrLong not returned\n");
|
||||
}
|
||||
pbuffer += dbr_grLong_size;
|
||||
pbuffer = (char *)pbuffer + dbr_grLong_size;
|
||||
}
|
||||
if (reqOptions & DBR_GR_DOUBLE) {
|
||||
if (retOptions & DBR_GR_DOUBLE) {
|
||||
@@ -979,7 +921,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("DBRgrDouble not returned\n");
|
||||
}
|
||||
pbuffer += dbr_grDouble_size;
|
||||
pbuffer = (char *)pbuffer + dbr_grDouble_size;
|
||||
}
|
||||
if (reqOptions & DBR_CTRL_LONG) {
|
||||
if (retOptions & DBR_CTRL_LONG){
|
||||
@@ -990,7 +932,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("DBRctrlLong not returned\n");
|
||||
}
|
||||
pbuffer += dbr_ctrlLong_size;
|
||||
pbuffer = (char *)pbuffer + dbr_ctrlLong_size;
|
||||
}
|
||||
if (reqOptions & DBR_CTRL_DOUBLE) {
|
||||
if (retOptions & DBR_CTRL_DOUBLE) {
|
||||
@@ -1001,7 +943,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("DBRctrlDouble not returned\n");
|
||||
}
|
||||
pbuffer += dbr_ctrlDouble_size;
|
||||
pbuffer = (char *)pbuffer + dbr_ctrlDouble_size;
|
||||
}
|
||||
if (reqOptions & DBR_AL_LONG) {
|
||||
if (retOptions & DBR_AL_LONG) {
|
||||
@@ -1013,7 +955,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("DBRalLong not returned\n");
|
||||
}
|
||||
pbuffer += dbr_alLong_size;
|
||||
pbuffer = (char *)pbuffer + dbr_alLong_size;
|
||||
}
|
||||
if (reqOptions & DBR_AL_DOUBLE) {
|
||||
if (retOptions & DBR_AL_DOUBLE) {
|
||||
@@ -1025,7 +967,7 @@ static void printBuffer(
|
||||
}else{
|
||||
printf("DBRalDouble not returned\n");
|
||||
}
|
||||
pbuffer += dbr_alDouble_size;
|
||||
pbuffer = (char *)pbuffer + dbr_alDouble_size;
|
||||
}
|
||||
/* Now print values */
|
||||
if (no_elements == 0) return;
|
||||
@@ -1044,7 +986,7 @@ static void printBuffer(
|
||||
sprintf(pmsg, " %s", (char *)pbuffer);
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
}
|
||||
pbuffer += MAX_STRING_SIZE;
|
||||
pbuffer = (char *)pbuffer + MAX_STRING_SIZE;
|
||||
}
|
||||
break;
|
||||
case (DBR_CHAR):
|
||||
@@ -1059,7 +1001,7 @@ static void printBuffer(
|
||||
svalue = *(char *) pbuffer;
|
||||
sprintf(pmsg, "%-9d 0x%-9x", svalue,svalue);
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 1;
|
||||
pbuffer = (char *)pbuffer + 1;
|
||||
}
|
||||
break;
|
||||
case (DBR_UCHAR):
|
||||
@@ -1074,7 +1016,7 @@ static void printBuffer(
|
||||
usvalue = *(unsigned char *) pbuffer;
|
||||
sprintf(pmsg, "%-9d 0x%-9x", usvalue,usvalue);
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 1;
|
||||
pbuffer = (char *)pbuffer + 1;
|
||||
}
|
||||
break;
|
||||
case (DBR_SHORT):
|
||||
@@ -1088,7 +1030,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-9d 0x%-9x", *((short *) pbuffer), *((short *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 2;
|
||||
pbuffer = (char *)pbuffer + sizeof(short);
|
||||
}
|
||||
break;
|
||||
case (DBR_USHORT):
|
||||
@@ -1102,7 +1044,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-9u 0x%-9x",*((unsigned short *) pbuffer),*((unsigned short *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 2;
|
||||
pbuffer = (char *)pbuffer + sizeof(unsigned short);
|
||||
}
|
||||
break;
|
||||
case (DBR_LONG):
|
||||
@@ -1116,7 +1058,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-9ld 0x%-9lx", *((long *) pbuffer), *((long *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 4;
|
||||
pbuffer = (char *)pbuffer + sizeof(long);
|
||||
}
|
||||
break;
|
||||
case (DBR_ULONG):
|
||||
@@ -1130,7 +1072,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-9ld 0x%-9lx",*((unsigned long *) pbuffer),*((unsigned long *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 4;
|
||||
pbuffer = (char *)pbuffer + sizeof(unsigned long);
|
||||
}
|
||||
break;
|
||||
case (DBR_FLOAT):
|
||||
@@ -1144,7 +1086,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-13.6g", *((float *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 4;
|
||||
pbuffer = (char *)pbuffer + sizeof(float);
|
||||
}
|
||||
break;
|
||||
case (DBR_DOUBLE):
|
||||
@@ -1158,7 +1100,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-13.6g", *((double *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 8;
|
||||
pbuffer = (char *)pbuffer + sizeof(double);
|
||||
}
|
||||
break;
|
||||
case (DBR_ENUM):
|
||||
@@ -1172,7 +1114,7 @@ static void printBuffer(
|
||||
for (i = 0; i < no_elements; i++) {
|
||||
sprintf(pmsg, "%-9u", *((unsigned short *) pbuffer));
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
pbuffer += 2;
|
||||
pbuffer = (char *)pbuffer + sizeof(unsigned short);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1819,4 +1761,56 @@ char *record_name;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int dbllsdblinks(int lset)
|
||||
{
|
||||
int i,link;
|
||||
struct recLoc *precLoc;
|
||||
struct recDes *precDes;
|
||||
struct recTypDes *precTypDes;
|
||||
struct recHeader *precHeader;
|
||||
RECNODE *precNode;
|
||||
struct fldDes *pfldDes;
|
||||
struct dbCommon *precord;
|
||||
struct link *plink;
|
||||
|
||||
if(!(precHeader = pdbBase->precHeader)) return(-1);
|
||||
if(!(precDes = pdbBase->precDes)) return(-1);
|
||||
for(i=0; i< (precHeader->number); i++) {
|
||||
if(!(precLoc = precHeader->papRecLoc[i]))continue;
|
||||
if(!precLoc->preclist) continue;
|
||||
precTypDes = precDes->papRecTypDes[i];
|
||||
for(precNode=(RECNODE *)ellFirst(precLoc->preclist);
|
||||
precNode; precNode = (RECNODE *)ellNext(&precNode->node)) {
|
||||
precord = precNode->precord;
|
||||
/* If NAME is null then skip this record*/
|
||||
if(!(precord->name[0])) continue;
|
||||
if(precord->lset != lset) continue;
|
||||
printf("%s\n",precord->name);
|
||||
for(link=0; (link<precTypDes->no_links) ; link++) {
|
||||
struct dbAddr *pdbAddr;
|
||||
|
||||
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
|
||||
/*
|
||||
* Find link structure, which is at an offset in the record
|
||||
*/
|
||||
plink = (struct link *)((char *)precord + pfldDes->offset);
|
||||
/* Ignore link if type is constant, channel access, or hardware specific */
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (struct dbAddr *)(plink->value.db_link.pdbAddr);
|
||||
if(pfldDes->field_type==DBF_INLINK) {
|
||||
printf("\t INLINK");
|
||||
} else if(pfldDes->field_type==DBF_OUTLINK) {
|
||||
printf("\tOUTLINK");
|
||||
} else if(pfldDes->field_type==DBF_FWDLINK) {
|
||||
printf("\tFWDLINK");
|
||||
}
|
||||
printf(" %s %s",
|
||||
((plink->value.db_link.process_passive)?" PP":"NPP"),
|
||||
((plink->value.db_link.maximize_sevr)?" MS":"NMS"));
|
||||
printf(" %s\n",pdbAddr->precord->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ short index;
|
||||
}
|
||||
printf(" Record Name: %s\n",pname);
|
||||
printf(" Record Type: %d\n",addr.record_type);
|
||||
printf("Record Address: 0x%x\n",addr.precord);
|
||||
printf("Record Address: 0x%p\n",addr.precord);
|
||||
printf(" Field Type: %d\n",addr.field_type);
|
||||
printf(" Field Address: 0x%x\n",addr.pfield);
|
||||
printf(" Field Address: 0x%p\n",addr.pfield);
|
||||
printf(" Field Size: %d\n",addr.field_size);
|
||||
printf(" No Elements: %d\n",addr.no_elements);
|
||||
number_elements =
|
||||
@@ -128,9 +128,9 @@ short index;
|
||||
}
|
||||
printf(" Record Name: %s\n",pname);
|
||||
printf(" Record Type: %d\n",addr.record_type);
|
||||
printf("Record Address: 0x%x\n",addr.precord);
|
||||
printf("Record Address: 0x%p\n",addr.precord);
|
||||
printf(" Field Type: %d\n",addr.field_type);
|
||||
printf(" Field Address: 0x%x\n",addr.pfield);
|
||||
printf(" Field Address: 0x%p\n",addr.pfield);
|
||||
printf(" Field Size: %d\n",addr.field_size);
|
||||
printf(" No Elements: %d\n",addr.no_elements);
|
||||
if (db_put_field(paddr,DBR_STRING,pvalue,1) < 0) printf("\n\t failed ");
|
||||
@@ -312,7 +312,7 @@ static void print_returned(type,pbuffer,count)
|
||||
{
|
||||
struct dbr_sts_long *pvalue
|
||||
= (struct dbr_sts_long *)pbuffer;
|
||||
long *plong = &pvalue->value;
|
||||
dbr_long_t *plong = &pvalue->value;
|
||||
printf("%2d %2d",pvalue->status,pvalue->severity);
|
||||
if(count==1) printf("\tValue: ");
|
||||
for (i = 0; i < count; i++,plong++){
|
||||
@@ -395,7 +395,7 @@ static void print_returned(type,pbuffer,count)
|
||||
{
|
||||
struct dbr_time_long *pvalue
|
||||
= (struct dbr_time_long *)pbuffer;
|
||||
long *plong = &pvalue->value;
|
||||
dbr_long_t *plong = &pvalue->value;
|
||||
printf("%2d %2d",pvalue->status,pvalue->severity);
|
||||
printf("\tTimeStamp: %lx %lx",
|
||||
pvalue->stamp.secPastEpoch, pvalue->stamp.nsec);
|
||||
@@ -495,7 +495,7 @@ static void print_returned(type,pbuffer,count)
|
||||
{
|
||||
struct dbr_gr_long *pvalue
|
||||
= (struct dbr_gr_long *)pbuffer;
|
||||
long *plong = &pvalue->value;
|
||||
dbr_long_t *plong = &pvalue->value;
|
||||
printf("%2d %2d %.8s",pvalue->status,pvalue->severity,
|
||||
pvalue->units);
|
||||
printf("\n\t%8d %8d %8d %8d %8d %8d",
|
||||
@@ -596,7 +596,7 @@ static void print_returned(type,pbuffer,count)
|
||||
{
|
||||
struct dbr_ctrl_long *pvalue
|
||||
= (struct dbr_ctrl_long *)pbuffer;
|
||||
long *plong = &pvalue->value;
|
||||
dbr_long_t *plong = &pvalue->value;
|
||||
printf("%2d %2d %.8s",pvalue->status,pvalue->severity,
|
||||
pvalue->units);
|
||||
printf("\n\t%8d %8d %8d %8d %8d %8d",
|
||||
|
||||
@@ -120,7 +120,7 @@ if (strcmp(dbl_option,"-1") == 0)
|
||||
ntype = dbl_dbGetRecTypes(pdbbase);
|
||||
|
||||
else {
|
||||
if (strlen(dbl_option) > 1) DBL_OPTION = 2;
|
||||
if (strlen(dbl_option) > (size_t)1) DBL_OPTION = 2;
|
||||
else if (strcmp(dbl_option,"1") == 0) DBL_OPTION = 1;
|
||||
else if (strcmp(dbl_option,"2") == 0) DBL_OPTION = 3;
|
||||
else DBL_OPTION = 0;
|
||||
|
||||
256
src/db/dbls.c
256
src/db/dbls.c
@@ -318,17 +318,17 @@ DbRecType(fp, fflag)
|
||||
if(!(precType=pdbBase->precType)) return;
|
||||
sprintf(buffer, "\n\ndbls: listing the precType structure\n");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] precType-> recType", &precType, precType);
|
||||
sprintf(buffer, "%p[%p] precType-> recType", &precType, precType);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t number\t [ %d ]\t/* number of types */",
|
||||
sprintf(buffer, "%p\t number\t [ %d ]\t/* number of types */",
|
||||
&precType->number, precType->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papName\t\t /* pap to record type */",
|
||||
sprintf(buffer, "%p[%p] **papName\t\t /* pap to record type */",
|
||||
&precType->papName, precType->papName);
|
||||
bufOut(fp, fflag);
|
||||
for (i = 0; i < precType->number; i++) {
|
||||
if (precType->papName[i]) {
|
||||
sprintf(buffer, "%8x[%8x] papName->[%d]->\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p] papName->[%d]->\t\"%s\"",
|
||||
&precType->papName[i],
|
||||
precType->papName[i],
|
||||
i, precType->papName[i]);
|
||||
@@ -349,33 +349,33 @@ ChoiceGbl(fp, fflag)
|
||||
}
|
||||
sprintf(buffer, "\n\ndbls: listing the choiceGbl structure\n");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] pchoiceGbl -> arrChoiceSet", &pchoiceGbl, pchoiceGbl);
|
||||
sprintf(buffer, "%p[%p] pchoiceGbl -> arrChoiceSet", &pchoiceGbl, pchoiceGbl);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */",
|
||||
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of choice sets */",
|
||||
&pchoiceGbl->number,
|
||||
pchoiceGbl->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t**papChoiceSet -> choiceSet",
|
||||
sprintf(buffer, "%p[%p]\t**papChoiceSet -> choiceSet",
|
||||
&pchoiceGbl->papChoiceSet,
|
||||
pchoiceGbl->papChoiceSet);
|
||||
bufOut(fp, fflag);
|
||||
for (i = 0; i < pchoiceGbl->number; i++) {
|
||||
if (pchoiceGbl->papChoiceSet[i]) {
|
||||
sprintf(buffer, "%8x[%8x]\t papChoiceSet->[%d]\tINDEX[%d]",
|
||||
sprintf(buffer, "%p[%p]\t papChoiceSet->[%d]\tINDEX[%d]",
|
||||
&pchoiceGbl->papChoiceSet[i],
|
||||
pchoiceGbl->papChoiceSet[i], i, i);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number [%d]\t\t/* number of choices */",
|
||||
sprintf(buffer, "%p\t\t number [%d]\t\t/* number of choices */",
|
||||
&pchoiceGbl->papChoiceSet[i]->number,
|
||||
pchoiceGbl->papChoiceSet[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t **papChoice -> \t\"choice string\"",
|
||||
sprintf(buffer, "%p[%p]\t **papChoice -> \t\"choice string\"",
|
||||
&pchoiceGbl->papChoiceSet[i]->papChoice,
|
||||
pchoiceGbl->papChoiceSet[i]->papChoice);
|
||||
bufOut(fp, fflag);
|
||||
for (j = 0; j < pchoiceGbl->papChoiceSet[i]->number; j++) {
|
||||
if (pchoiceGbl->papChoiceSet[i]->papChoice[j]) {
|
||||
sprintf(buffer, "%8x[%8x]\t\t papChoice->[%d]\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p]\t\t papChoice->[%d]\t\"%s\"",
|
||||
&pchoiceGbl->papChoiceSet[i]->papChoice[j],
|
||||
pchoiceGbl->papChoiceSet[i]->papChoice[j],
|
||||
j,
|
||||
@@ -402,41 +402,41 @@ ChoiceDev(fp, fflag)
|
||||
getRecTypeSel();
|
||||
sprintf(buffer, "\n\ndbls: listing the choiceDev structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]pchoiceDev-> devChoiceRec ", &pchoiceDev, pchoiceDev);
|
||||
sprintf(buffer, "%p[%p]pchoiceDev-> devChoiceRec ", &pchoiceDev, pchoiceDev);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t number\t[%d]\t\t\t/* number of devChoiceSet */",
|
||||
sprintf(buffer, "%p\t number\t[%d]\t\t\t/* number of devChoiceSet */",
|
||||
&pchoiceDev->number, pchoiceDev->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papDevChoiceSet -> devChoiceSet ",
|
||||
sprintf(buffer, "%p[%p] **papDevChoiceSet -> devChoiceSet ",
|
||||
&pchoiceDev->papDevChoiceSet,
|
||||
pchoiceDev->papDevChoiceSet);
|
||||
bufOut(fp, fflag);
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
if (pchoiceDev->papDevChoiceSet[i]) {
|
||||
sprintf(buffer, "\n%8x[%8x]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"",
|
||||
sprintf(buffer, "\n%p[%p]\tpapDevChoiceSet->[%d]\t\tRECTYPE \"%s\"",
|
||||
&pchoiceDev->papDevChoiceSet[i],
|
||||
pchoiceDev->papDevChoiceSet[i], i,
|
||||
precType->papName[i]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t[%d]\t\t/*number of choices */ ",
|
||||
sprintf(buffer, "%p\t\t number\t[%d]\t\t/*number of choices */ ",
|
||||
&pchoiceDev->papDevChoiceSet[i]->number,
|
||||
pchoiceDev->papDevChoiceSet[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t **papDevChoice -> devChoice",
|
||||
sprintf(buffer, "%p[%p]\t **papDevChoice -> devChoice",
|
||||
&pchoiceDev->papDevChoiceSet[i]->papDevChoice,
|
||||
pchoiceDev->papDevChoiceSet[i]->papDevChoice);
|
||||
bufOut(fp, fflag);
|
||||
for (j = 0; j < pchoiceDev->papDevChoiceSet[i]->number; j++) {
|
||||
if (pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]) {
|
||||
sprintf(buffer, "%8x[%8x]\t papDevChoice[%d]",
|
||||
sprintf(buffer, "%p[%p]\t papDevChoice[%d]",
|
||||
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j],
|
||||
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j], j);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t link_type [%d]",
|
||||
sprintf(buffer, "%p\t\t link_type [%d]",
|
||||
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type,
|
||||
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->link_type);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t\t*pchoice\t\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p]\t\t*pchoice\t\t\"%s\"",
|
||||
&pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice,
|
||||
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice,
|
||||
pchoiceDev->papDevChoiceSet[i]->papDevChoice[j]->pchoice);
|
||||
@@ -459,18 +459,18 @@ ChoiceCvt(fp, fflag)
|
||||
}
|
||||
sprintf(buffer, "\n\ndbls: listing the choiceCvt structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] choiceCvt -> choiceCvt", &pchoiceCvt, pchoiceCvt);
|
||||
sprintf(buffer, "%p[%p] choiceCvt -> choiceCvt", &pchoiceCvt, pchoiceCvt);
|
||||
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x number\t [ %d ]\t/* number of choices */",
|
||||
sprintf(buffer, "%p number\t [ %d ]\t/* number of choices */",
|
||||
&pchoiceCvt->number, pchoiceCvt->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papChoice -> \"choice string\"",
|
||||
sprintf(buffer, "%p[%p] **papChoice -> \"choice string\"",
|
||||
&pchoiceCvt->papChoice, pchoiceCvt->papChoice);
|
||||
bufOut(fp, fflag);
|
||||
for (i = 0; i < pchoiceCvt->number; i++)
|
||||
if (pchoiceCvt->papChoice[i]) {
|
||||
sprintf(buffer, "%8x[%8x] papChoice[%d]\t\"%s\" ",
|
||||
sprintf(buffer, "%p[%p] papChoice[%d]\t\"%s\" ",
|
||||
&pchoiceCvt->papChoice[i], pchoiceCvt->papChoice[i], i,
|
||||
pchoiceCvt->papChoice[i]);
|
||||
bufOut(fp, fflag);
|
||||
@@ -523,55 +523,55 @@ CvtTable(fp, fflag)
|
||||
}
|
||||
sprintf(buffer, "\n\ndbls: listing the pcvtTable structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] pcvtTable -> arrBrkTable", &pcvtTable, pcvtTable);
|
||||
sprintf(buffer, "%p[%p] pcvtTable -> arrBrkTable", &pcvtTable, pcvtTable);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x number\t [ %d ]\t/* number of break tables */",
|
||||
sprintf(buffer, "%p number\t [ %d ]\t/* number of break tables */",
|
||||
&pcvtTable->number, pcvtTable->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papBrkTable -> brkTable",
|
||||
sprintf(buffer, "%p[%p] **papBrkTable -> brkTable",
|
||||
&pcvtTable->papBrkTable, pcvtTable->papBrkTable);
|
||||
bufOut(fp, fflag);
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
if (pcvtTable->papBrkTable[i]) {
|
||||
sprintf(buffer, "%8x[%8x] papBrkTable[%d] ",
|
||||
sprintf(buffer, "%p[%p] papBrkTable[%d] ",
|
||||
&pcvtTable->papBrkTable[i], pcvtTable->papBrkTable[i], i);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t *name\t\t\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p]\t *name\t\t\t\"%s\"",
|
||||
&pcvtTable->papBrkTable[i]->name,
|
||||
pcvtTable->papBrkTable[i]->name,
|
||||
pcvtTable->papBrkTable[i]->name);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number [ %d ]\t/* number of brkInt in this table */ ",
|
||||
sprintf(buffer, "%p\t\t number [ %d ]\t/* number of brkInt in this table */ ",
|
||||
&pcvtTable->papBrkTable[i]->number,
|
||||
pcvtTable->papBrkTable[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t rawLow\t\t\t%-d",
|
||||
sprintf(buffer, "%p\t\t rawLow\t\t\t%-d",
|
||||
&pcvtTable->papBrkTable[i]->rawLow,
|
||||
pcvtTable->papBrkTable[i]->rawLow);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t rawHigh\t\t\t%-d",
|
||||
sprintf(buffer, "%p\t\t rawHigh\t\t\t%-d",
|
||||
&pcvtTable->papBrkTable[i]->rawHigh,
|
||||
pcvtTable->papBrkTable[i]->rawHigh);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t**papBrkInt",
|
||||
sprintf(buffer, "%p[%p]\t**papBrkInt",
|
||||
&pcvtTable->papBrkTable[i]->papBrkInt,
|
||||
pcvtTable->papBrkTable[i]->papBrkInt);
|
||||
bufOut(fp, fflag);
|
||||
for (j = 0; j < pcvtTable->papBrkTable[i]->number; j++) {
|
||||
if (pcvtTable->papBrkTable[i]->papBrkInt[j]) {
|
||||
sprintf(buffer, "%8x[%8x]\t papBrkInt[%d] -> brkInt",
|
||||
sprintf(buffer, "%p[%p]\t papBrkInt[%d] -> brkInt",
|
||||
&pcvtTable->papBrkTable[i]->papBrkInt[j],
|
||||
pcvtTable->papBrkTable[i]->papBrkInt[j], j);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t raw\t\t\t%-d",
|
||||
sprintf(buffer, "%p\t\t raw\t\t\t%-d",
|
||||
&pcvtTable->papBrkTable[i]->papBrkInt[j]->raw,
|
||||
pcvtTable->papBrkTable[i]->papBrkInt[j]->raw);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t slope\t\t\t%-.5f",
|
||||
sprintf(buffer, "%p\t\t slope\t\t\t%-.5f",
|
||||
&pcvtTable->papBrkTable[i]->papBrkInt[j]->slope,
|
||||
pcvtTable->papBrkTable[i]->papBrkInt[j]->slope);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t eng\t\t\t%-.5f",
|
||||
sprintf(buffer, "%p\t\t eng\t\t\t%-.5f",
|
||||
&pcvtTable->papBrkTable[i]->papBrkInt[j]->eng,
|
||||
pcvtTable->papBrkTable[i]->papBrkInt[j]->eng);
|
||||
bufOut(fp, fflag);
|
||||
@@ -596,42 +596,42 @@ DevSup(fp, fflag)
|
||||
getRecTypeSel();
|
||||
sprintf(buffer, "\n\ndbls: listing the devSup structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] precDevSup -> recDevSup ", &precDevSup, precDevSup);
|
||||
sprintf(buffer, "%p[%p] precDevSup -> recDevSup ", &precDevSup, precDevSup);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t/* number of record types */",
|
||||
sprintf(buffer, "%p\t\tnumber\t [ %d ]\t/* number of record types */",
|
||||
&precDevSup->number, precDevSup->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papDevSup -> precDevSup ",
|
||||
sprintf(buffer, "%p[%p] **papDevSup -> precDevSup ",
|
||||
&precDevSup->papDevSup, precDevSup->papDevSup);
|
||||
bufOut(fp, fflag);
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
if (precDevSup->papDevSup[i]) {
|
||||
sprintf(buffer, "%8x[%8x] papDevSup->[%d]\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p] papDevSup->[%d]\t\"%s\"",
|
||||
&precDevSup->papDevSup[i],
|
||||
precDevSup->papDevSup[i], i,
|
||||
precType->papName[i]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */",
|
||||
sprintf(buffer, "%p\t\t number\t[%d]\t/* number of dset */",
|
||||
&precDevSup->papDevSup[i]->number,
|
||||
precDevSup->papDevSup[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papDsetName",
|
||||
sprintf(buffer, "%p[%p] **papDsetName",
|
||||
&precDevSup->papDevSup[i]->papDsetName,
|
||||
precDevSup->papDevSup[i]->papDsetName);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papDset",
|
||||
sprintf(buffer, "%p[%p] **papDset",
|
||||
&precDevSup->papDevSup[i]->papDset,
|
||||
precDevSup->papDevSup[i]->papDset);
|
||||
bufOut(fp, fflag);
|
||||
for (j = 0; j < precDevSup->papDevSup[i]->number; j++) {
|
||||
if (precDevSup->papDevSup[i]->papDsetName[j]) {
|
||||
sprintf(buffer, "%8x[%8x]\t\tpapDsetName[%d]\t%s",
|
||||
sprintf(buffer, "%p[%p]\t\tpapDsetName[%d]\t%s",
|
||||
&precDevSup->papDevSup[i]->papDsetName[j],
|
||||
precDevSup->papDevSup[i]->papDsetName[j],
|
||||
j,
|
||||
precDevSup->papDevSup[i]->papDsetName[j]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t\tpapDset[%d]",
|
||||
sprintf(buffer, "%p[%p]\t\tpapDset[%d]",
|
||||
&precDevSup->papDevSup[i]->papDset[j],
|
||||
precDevSup->papDevSup[i]->papDset[j], j);
|
||||
bufOut(fp, fflag);
|
||||
@@ -652,24 +652,24 @@ DrvSup(fp, fflag)
|
||||
}
|
||||
sprintf(buffer, "\n\ndbls: listing the drvSup structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] pdrvSup -> pdrvSup ", &pdrvSup, pdrvSup);
|
||||
sprintf(buffer, "%p[%p] pdrvSup -> pdrvSup ", &pdrvSup, pdrvSup);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t[%d]\t/* number of dset */", &pdrvSup->number, pdrvSup->number);
|
||||
sprintf(buffer, "%p\t\t number\t[%d]\t/* number of dset */", &pdrvSup->number, pdrvSup->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papDrvName -> \t/* pArr of ptr to papDrvName */ ",
|
||||
sprintf(buffer, "%p[%p] **papDrvName -> \t/* pArr of ptr to papDrvName */ ",
|
||||
&pdrvSup->papDrvName, pdrvSup->papDrvName);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papDrvet-> drvet \t/* pArr ptr to drvet */",
|
||||
sprintf(buffer, "%p[%p] **papDrvet-> drvet \t/* pArr ptr to drvet */",
|
||||
&pdrvSup->papDrvet, pdrvSup->papDrvet);
|
||||
bufOut(fp, fflag);
|
||||
for (i = 0; i < pdrvSup->number; i++) {
|
||||
if (pdrvSup->papDrvName[i])
|
||||
sprintf(buffer, "%8x[%8x]\t papDrvName->[%d]\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p]\t papDrvName->[%d]\t\"%s\"",
|
||||
&pdrvSup->papDrvName[i],
|
||||
pdrvSup->papDrvName[i],
|
||||
i, pdrvSup->papDrvName[i]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t papDrvet->[%d] /* reserved ptr to drvet */",
|
||||
sprintf(buffer, "%p[%p]\t papDrvet->[%d] /* reserved ptr to drvet */",
|
||||
&pdrvSup->papDrvet[i],
|
||||
pdrvSup->papDrvet[i], i);
|
||||
bufOut(fp, fflag);
|
||||
@@ -703,7 +703,7 @@ DbRecDes(fp, fflag)
|
||||
for (j = 0; j < endNumJ; j++) {
|
||||
printf("%3d %4.4s",
|
||||
precDes->papRecTypDes[begNumI]->sortFldInd[j],
|
||||
&precDes->papRecTypDes[begNumI]->sortFldName[j]);
|
||||
(char *)&precDes->papRecTypDes[begNumI]->sortFldName[j]);
|
||||
if (!((j + 1) % 8))
|
||||
printf("\n");
|
||||
}
|
||||
@@ -723,48 +723,48 @@ DbRecDes(fp, fflag)
|
||||
|
||||
sprintf(buffer, "\n\ndbls: listing the precDes structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] precDes-> recDes", &precDes, precDes);
|
||||
sprintf(buffer, "%p[%p] precDes-> recDes", &precDes, precDes);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\tnumber [%d] \t/* number of recTypDes */",
|
||||
sprintf(buffer, "%p\t\tnumber [%d] \t/* number of recTypDes */",
|
||||
&precDes->number, precDes->number);
|
||||
bufOut(fp, fflag);
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
|
||||
if (precDes->papRecTypDes[i]) {
|
||||
sprintf(buffer, "\n%8x[%8x] **papRecTypDes-> recTypDes\t\"%s\"",
|
||||
sprintf(buffer, "\n%p[%p] **papRecTypDes-> recTypDes\t\"%s\"",
|
||||
&precDes->papRecTypDes,
|
||||
precDes->papRecTypDes,
|
||||
precType->papName[i]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t rec_size [%d]",
|
||||
sprintf(buffer, "%p\t\t rec_size [%d]",
|
||||
&precDes->papRecTypDes[i]->rec_size,
|
||||
precDes->papRecTypDes[i]->rec_size);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t no_fields [%d]",
|
||||
sprintf(buffer, "%p\t\t no_fields [%d]",
|
||||
&precDes->papRecTypDes[i]->no_fields,
|
||||
precDes->papRecTypDes[i]->no_fields);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t no_prompt [%d]",
|
||||
sprintf(buffer, "%p\t\t no_prompt [%d]",
|
||||
&precDes->papRecTypDes[i]->no_prompt,
|
||||
precDes->papRecTypDes[i]->no_prompt);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t no_links [%d]",
|
||||
sprintf(buffer, "%p\t\t no_links [%d]",
|
||||
&precDes->papRecTypDes[i]->no_links,
|
||||
precDes->papRecTypDes[i]->no_links);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t *link_ind",
|
||||
sprintf(buffer, "%p[%p]\t *link_ind",
|
||||
&precDes->papRecTypDes[i]->link_ind,
|
||||
precDes->papRecTypDes[i]->link_ind);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t *sortFldName",
|
||||
sprintf(buffer, "%p[%p]\t *sortFldName",
|
||||
&precDes->papRecTypDes[i]->sortFldName,
|
||||
precDes->papRecTypDes[i]->sortFldName);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t *sortFldInd",
|
||||
sprintf(buffer, "%p[%p]\t *sortFldInd",
|
||||
&precDes->papRecTypDes[i]->sortFldInd,
|
||||
precDes->papRecTypDes[i]->sortFldInd);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t **papFldDes-> fldDes",
|
||||
sprintf(buffer, "%p[%p]\t **papFldDes-> fldDes",
|
||||
&precDes->papRecTypDes[i]->papFldDes,
|
||||
precDes->papRecTypDes[i]->papFldDes);
|
||||
bufOut(fp, fflag);
|
||||
@@ -773,7 +773,7 @@ DbRecDes(fp, fflag)
|
||||
endNumJ = precDes->papRecTypDes[i]->no_fields;
|
||||
/* expand *link_ind */
|
||||
for (j = 0; j < precDes->papRecTypDes[i]->no_links; j++) {
|
||||
sprintf(buffer,"%8x\tlink_ind[%d] offset=[%d]",
|
||||
sprintf(buffer,"%p\tlink_ind[%d] offset=[%d]",
|
||||
&precDes->papRecTypDes[i]->link_ind[j],
|
||||
j,
|
||||
precDes->papRecTypDes[i]->link_ind[j]);
|
||||
@@ -782,7 +782,7 @@ DbRecDes(fp, fflag)
|
||||
/* expand *sortFldName and *sortFldInd */
|
||||
ptemp = (char *) precDes->papRecTypDes[i]->sortFldName;
|
||||
for (j = 0; j < precDes->papRecTypDes[i]->no_fields; j++) {
|
||||
sprintf(buffer,"[%8x] sortFldName[%2d]=%4.4s [%8x] sortFldInd=%2d",
|
||||
sprintf(buffer,"[%p] sortFldName[%2d]=%4.4s [%p] sortFldInd=%2d",
|
||||
ptemp,
|
||||
j,
|
||||
ptemp,
|
||||
@@ -796,89 +796,89 @@ DbRecDes(fp, fflag)
|
||||
for (j = begNumJ; j < endNumJ; j++) {
|
||||
sprintf(buffer, "\n");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t **papFldDes->fldDes[%d]",
|
||||
sprintf(buffer, "%p[%p]\t **papFldDes->fldDes[%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j],
|
||||
precDes->papRecTypDes[i]->papFldDes[j], j);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tprompt\t\t\"%s\"",
|
||||
sprintf(buffer, "%p\t\t\tprompt\t\t\"%s\"",
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->prompt,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->prompt);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tfldname\t\t\"%4.4s\"",
|
||||
sprintf(buffer, "%p\t\t\tfldname\t\t\"%4.4s\"",
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->fldname,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->fldname);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\toffset [%d]",
|
||||
sprintf(buffer, "%p\t\t\toffset [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->offset,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->offset);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tsize [%d]",
|
||||
sprintf(buffer, "%p\t\t\tsize [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->size,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->size);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tspecial [%d]",
|
||||
sprintf(buffer, "%p\t\t\tspecial [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->special,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->special);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tfield_type [%d]",
|
||||
sprintf(buffer, "%p\t\t\tfield_type [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->field_type,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->field_type);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tprocess_passive [%d]",
|
||||
sprintf(buffer, "%p\t\t\tprocess_passive [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->process_passive,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->process_passive);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tchoice_set [%d]",
|
||||
sprintf(buffer, "%p\t\t\tchoice_set [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->choice_set,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->choice_set);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tcvt_type [%d]",
|
||||
sprintf(buffer, "%p\t\t\tcvt_type [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->cvt_type,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->cvt_type);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tpromptflag [%d]",
|
||||
sprintf(buffer, "%p\t\t\tpromptflag [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->promptflag,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->promptflag);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tlowfl [%d]",
|
||||
sprintf(buffer, "%p\t\t\tlowfl [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->lowfl,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->lowfl);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\thighfl [%d]",
|
||||
sprintf(buffer, "%p\t\t\thighfl [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->highfl,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->highfl);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tinterest [%d]",
|
||||
sprintf(buffer, "%p\t\t\tinterest [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->interest,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->interest);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tas_level [%d]",
|
||||
sprintf(buffer, "%p\t\t\tas_level [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->as_level,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->as_level);
|
||||
bufOut(fp, fflag);
|
||||
memcpy((void *) buff,
|
||||
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->initial, 8);
|
||||
sprintf(buffer, "%8x[%8x][%8x]\tinitial",
|
||||
sprintf(buffer, "%p[%8x][%8x]\tinitial",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->initial,
|
||||
buff[0], buff[1]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\trange1.fldnum [%d]",
|
||||
sprintf(buffer, "%p\t\t\trange1.fldnum [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->range1.fldnum);
|
||||
bufOut(fp, fflag);
|
||||
memcpy((void *) buff,
|
||||
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->range1.value, 8);
|
||||
sprintf(buffer, "%8x[%8x][%8x]\trange1.value",
|
||||
sprintf(buffer, "%p[%8x][%8x]\trange1.value",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->range1.value,
|
||||
buff[0], buff[1]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\trange2.fldnum [%d]",
|
||||
sprintf(buffer, "%p\t\t\trange2.fldnum [%d]",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum,
|
||||
precDes->papRecTypDes[i]->papFldDes[j]->range2.fldnum);
|
||||
bufOut(fp, fflag);
|
||||
memcpy((void *) buff,
|
||||
(void *) & precDes->papRecTypDes[i]->papFldDes[j]->range2.value, 8);
|
||||
sprintf(buffer, "%8x[%8x][%8x]\trange2.value",
|
||||
sprintf(buffer, "%p[%8x][%8x]\trange2.value",
|
||||
&precDes->papRecTypDes[i]->papFldDes[j]->range2.value,
|
||||
buff[0], buff[1]);
|
||||
bufOut(fp, fflag);
|
||||
@@ -935,48 +935,48 @@ ChoiceRec(fp, fflag)
|
||||
}
|
||||
sprintf(buffer, "\n\ndbls: listing the choiceRec structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] pchoiceRec -> pchoiceRec", &pchoiceRec, pchoiceRec);
|
||||
sprintf(buffer, "%p[%p] pchoiceRec -> pchoiceRec", &pchoiceRec, pchoiceRec);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\tnumber\t\t[%d]", &pchoiceRec->number, pchoiceRec->number);
|
||||
sprintf(buffer, "%p\t\tnumber\t\t[%d]", &pchoiceRec->number, pchoiceRec->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t**papArrChoiceSet -> arrChoiceSet",
|
||||
sprintf(buffer, "%p[%p]\t**papArrChoiceSet -> arrChoiceSet",
|
||||
&pchoiceRec->papArrChoiceSet,
|
||||
pchoiceRec->papArrChoiceSet);
|
||||
bufOut(fp, fflag);
|
||||
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
if (pchoiceRec->papArrChoiceSet[i]) {
|
||||
sprintf(buffer, "%8x[%8x]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"",
|
||||
sprintf(buffer, "%p[%p]\tpapArrChoiceSet[%d] -> arrChoiceSet\t\tRECTYPE \"%s\"",
|
||||
&pchoiceRec->papArrChoiceSet[i],
|
||||
pchoiceRec->papArrChoiceSet[i], i,
|
||||
precType->papName[i]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of choice sets */",
|
||||
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of choice sets */",
|
||||
&pchoiceRec->papArrChoiceSet[i]->number,
|
||||
pchoiceRec->papArrChoiceSet[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t **papChoiceSet",
|
||||
sprintf(buffer, "%p[%p]\t **papChoiceSet",
|
||||
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet,
|
||||
pchoiceRec->papArrChoiceSet[i]->papChoiceSet);
|
||||
bufOut(fp, fflag);
|
||||
for (j = 0; j < pchoiceRec->papArrChoiceSet[i]->number; j++) {
|
||||
if (pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]) {
|
||||
sprintf(buffer, "%8x[%8x]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]",
|
||||
sprintf(buffer, "%p[%p]\t papChoiceSet[%d] -> choiceSet \t\tINDEX[%d]",
|
||||
|
||||
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j],
|
||||
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j], j, j);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t\tnumber\t\t[%d]\t/* number of choices */ ",
|
||||
sprintf(buffer, "%p\t\t\tnumber\t\t[%d]\t/* number of choices */ ",
|
||||
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number,
|
||||
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t\t**papChoice -> \"string\"",
|
||||
sprintf(buffer, "%p[%p]\t\t**papChoice -> \"string\"",
|
||||
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice,
|
||||
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice);
|
||||
bufOut(fp, fflag);
|
||||
for (k = 0; k < pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->number; k++) {
|
||||
if (pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]) {
|
||||
sprintf(buffer, "%8x[%8x]\t\tpapChoice[%d]\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p]\t\tpapChoice[%d]\t\"%s\"",
|
||||
&pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k],
|
||||
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k], k,
|
||||
pchoiceRec->papArrChoiceSet[i]->papChoiceSet[j]->papChoice[k]);
|
||||
@@ -1003,28 +1003,28 @@ DbErrDes(fp, fflag)
|
||||
}
|
||||
sprintf(buffer, "\n\ndbls: listing the dbErrDes structure");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] dbErrDes -> errDes ", &dbErrDes, dbErrDes);
|
||||
sprintf(buffer, "%p[%p] dbErrDes -> errDes ", &dbErrDes, dbErrDes);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\tnumber\t [ %d ]\t /* dim of err modules */",
|
||||
sprintf(buffer, "%p\t\tnumber\t [ %d ]\t /* dim of err modules */",
|
||||
&dbErrDes->number, dbErrDes->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papErrSet -> errSet ",
|
||||
sprintf(buffer, "%p[%p] **papErrSet -> errSet ",
|
||||
&dbErrDes->papErrSet, dbErrDes->papErrSet);
|
||||
bufOut(fp, fflag);
|
||||
for (i = 0; i < dbErrDes->number; i++) {
|
||||
if (dbErrDes->papErrSet[i]) {
|
||||
sprintf(buffer, "%8x[%8x] papErrSet->[%d]\tmodule[%d]",
|
||||
sprintf(buffer, "%p[%p] papErrSet->[%d]\tmodule[%d]",
|
||||
&dbErrDes->papErrSet[i],
|
||||
dbErrDes->papErrSet[i], i,
|
||||
i + 501);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t[%d]\t/* dim of errSet */",
|
||||
sprintf(buffer, "%p\t\t number\t[%d]\t/* dim of errSet */",
|
||||
&dbErrDes->papErrSet[i]->number,
|
||||
dbErrDes->papErrSet[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
for (j = 0; j < dbErrDes->papErrSet[i]->number; j++) {
|
||||
if (dbErrDes->papErrSet[i]->papName[j]) {
|
||||
sprintf(buffer, "%8x[%8x]\t\tpapName[%d]\t\"%s\"",
|
||||
sprintf(buffer, "%p[%p]\t\tpapName[%d]\t\"%s\"",
|
||||
&dbErrDes->papErrSet[i]->papName[j],
|
||||
dbErrDes->papErrSet[i]->papName[j],
|
||||
j,
|
||||
@@ -1055,30 +1055,30 @@ DbRecords(fp, fflag)
|
||||
getRecTypeSel();
|
||||
sprintf(buffer, "\n\ndbls: listing the precHeader structure\n");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] precHeader -> recHeader", &precHeader, precHeader);
|
||||
sprintf(buffer, "%p[%p] precHeader -> recHeader", &precHeader, precHeader);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */",
|
||||
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of record types */",
|
||||
&precHeader->number,
|
||||
precHeader->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t**papRecLoc -> recLoc",
|
||||
sprintf(buffer, "%p[%p]\t**papRecLoc -> recLoc",
|
||||
&precHeader->papRecLoc,
|
||||
precHeader->papRecLoc);
|
||||
bufOut(fp, fflag);
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
if (precHeader->papRecLoc[i]) {
|
||||
sprintf(buffer, "%8x[%8x]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]",
|
||||
sprintf(buffer, "%p[%p]\t papRecLoc->[%d]\tRECTYPE[\"%s\"]",
|
||||
&precHeader->papRecLoc[i],
|
||||
precHeader->papRecLoc[i],
|
||||
i,
|
||||
precType->papName[i]);
|
||||
bufOut(fp, fflag);
|
||||
|
||||
sprintf(buffer, "%8x\t\t rec_size [%d]\t\t/* rec_size in bytes */",
|
||||
sprintf(buffer, "%p\t\t rec_size [%d]\t\t/* rec_size in bytes */",
|
||||
&precHeader->papRecLoc[i]->rec_size,
|
||||
precHeader->papRecLoc[i]->rec_size);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t record_type [%d]\t\t/* record_type in bytes */",
|
||||
sprintf(buffer, "%p\t\t record_type [%d]\t\t/* record_type in bytes */",
|
||||
&precHeader->papRecLoc[i]->record_type,
|
||||
precHeader->papRecLoc[i]->record_type);
|
||||
bufOut(fp, fflag);
|
||||
@@ -1102,84 +1102,84 @@ RecSup(fp, fflag)
|
||||
getRecTypeSel();
|
||||
sprintf(buffer, "\n\ndbls: listing the recSup structure\n");
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] precSup -> precSup", &precSup, precSup);
|
||||
sprintf(buffer, "%p[%p] precSup -> precSup", &precSup, precSup);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x\t\t number\t\t[%d]\t/* number of record types */",
|
||||
sprintf(buffer, "%p\t\t number\t\t[%d]\t/* number of record types */",
|
||||
&precSup->number,
|
||||
precSup->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x] **papRset -> rset",
|
||||
sprintf(buffer, "%p[%p] **papRset -> rset",
|
||||
&precSup->papRset,
|
||||
precSup->papRset);
|
||||
bufOut(fp, fflag);
|
||||
for (i = begNumI; i < endNumI; i++) {
|
||||
if (precSup->papRset[i]) {
|
||||
sprintf(buffer, "%8x[%8x]\t papRset->[%d]\t\tRECTYPE[\"%s\"]",
|
||||
sprintf(buffer, "%p[%p]\t papRset->[%d]\t\tRECTYPE[\"%s\"]",
|
||||
&precSup->papRset[i],
|
||||
precSup->papRset[i], i,
|
||||
precType->papName[i]);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t number\t\t/*number of support routines */",
|
||||
sprintf(buffer, "%p[%d]\t number\t\t/*number of support routines */",
|
||||
&precSup->papRset[i]->number,
|
||||
precSup->papRset[i]->number);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t report\t\t/*print report */",
|
||||
sprintf(buffer, "%p[%p]\t report\t\t/*print report */",
|
||||
&precSup->papRset[i]->report,
|
||||
precSup->papRset[i]->report);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t init\t\t/*init support */",
|
||||
sprintf(buffer, "%p[%p]\t init\t\t/*init support */",
|
||||
&precSup->papRset[i]->init,
|
||||
precSup->papRset[i]->init);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t init_record\t/*init record */",
|
||||
sprintf(buffer, "%p[%p]\t init_record\t/*init record */",
|
||||
&precSup->papRset[i]->init_record,
|
||||
precSup->papRset[i]->init_record);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t process\t\t/*process record */",
|
||||
sprintf(buffer, "%p[%p]\t process\t\t/*process record */",
|
||||
&precSup->papRset[i]->process,
|
||||
precSup->papRset[i]->process);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t special\t\t/*special processing */",
|
||||
sprintf(buffer, "%p[%p]\t special\t\t/*special processing */",
|
||||
&precSup->papRset[i]->special,
|
||||
precSup->papRset[i]->special);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_precision\t/* get_precision of this type */",
|
||||
sprintf(buffer, "%p[%p]\t get_precision\t/* get_precision of this type */",
|
||||
&precSup->papRset[i]->get_precision,
|
||||
precSup->papRset[i]->get_precision);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_value\t\t/*get value field */",
|
||||
sprintf(buffer, "%p[%p]\t get_value\t\t/*get value field */",
|
||||
&precSup->papRset[i]->get_value,
|
||||
precSup->papRset[i]->get_value);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t cvt_dbaddr\t\t/*cvt dbAddr */",
|
||||
sprintf(buffer, "%p[%p]\t cvt_dbaddr\t\t/*cvt dbAddr */",
|
||||
&precSup->papRset[i]->cvt_dbaddr,
|
||||
precSup->papRset[i]->cvt_dbaddr);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_array_info\t/* get_array_info of this type */",
|
||||
sprintf(buffer, "%p[%p]\t get_array_info\t/* get_array_info of this type */",
|
||||
&precSup->papRset[i]->get_array_info,
|
||||
precSup->papRset[i]->get_array_info);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t put_array_info\t/* put_array_info of this type */",
|
||||
sprintf(buffer, "%p[%p]\t put_array_info\t/* put_array_info of this type */",
|
||||
&precSup->papRset[i]->put_array_info,
|
||||
precSup->papRset[i]->put_array_info);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_enum_str\t/*get string from enum item*/",
|
||||
sprintf(buffer, "%p[%p]\t get_enum_str\t/*get string from enum item*/",
|
||||
&precSup->papRset[i]->get_enum_str,
|
||||
precSup->papRset[i]->get_enum_str);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_units \t\t/* get_units of this type */",
|
||||
sprintf(buffer, "%p[%p]\t get_units \t\t/* get_units of this type */",
|
||||
&precSup->papRset[i]->get_units,
|
||||
precSup->papRset[i]->get_units);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_graphic_double /* get_graphic_double of this type */",
|
||||
sprintf(buffer, "%p[%p]\t get_graphic_double /* get_graphic_double of this type */",
|
||||
&precSup->papRset[i]->get_graphic_double,
|
||||
precSup->papRset[i]->get_graphic_double);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_control_double /* get_control_double of this type */",
|
||||
sprintf(buffer, "%p[%p]\t get_control_double /* get_control_double of this type */",
|
||||
&precSup->papRset[i]->get_control_double,
|
||||
precSup->papRset[i]->get_control_double);
|
||||
bufOut(fp, fflag);
|
||||
sprintf(buffer, "%8x[%8x]\t get_enum_strs\t/*get all enum strings */",
|
||||
sprintf(buffer, "%p[%p]\t get_enum_strs\t/*get all enum strings */",
|
||||
&precSup->papRset[i]->get_enum_strs,
|
||||
precSup->papRset[i]->get_enum_strs);
|
||||
bufOut(fp, fflag);
|
||||
|
||||
521
src/db/drvTS.c
521
src/db/drvTS.c
File diff suppressed because it is too large
Load Diff
@@ -55,8 +55,6 @@ int callNumber;
|
||||
switch (callNumber) {
|
||||
case INITHOOKatBeginning :
|
||||
break;
|
||||
case INITHOOKafterSetEnvParams :
|
||||
break;
|
||||
case INITHOOKafterGetResources :
|
||||
break;
|
||||
case INITHOOKafterLogInit :
|
||||
|
||||
106
src/db/iocInit.c
106
src/db/iocInit.c
@@ -98,6 +98,8 @@
|
||||
#include <envDefs.h>
|
||||
#include <dbStaticLib.h>
|
||||
#include <initHooks.h>
|
||||
#include <drvTS.h>
|
||||
#include <asLib.h>
|
||||
|
||||
/*This module will declare and initilize module_type variables*/
|
||||
#define MODULE_TYPES_INIT 1
|
||||
@@ -106,10 +108,11 @@
|
||||
LOCAL int initialized=FALSE;
|
||||
|
||||
/* The following is for use by interrupt routines */
|
||||
int interruptAccept=FALSE;
|
||||
volatile int interruptAccept=FALSE;
|
||||
|
||||
struct dbBase *pdbBase=NULL;
|
||||
|
||||
|
||||
/* added for Channel Access Links */
|
||||
long dbCommonInit();
|
||||
|
||||
@@ -120,7 +123,8 @@ LOCAL long initDevSup(void);
|
||||
LOCAL long finishDevSup(void);
|
||||
LOCAL long initDatabase(void);
|
||||
LOCAL void createLockSets(void);
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr,short set);
|
||||
LOCAL void createLockSetsExtraPass(int *anyChange);
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr,short set,int *anyChange);
|
||||
LOCAL long initialProcess(void);
|
||||
LOCAL long getResources(char *fname);
|
||||
LOCAL int getResourceToken(FILE *fp, char *pToken, unsigned maxToken);
|
||||
@@ -165,15 +169,6 @@ int iocInit(char * pResourceFilename)
|
||||
* Print out version of iocCore
|
||||
*/
|
||||
coreRelease();
|
||||
|
||||
/*
|
||||
* Read EPICS environment
|
||||
*/
|
||||
epicsSetEnvParams();
|
||||
|
||||
/* Hook after environment has been set */
|
||||
if (pinitHooks) (*pinitHooks)(INITHOOKafterSetEnvParams);
|
||||
|
||||
/*
|
||||
* Read EPICS resources.
|
||||
*/
|
||||
@@ -829,17 +824,6 @@ LOCAL long initDatabase(void)
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create lock sets for records
|
||||
* A lock set is a set of records that must be locked
|
||||
* with a semaphore so as to prevent mutual exclusion
|
||||
* hazards. Lock sets are determined by examining the
|
||||
* links interconnecting the records. If a link connecting
|
||||
* two records is not an NPP/NMS single-valued input link,
|
||||
* then the two records are considered part of the same
|
||||
* lock set. Records connected by forward links are
|
||||
* definately considered part of the same lockset.
|
||||
*/
|
||||
LOCAL void createLockSets(void)
|
||||
{
|
||||
int i,link;
|
||||
@@ -853,6 +837,7 @@ LOCAL void createLockSets(void)
|
||||
struct link *plink;
|
||||
short nset,maxnset,newset;
|
||||
int again;
|
||||
int anyChange;
|
||||
|
||||
nset = 0;
|
||||
if(!(precHeader = pdbBase->precHeader)) return;
|
||||
@@ -873,7 +858,6 @@ LOCAL void createLockSets(void)
|
||||
* We shall see later if this assumption is incorrect.
|
||||
*/
|
||||
precord->lset = maxnset = ++nset;
|
||||
|
||||
/*
|
||||
* Use the process active flag to eliminate traversing
|
||||
* cycles in the database "graph"
|
||||
@@ -881,7 +865,7 @@ LOCAL void createLockSets(void)
|
||||
precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
again = FALSE;
|
||||
for(link=0; link<precTypDes->no_links; link++) {
|
||||
for(link=0; (link<precTypDes->no_links&&!again) ; link++) {
|
||||
struct dbAddr *pdbAddr;
|
||||
|
||||
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
|
||||
@@ -910,7 +894,7 @@ LOCAL void createLockSets(void)
|
||||
* Combine the lock sets of the current record with the
|
||||
* remote record pointed to by the link. (recursively)
|
||||
*/
|
||||
newset = makeSameSet(pdbAddr,precord->lset);
|
||||
newset = makeSameSet(pdbAddr,precord->lset,&anyChange);
|
||||
|
||||
/*
|
||||
* Perform an iteration of the while-loop again
|
||||
@@ -930,10 +914,70 @@ LOCAL void createLockSets(void)
|
||||
precord->pact = FALSE;
|
||||
}
|
||||
}
|
||||
anyChange = TRUE;
|
||||
while(anyChange) {
|
||||
anyChange = FALSE;
|
||||
createLockSetsExtraPass(&anyChange);
|
||||
}
|
||||
dbScanLockInit(nset);
|
||||
}
|
||||
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
|
||||
LOCAL void createLockSetsExtraPass(int *anyChange)
|
||||
{
|
||||
int i,link;
|
||||
struct recLoc *precLoc;
|
||||
struct recDes *precDes;
|
||||
struct recTypDes *precTypDes;
|
||||
struct recHeader *precHeader;
|
||||
RECNODE *precNode;
|
||||
struct fldDes *pfldDes;
|
||||
struct dbCommon *precord;
|
||||
struct link *plink;
|
||||
int again;
|
||||
|
||||
if(!(precHeader = pdbBase->precHeader)) return;
|
||||
if(!(precDes = pdbBase->precDes)) return;
|
||||
for(i=0; i< (precHeader->number); i++) {
|
||||
if(!(precLoc = precHeader->papRecLoc[i]))continue;
|
||||
if(!precLoc->preclist) continue;
|
||||
precTypDes = precDes->papRecTypDes[i];
|
||||
for(precNode=(RECNODE *)ellFirst(precLoc->preclist);
|
||||
precNode; precNode = (RECNODE *)ellNext(&precNode->node)) {
|
||||
precord = precNode->precord;
|
||||
if(!(precord->name[0])) continue;
|
||||
/*Prevent cycles in database graph*/
|
||||
precord->pact = TRUE; again = TRUE;
|
||||
while(again) {
|
||||
short newset;
|
||||
|
||||
again = FALSE;
|
||||
for(link=0; (link<precTypDes->no_links&&!again) ; link++) {
|
||||
struct dbAddr *pdbAddr;
|
||||
|
||||
pfldDes = precTypDes->papFldDes[precTypDes->link_ind[link]];
|
||||
plink = (struct link *)((char *)precord + pfldDes->offset);
|
||||
if(plink->type != DB_LINK) continue;
|
||||
pdbAddr = (struct dbAddr *)(plink->value.db_link.pdbAddr);
|
||||
if (pfldDes->field_type==DBF_INLINK
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr))
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
|
||||
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
|
||||
if (newset!=precord->lset) {
|
||||
precord->lset = newset;
|
||||
*anyChange = TRUE;
|
||||
again = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
precord->pact = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL short makeSameSet(struct dbAddr *paddr, short lset,int *anyChange)
|
||||
{
|
||||
struct dbCommon *precord = paddr->precord;
|
||||
short link;
|
||||
@@ -943,12 +987,7 @@ LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
|
||||
struct recDes *precDes;
|
||||
int again;
|
||||
|
||||
/*
|
||||
* Use the process active flag to eliminate traversing
|
||||
* cycles in the database "graph." Effectively converts
|
||||
* the arbitrary database "graph" (where edges are
|
||||
* defined as links) into a tree structure.
|
||||
*/
|
||||
/*Prevent cycles in database graph*/
|
||||
if(precord->pact) return(((precord->lset<lset) ? precord->lset : lset));
|
||||
|
||||
/*
|
||||
@@ -988,10 +1027,11 @@ LOCAL short makeSameSet(struct dbAddr *paddr, short lset)
|
||||
&& ( !(plink->value.db_link.process_passive)
|
||||
&& !(plink->value.db_link.maximize_sevr) )
|
||||
&& pdbAddr->no_elements<=1) continue;
|
||||
newset = makeSameSet(pdbAddr,precord->lset);
|
||||
newset = makeSameSet(pdbAddr,precord->lset,anyChange);
|
||||
if(newset != precord->lset) {
|
||||
precord->lset = newset;
|
||||
again = TRUE;
|
||||
*anyChange = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,10 +328,8 @@ void recGblFwdLink(void *precord)
|
||||
dbScanPassive(precord,paddr->precord);
|
||||
}
|
||||
/*Handle dbPutFieldNotify record completions*/
|
||||
if(pdbc->ppn) {
|
||||
/*Note: dbNotifyCancel also handles rpro*/
|
||||
dbNotifyCompletion(pdbc->ppn);
|
||||
} else if(pdbc->rpro) {
|
||||
if(pdbc->ppn) dbNotifyCompletion(pdbc);
|
||||
if(pdbc->rpro) {
|
||||
/*If anyone requested reprocessing do it*/
|
||||
pdbc->rpro = FALSE;
|
||||
scanOnce(pdbc);
|
||||
@@ -344,7 +342,6 @@ void recGblFwdLink(void *precord)
|
||||
void recGblGetTimeStamp(void* prec)
|
||||
{
|
||||
struct dbCommon* pr = (struct dbCommon*)prec;
|
||||
long status;
|
||||
long nRequest=1;
|
||||
long options=0;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <stdio.h>
|
||||
#include <ellLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <sysLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <errMdef.h>
|
||||
@@ -166,7 +167,7 @@ static void taskwdTask(void)
|
||||
|
||||
pname = taskName(pt->id.tid);
|
||||
if(!pt->suspended) {
|
||||
struct task_list *ptany,*anynext;
|
||||
struct task_list *ptany;
|
||||
|
||||
pt->suspended = TRUE;
|
||||
sprintf(message,"task %x %s suspended",pt->id.tid,pname);
|
||||
@@ -205,7 +206,7 @@ static struct task_list *allocList(void)
|
||||
|
||||
FASTLOCK(&alloclock);
|
||||
if(freeHead) {
|
||||
(void *)pt = (void *)freeHead;
|
||||
pt = (struct task_list *)freeHead;
|
||||
freeHead = freeHead->next;
|
||||
} else pt = calloc(1,sizeof(struct task_list));
|
||||
if(pt==NULL) {
|
||||
|
||||
@@ -9,9 +9,9 @@ LEXOPT = -L
|
||||
|
||||
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
|
||||
dbLoadRecords_lex.c dbLoadRecords.c
|
||||
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
LIBOBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
|
||||
PROD = dbSubs
|
||||
LIBNAME = dbSubs
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
@@ -29,7 +29,4 @@ clean::
|
||||
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \
|
||||
dbLoadRecords.c
|
||||
|
||||
dbSubs: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
|
||||
pvname [a-zA-Z0-9_~\-:\.\[\]<>;]
|
||||
value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
|
||||
%{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
value [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
|
||||
value [a-zA-Z0-9_~\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
|
||||
word [a-zA-Z0-9_\.\^~/\*#\[\]%:;!|\-&\$\(\)@\?\+<>]
|
||||
par [\"\']
|
||||
|
||||
|
||||
@@ -106,113 +106,109 @@ SRCS.c += ../devABBINARY.c
|
||||
SRCS.c += ../devABStatus.c
|
||||
SRCS.c += ../devMpc.c
|
||||
|
||||
# OBJS += devAaiCamac.o
|
||||
# OBJS += devAiCamac.o
|
||||
OBJS += devAiDvx2502.o
|
||||
OBJS += devAiKscV215.o
|
||||
OBJS += devAiSoft.o
|
||||
OBJS += devAiSoftRaw.o
|
||||
OBJS += devAiSymb.o
|
||||
OBJS += devAiTestAsyn.o
|
||||
OBJS += devAiXy566Di.o
|
||||
OBJS += devAiXy566DiL.o
|
||||
OBJS += devAiXy566Se.o
|
||||
# OBJS += devAaoCamac.o
|
||||
# OBJS += devAoCamac.o
|
||||
OBJS += devAoSoft.o
|
||||
OBJS += devAoSoftRaw.o
|
||||
OBJS += devAoSymb.o
|
||||
OBJS += devAoTestAsyn.o
|
||||
OBJS += devAoVmiVme4100.o
|
||||
OBJS += devApsEg.o
|
||||
OBJS += devApsEr.o
|
||||
OBJS += devAt5Vxi.o
|
||||
OBJS += devAt8Fp.o
|
||||
OBJS += devAvme9440.o
|
||||
# OBJS += devBiCamac.o
|
||||
OBJS += devBiMpv910.o
|
||||
OBJS += devBiSoft.o
|
||||
OBJS += devBiSoftRaw.o
|
||||
OBJS += devBiTestAsyn.o
|
||||
OBJS += devBiXVme210.o
|
||||
# OBJS += devBoCamac.o
|
||||
OBJS += devBoMpv902.o
|
||||
OBJS += devBoSoft.o
|
||||
OBJS += devBoSoftRaw.o
|
||||
OBJS += devBoTestAsyn.o
|
||||
OBJS += devBoXVme220.o
|
||||
OBJS += devCommonGpib.o
|
||||
OBJS += devEventSoft.o
|
||||
OBJS += devEventTestIoEvent.o
|
||||
OBJS += devHistogramSoft.o
|
||||
OBJS += devHistogramTestAsyn.o
|
||||
OBJS += devHpe1368a.o
|
||||
# OBJS += devLiCamac.o
|
||||
OBJS += devLiSoft.o
|
||||
OBJS += devLiSymb.o
|
||||
# OBJS += devLoCamac.o
|
||||
OBJS += devLoSoft.o
|
||||
OBJS += devLoSymb.o
|
||||
# OBJS += devMbbiCamac.o
|
||||
# OBJS += devMbbiDirectCamac.o
|
||||
OBJS += devMbbiDirectMpv910.o
|
||||
OBJS += devMbbiDirectSoft.o
|
||||
OBJS += devMbbiDirectSoftRaw.o
|
||||
OBJS += devMbbiDirectXVme210.o
|
||||
OBJS += devMbbiMpv910.o
|
||||
OBJS += devMbbiSoft.o
|
||||
OBJS += devMbbiSoftRaw.o
|
||||
OBJS += devMbbiTestAsyn.o
|
||||
OBJS += devMbbiXVme210.o
|
||||
# OBJS += devMbboCamac.o
|
||||
# OBJS += devMbboDirectCamac.o
|
||||
OBJS += devMbboDirectMpv902.o
|
||||
OBJS += devMbboDirectSoft.o
|
||||
OBJS += devMbboDirectSoftRaw.o
|
||||
OBJS += devMbboDirectXVme220.o
|
||||
OBJS += devMbboMpv902.o
|
||||
OBJS += devMbboSoft.o
|
||||
OBJS += devMbboSoftRaw.o
|
||||
OBJS += devMbboTestAsyn.o
|
||||
OBJS += devMbboXVme220.o
|
||||
OBJS += devMz8310.o
|
||||
OBJS += devPtSoft.o
|
||||
OBJS += devSASoft.o
|
||||
OBJS += devSiSoft.o
|
||||
OBJS += devSiSymb.o
|
||||
OBJS += devSiTestAsyn.o
|
||||
OBJS += devSmCompumotor1830.o
|
||||
OBJS += devSmOms6Axis.o
|
||||
OBJS += devSoSoft.o
|
||||
OBJS += devSoSymb.o
|
||||
OBJS += devSoTestAsyn.o
|
||||
OBJS += devSysmon.o
|
||||
OBJS += devTimerMz8310.o
|
||||
OBJS += devVxiTDM.o
|
||||
# OBJS += devWfCamac.o
|
||||
OBJS += devWfComet.o
|
||||
OBJS += devWfDvx2502.o
|
||||
OBJS += devWfJoergerVtr1.o
|
||||
OBJS += devWfSoft.o
|
||||
OBJS += devWfTestAsyn.o
|
||||
OBJS += devWfXy566Sc.o
|
||||
OBJS += devWfPentek4261.o
|
||||
OBJS += devXy240.o
|
||||
OBJS += devAB1771IFE.o
|
||||
OBJS += devAB1771IL.o
|
||||
OBJS += devAB1771IR.o
|
||||
OBJS += devAB1771IXE.o
|
||||
OBJS += devAB1771OFE.o
|
||||
OBJS += devABBINARY.o
|
||||
OBJS += devABStatus.o
|
||||
OBJS += devMpc.o
|
||||
# LIBOBJS += devAaiCamac.o
|
||||
# LIBOBJS += devAiCamac.o
|
||||
LIBOBJS += devAiDvx2502.o
|
||||
LIBOBJS += devAiKscV215.o
|
||||
LIBOBJS += devAiSoft.o
|
||||
LIBOBJS += devAiSoftRaw.o
|
||||
LIBOBJS += devAiSymb.o
|
||||
LIBOBJS += devAiTestAsyn.o
|
||||
LIBOBJS += devAiXy566Di.o
|
||||
LIBOBJS += devAiXy566DiL.o
|
||||
LIBOBJS += devAiXy566Se.o
|
||||
# LIBOBJS += devAaoCamac.o
|
||||
# LIBOBJS += devAoCamac.o
|
||||
LIBOBJS += devAoSoft.o
|
||||
LIBOBJS += devAoSoftRaw.o
|
||||
LIBOBJS += devAoSymb.o
|
||||
LIBOBJS += devAoTestAsyn.o
|
||||
LIBOBJS += devAoVmiVme4100.o
|
||||
LIBOBJS += devApsEg.o
|
||||
LIBOBJS += devApsEr.o
|
||||
LIBOBJS += devAt5Vxi.o
|
||||
LIBOBJS += devAt8Fp.o
|
||||
LIBOBJS += devAvme9440.o
|
||||
# LIBOBJS += devBiCamac.o
|
||||
LIBOBJS += devBiMpv910.o
|
||||
LIBOBJS += devBiSoft.o
|
||||
LIBOBJS += devBiSoftRaw.o
|
||||
LIBOBJS += devBiTestAsyn.o
|
||||
LIBOBJS += devBiXVme210.o
|
||||
# LIBOBJS += devBoCamac.o
|
||||
LIBOBJS += devBoMpv902.o
|
||||
LIBOBJS += devBoSoft.o
|
||||
LIBOBJS += devBoSoftRaw.o
|
||||
LIBOBJS += devBoTestAsyn.o
|
||||
LIBOBJS += devBoXVme220.o
|
||||
LIBOBJS += devCommonGpib.o
|
||||
LIBOBJS += devEventSoft.o
|
||||
LIBOBJS += devEventTestIoEvent.o
|
||||
LIBOBJS += devHistogramSoft.o
|
||||
LIBOBJS += devHistogramTestAsyn.o
|
||||
LIBOBJS += devHpe1368a.o
|
||||
# LIBOBJS += devLiCamac.o
|
||||
LIBOBJS += devLiSoft.o
|
||||
LIBOBJS += devLiSymb.o
|
||||
# LIBOBJS += devLoCamac.o
|
||||
LIBOBJS += devLoSoft.o
|
||||
LIBOBJS += devLoSymb.o
|
||||
# LIBOBJS += devMbbiCamac.o
|
||||
# LIBOBJS += devMbbiDirectCamac.o
|
||||
LIBOBJS += devMbbiDirectMpv910.o
|
||||
LIBOBJS += devMbbiDirectSoft.o
|
||||
LIBOBJS += devMbbiDirectSoftRaw.o
|
||||
LIBOBJS += devMbbiDirectXVme210.o
|
||||
LIBOBJS += devMbbiMpv910.o
|
||||
LIBOBJS += devMbbiSoft.o
|
||||
LIBOBJS += devMbbiSoftRaw.o
|
||||
LIBOBJS += devMbbiTestAsyn.o
|
||||
LIBOBJS += devMbbiXVme210.o
|
||||
# LIBOBJS += devMbboCamac.o
|
||||
# LIBOBJS += devMbboDirectCamac.o
|
||||
LIBOBJS += devMbboDirectMpv902.o
|
||||
LIBOBJS += devMbboDirectSoft.o
|
||||
LIBOBJS += devMbboDirectSoftRaw.o
|
||||
LIBOBJS += devMbboDirectXVme220.o
|
||||
LIBOBJS += devMbboMpv902.o
|
||||
LIBOBJS += devMbboSoft.o
|
||||
LIBOBJS += devMbboSoftRaw.o
|
||||
LIBOBJS += devMbboTestAsyn.o
|
||||
LIBOBJS += devMbboXVme220.o
|
||||
LIBOBJS += devMz8310.o
|
||||
LIBOBJS += devPtSoft.o
|
||||
LIBOBJS += devSASoft.o
|
||||
LIBOBJS += devSiSoft.o
|
||||
LIBOBJS += devSiSymb.o
|
||||
LIBOBJS += devSiTestAsyn.o
|
||||
LIBOBJS += devSmCompumotor1830.o
|
||||
LIBOBJS += devSmOms6Axis.o
|
||||
LIBOBJS += devSoSoft.o
|
||||
LIBOBJS += devSoSymb.o
|
||||
LIBOBJS += devSoTestAsyn.o
|
||||
LIBOBJS += devSysmon.o
|
||||
LIBOBJS += devTimerMz8310.o
|
||||
LIBOBJS += devVxiTDM.o
|
||||
# LIBOBJS += devWfCamac.o
|
||||
LIBOBJS += devWfComet.o
|
||||
LIBOBJS += devWfDvx2502.o
|
||||
LIBOBJS += devWfJoergerVtr1.o
|
||||
LIBOBJS += devWfSoft.o
|
||||
LIBOBJS += devWfTestAsyn.o
|
||||
LIBOBJS += devWfXy566Sc.o
|
||||
LIBOBJS += devWfPentek4261.o
|
||||
LIBOBJS += devXy240.o
|
||||
LIBOBJS += devAB1771IFE.o
|
||||
LIBOBJS += devAB1771IL.o
|
||||
LIBOBJS += devAB1771IR.o
|
||||
LIBOBJS += devAB1771IXE.o
|
||||
LIBOBJS += devAB1771OFE.o
|
||||
LIBOBJS += devABBINARY.o
|
||||
LIBOBJS += devABStatus.o
|
||||
LIBOBJS += devMpc.o
|
||||
|
||||
PROD = devSup
|
||||
LIBNAME = devSup
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
$(PROD): $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
|
||||
@@ -137,8 +137,8 @@ LOCAL long init_1771Ofe(struct aoRecord *prec)
|
||||
"devAiAb1771Ife (init_record) startScan");
|
||||
break;
|
||||
}
|
||||
/*wait for up to 1 seconds*/
|
||||
for(failed=0; failed<10; failed++) {
|
||||
/*wait for up to 3 seconds*/
|
||||
for(failed=0; failed<30; failed++) {
|
||||
taskDelay(vxTicksPerSecond/10);
|
||||
drvStatus = (*pabDrv->getStatus)(drvPvt);
|
||||
if(drvStatus==abSuccess) {
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.24 1995/03/10 16:55:40 winans
|
||||
* Added waveform writing support
|
||||
*
|
||||
* Revision 1.23 1995/01/06 16:55:52 winans
|
||||
* Added the log parameter to the doc
|
||||
*
|
||||
@@ -1302,13 +1305,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1353,13 +1350,7 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_aiGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1404,13 +1395,7 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1452,13 +1437,7 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(IDLE);
|
||||
}
|
||||
@@ -1489,13 +1468,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1540,13 +1513,7 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_liGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1590,13 +1557,7 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1638,13 +1599,7 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -1671,13 +1626,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else /* interpret response that came back */
|
||||
{
|
||||
@@ -1720,13 +1669,7 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_biGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1773,13 +1716,7 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1821,14 +1758,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(IDLE);
|
||||
}
|
||||
@@ -1856,13 +1786,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1907,13 +1831,7 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_mbbiGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -1960,13 +1878,7 @@ struct gpibDpvt *pdpvt;
|
||||
devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -2009,14 +1921,8 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -2046,13 +1952,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2097,13 +1997,7 @@ int srqStatus;
|
||||
{
|
||||
devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
devGpibLib_stringinGpibFinish(pdpvt); /* and finish the processing */
|
||||
@@ -2139,13 +2033,7 @@ struct gpibDpvt *pdpvt;
|
||||
psi->val[40] = '\0';
|
||||
psi->udf = FALSE;
|
||||
}
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -2185,14 +2073,8 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM);
|
||||
}
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
#if 1
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
#else
|
||||
pdpvt->head.header.callback.callback = devGpibLib_processCallback;
|
||||
pdpvt->head.header.callback.priority = priorityLow;
|
||||
callbackRequest(&pdpvt->head.header.callback);
|
||||
#endif
|
||||
return(IDLE);
|
||||
}
|
||||
|
||||
@@ -2225,7 +2107,7 @@ unsigned short val; /* used for EFAST operations only */
|
||||
bbnode = pdpvt->head.bitBusDpvt->txMsg.node;
|
||||
|
||||
/*
|
||||
* check to see if this node has timed out within last 10 sec
|
||||
* check to see if this node has timed out within last <timeWindow> ticks
|
||||
*/
|
||||
if(tickGet() < (pdpvt->phwpvt->tmoVal + parmBlock->timeWindow) )
|
||||
{
|
||||
@@ -2679,8 +2561,7 @@ struct gpibDpvt *pdpvt;
|
||||
{
|
||||
devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM);
|
||||
}
|
||||
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ struct card {
|
||||
int word_clock;
|
||||
unsigned long clock_freq;
|
||||
int soc;
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
typedef struct card CARD;
|
||||
|
||||
@@ -231,7 +232,6 @@ struct pvt_area {
|
||||
typedef struct pvt_area PVT_AREA;
|
||||
|
||||
static long dev_report(int level);
|
||||
static long dev_init(int after);
|
||||
static long dev_init_rec(struct waveformRecord* pr);
|
||||
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt);
|
||||
static long dev_read(struct waveformRecord* pr);
|
||||
@@ -256,9 +256,9 @@ typedef struct {
|
||||
} ADC_DSET;
|
||||
|
||||
ADC_DSET devWfPentek4261=
|
||||
{6,dev_report,dev_init,dev_init_rec,dev_ioint_info,dev_read,NULL};
|
||||
{6,dev_report,NULL,dev_init_rec,dev_ioint_info,dev_read,NULL};
|
||||
|
||||
static IOSCANPVT ioscanpvt;
|
||||
/* this is a bug! there should be one per card! */
|
||||
static CARD** cards=0;
|
||||
|
||||
static void callback(CALLBACK* cback)
|
||||
@@ -311,14 +311,6 @@ static long dev_report(int level)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_init(int after)
|
||||
{
|
||||
if(after) return(0);
|
||||
scanIoInit(&ioscanpvt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dev_init_rec(struct waveformRecord* pr)
|
||||
{
|
||||
volatile ADC* adc_regs;
|
||||
@@ -524,7 +516,7 @@ static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt)
|
||||
else /* CMD_DELETED */
|
||||
buffer_reset(pvt); /* ensure that we are in a good state */
|
||||
|
||||
*iopvt=ioscanpvt;
|
||||
*iopvt=(cards[pvt->card])->ioscanpvt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -711,7 +703,7 @@ static void irq_func(void* v)
|
||||
pvt->adc_regs->trigger=trig|0x02; /* force reset run FF */
|
||||
|
||||
if(pr->scan==SCAN_IO_EVENT)
|
||||
scanIoRequest(ioscanpvt); /* scan EPICS record */
|
||||
scanIoRequest((cards[pvt->card])->ioscanpvt); /* scan EPICS records */
|
||||
else
|
||||
callbackRequest(cb);
|
||||
}
|
||||
@@ -754,5 +746,6 @@ void ConfigurePentekADC( int card,
|
||||
/* card not really present */
|
||||
cards[card]->in_use=1;
|
||||
}
|
||||
scanIoInit(&(cards[card]->ioscanpvt));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,22 +15,20 @@ SRCS.c += ../devXxDc5009Gpib.c
|
||||
SRCS.c += ../devXxK263Gpib.c
|
||||
SRCS.c += ../devXxSkeletonGpib.c
|
||||
|
||||
OBJS += devAnalytekGpib.o
|
||||
OBJS += devXxDg535Gpib.o
|
||||
OBJS += devBBInteract.o
|
||||
OBJS += devGpibInteract.o
|
||||
OBJS += devXxSr620Gpib.o
|
||||
OBJS += devK486Gpib.o
|
||||
OBJS += devXxK196Gpib.o
|
||||
OBJS += devXxDc5009Gpib.o
|
||||
OBJS += devXxK263Gpib.o
|
||||
OBJS += devXxSkeletonGpib.o
|
||||
LIBOBJS += devAnalytekGpib.o
|
||||
LIBOBJS += devXxDg535Gpib.o
|
||||
LIBOBJS += devBBInteract.o
|
||||
LIBOBJS += devGpibInteract.o
|
||||
LIBOBJS += devXxSr620Gpib.o
|
||||
LIBOBJS += devK486Gpib.o
|
||||
LIBOBJS += devXxK196Gpib.o
|
||||
LIBOBJS += devXxDc5009Gpib.o
|
||||
LIBOBJS += devXxK263Gpib.o
|
||||
LIBOBJS += devXxSkeletonGpib.o
|
||||
|
||||
PROD = devLibOpt $(OBJS)
|
||||
LIBNAME = devLibOpt
|
||||
|
||||
PROD = $(LIBOBJS)
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
devLibOpt: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
@@ -253,6 +253,7 @@ typedef struct {
|
||||
unsigned short baud_rate;
|
||||
unsigned short int_vector;
|
||||
unsigned short int_level;
|
||||
unsigned short autoconfig;
|
||||
unsigned short scan_list_len;
|
||||
unsigned char scan_list[64];
|
||||
} ab_config;
|
||||
@@ -740,6 +741,7 @@ LOCAL void config_init(ab_link *plink)
|
||||
p6008 += plink->link;
|
||||
pconfig->base_address = (void *)p6008;
|
||||
pconfig->baud_rate = DEF_RATE;
|
||||
pconfig->autoconfig = FALSE;
|
||||
pconfig->int_vector = AB_VEC_BASE + plink->link;
|
||||
pconfig->int_level = AB_INT_LEVEL;
|
||||
pconfig->scan_list_len = 8;
|
||||
@@ -763,6 +765,7 @@ int abConfigVme(int link, int base, int vector, int level)
|
||||
ab_config *pconfig;
|
||||
|
||||
if(link<0 || link>=max_ab_6008s) return(-1);
|
||||
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
|
||||
plink = pab_links[link];
|
||||
if(!plink) plink = allocLink(link);
|
||||
pconfig = plink->pconfig;
|
||||
@@ -778,6 +781,7 @@ int abConfigBaud(int link, int baud)
|
||||
ab_config *pconfig;
|
||||
|
||||
if(link<0 || link>=max_ab_6008s) return(-1);
|
||||
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
|
||||
plink = pab_links[link];
|
||||
if(!plink) plink = allocLink(link);
|
||||
pconfig = plink->pconfig;
|
||||
@@ -785,13 +789,28 @@ int abConfigBaud(int link, int baud)
|
||||
else pconfig->baud_rate = FAST_RATE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int abConfigAuto(int link)
|
||||
{
|
||||
ab_link *plink;
|
||||
ab_config *pconfig;
|
||||
|
||||
if(link<0 || link>=max_ab_6008s) return(-1);
|
||||
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
|
||||
plink = pab_links[link];
|
||||
if(!plink) plink = allocLink(link);
|
||||
pconfig = plink->pconfig;
|
||||
pconfig->autoconfig = TRUE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int abConfigScanList(int link, int scan_list_len, char *scan_list)
|
||||
{
|
||||
ab_link *plink;
|
||||
ab_config *pconfig;
|
||||
|
||||
if(link<0 || link>=max_ab_6008s) return(-1);
|
||||
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
|
||||
plink = pab_links[link];
|
||||
if(!plink) plink = allocLink(link);
|
||||
pconfig = plink->pconfig;
|
||||
@@ -800,6 +819,49 @@ int abConfigScanList(int link, int scan_list_len, char *scan_list)
|
||||
memcpy(pconfig->scan_list,scan_list,scan_list_len);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int abConfigScanListAscii(int link, char *filename,int setRackSize)
|
||||
{
|
||||
FILE *fp;
|
||||
char *scan_list;
|
||||
char buf[80];
|
||||
unsigned rack,group,size;
|
||||
int nItemsRead,nCharsRead,scan_list_len;
|
||||
|
||||
scan_list = abCalloc(64,sizeof(char));
|
||||
fp = fopen(filename,"r");
|
||||
scan_list_len = 0;
|
||||
while(fgets(buf,80,fp)) {
|
||||
if(buf[0] == '#') continue;
|
||||
nItemsRead = sscanf(buf,"%u %u %n",&rack,&group,&nCharsRead);
|
||||
if(nItemsRead!=2) {
|
||||
printf("abConfigScanListAscii: Illegal line %d %s\n",
|
||||
scan_list_len,buf);
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
if(!setRackSize) {
|
||||
size = 0x00;
|
||||
} else if(strstr(&buf[nCharsRead],"1/4")) {
|
||||
size = 0x00;
|
||||
} else if(strstr(&buf[nCharsRead],"1/2")) {
|
||||
size = 0x40;
|
||||
} else if(strstr(&buf[nCharsRead],"3/4")) {
|
||||
size = 0x80;
|
||||
} else if(strstr(&buf[nCharsRead],"Full")) {
|
||||
size = 0xc0;
|
||||
} else {
|
||||
printf("abConfigScanListAscii: Illegal line %d %s\n",
|
||||
scan_list_len,buf);
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
scan_list[scan_list_len] = size | (rack<<2) | group;
|
||||
scan_list_len++;
|
||||
}
|
||||
fclose(fp);
|
||||
return(abConfigScanList(link,scan_list_len,scan_list));
|
||||
}
|
||||
|
||||
LOCAL int ab_driver_init()
|
||||
{
|
||||
@@ -811,6 +873,7 @@ LOCAL int ab_driver_init()
|
||||
int vxstatus;
|
||||
long status;
|
||||
int got_one;
|
||||
char task_name[50];
|
||||
|
||||
if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *));
|
||||
/* check if any of the cards are there */
|
||||
@@ -865,7 +928,8 @@ LOCAL int ab_driver_init()
|
||||
continue;
|
||||
}
|
||||
plink->initialized = TRUE;
|
||||
vxstatus = taskSpawn(ABSCAN_NAME,ABSCAN_PRI,ABSCAN_OPT,
|
||||
sprintf(task_name,"%s%2.2d",ABSCAN_NAME,link);
|
||||
vxstatus = taskSpawn(task_name,ABSCAN_PRI,ABSCAN_OPT,
|
||||
ABSCAN_STACK,(FUNCPTR)abScanTask,(int)plink,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
if(vxstatus < 0){
|
||||
@@ -874,7 +938,8 @@ LOCAL int ab_driver_init()
|
||||
}
|
||||
plink->abScanId = vxstatus;
|
||||
taskwdInsert(plink->abScanId,NULL,NULL);
|
||||
vxstatus = taskSpawn(ABDONE_NAME,ABDONE_PRI,ABDONE_OPT,
|
||||
sprintf(task_name,"%s%2.2d",ABDONE_NAME,link);
|
||||
vxstatus = taskSpawn(task_name,ABDONE_PRI,ABDONE_OPT,
|
||||
ABDONE_STACK,(FUNCPTR)abDoneTask,(int)plink,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
if(vxstatus < 0){
|
||||
@@ -967,7 +1032,19 @@ LOCAL int link_init(ab_link *plink)
|
||||
not nice, but for now we'll have to assume that all
|
||||
adapters are needed and put them all in the scan list. */
|
||||
/* set scan list*/
|
||||
for(ntry=0; ntry<maxCmdTrys; ntry++) {
|
||||
if(pconfig->autoconfig) for(ntry=0; ntry<maxCmdTrys; ntry++) {
|
||||
status = sc_lock(plink);
|
||||
if(status) continue;
|
||||
pmb->command = AUTO_CONF;
|
||||
pmb->data_len = 0;
|
||||
status = sc_waitcmd(plink);
|
||||
if(status) continue;
|
||||
if(pmb->conf_stat != 0) {
|
||||
sc_conferr(plink);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}else for(ntry=0; ntry<maxCmdTrys; ntry++) {
|
||||
status = sc_lock(plink);
|
||||
if(status) continue;
|
||||
pmb->command = SCAN_LIST;
|
||||
@@ -983,7 +1060,7 @@ LOCAL int link_init(ab_link *plink)
|
||||
break;
|
||||
}
|
||||
if(ntry>=maxCmdTrys) {
|
||||
printf("abDrv: SCAN_LIST failed link %hu\n",plink->link);
|
||||
printf("abDrv: AUTO_CONFIG or SCAN_LIST failed link %hu\n",plink->link);
|
||||
return(ERROR);
|
||||
}
|
||||
sc_unlock(plink);
|
||||
@@ -1718,6 +1795,7 @@ LOCAL abStatus cardStatus(
|
||||
plink = pab_links[link];
|
||||
if(!plink || !plink->initialized) return(abFailure);
|
||||
padapter = plink->papadapter[adapter];
|
||||
if(!padapter->adapter_online) return(abAdapterDown);
|
||||
pcard = padapter->papcard[card];
|
||||
if(!pcard) return(abNoCard);
|
||||
if(!padapter->adapter_online) return(abAdapterDown);
|
||||
|
||||
@@ -87,5 +87,7 @@ int abConfigNlinks(int nlinks);
|
||||
int abConfigVme(int link, int base, int vector, int level);
|
||||
int abConfigBaud(int link, int baud);
|
||||
int abConfigScanList(int link, int scan_list_len, char *scan_list);
|
||||
int abConfigScanListAscii(int link, char *filename,int setRackSize);
|
||||
int abConfigAuto(int link);
|
||||
|
||||
#endif /*INCdrvAbh*/
|
||||
|
||||
@@ -71,8 +71,8 @@ epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
|
||||
|
||||
struct hpe1368a_config{
|
||||
FAST_LOCK lock; /* mutual exclusion */
|
||||
unsigned short pending; /* switch position pending int */
|
||||
unsigned short shadow; /* shadow of actual switch pos */
|
||||
uint16_t pending; /* switch position pending int */
|
||||
uint16_t shadow; /* shadow of actual switch pos */
|
||||
int busy; /* relays active */
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
|
||||
@@ -1044,7 +1044,7 @@ unsigned long npoints
|
||||
double dacPeakAmplitude;
|
||||
double dacOffset;
|
||||
double *pwf;
|
||||
unsigned short *pdata_port;
|
||||
uint16_t *pdata_port;
|
||||
|
||||
pdata_port = (unsigned short *) epvxiA24Base(la);
|
||||
pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port));
|
||||
|
||||
@@ -308,6 +308,10 @@ int smRespId; /* task id */
|
||||
/* interrupt buffers */
|
||||
unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ];
|
||||
unsigned short counts[MAX_COMPU_MOTORS];
|
||||
/* counts for debugging */
|
||||
long dbicounts; /* counts number of times through interrupt routine */
|
||||
long dbrcounts; /* counts number of times through response routine */
|
||||
long dbscounts; /* counts number of times through send routine */
|
||||
|
||||
/* VME memory Short Address Space is set up in gta_init */
|
||||
static int *compu_addr;
|
||||
@@ -392,6 +396,7 @@ compu_resp_task()
|
||||
FOREVER {
|
||||
/* wait for somebody to wake us up */
|
||||
semTake (smRespSem, WAIT_FOREVER);
|
||||
(dbrcounts < 0xFFFF ? dbrcounts++: 0);
|
||||
/* the response buffer contains: */
|
||||
/* 0 - motor number */
|
||||
/* 1 - the command which solicited this response */
|
||||
@@ -522,7 +527,12 @@ register int mdnum;
|
||||
|
||||
/* pointer to the compumotor card interface */
|
||||
pmtr = pcompu_motors[mdnum];
|
||||
|
||||
if (pmtr == 0)
|
||||
{
|
||||
intUnlock(key);
|
||||
return(0);
|
||||
};
|
||||
(dbicounts < 0xFFFF ? dbicounts++: 0);
|
||||
/* place the response byte into the appropriate response buffer */
|
||||
sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb;
|
||||
counts[mdnum]++;
|
||||
@@ -545,6 +555,7 @@ register int mdnum;
|
||||
}
|
||||
|
||||
intUnlock(key);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -621,17 +632,18 @@ short trigger = 0;
|
||||
*
|
||||
* driver interface to the database library layer
|
||||
*/
|
||||
compu_driver(card,value_flag,arg1,arg2)
|
||||
compu_driver(card, channel, value_flag,arg1,arg2)
|
||||
register short card;
|
||||
short channel;
|
||||
short value_flag;
|
||||
register int arg1;
|
||||
register int arg2;
|
||||
{
|
||||
register int *pint;
|
||||
register short *pshort;
|
||||
short j,i;
|
||||
short i;
|
||||
char compu_msg[20];
|
||||
|
||||
i = 0;
|
||||
/* verify the stepper motor driver card is present */
|
||||
if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card]))
|
||||
return (-1);
|
||||
@@ -661,144 +673,16 @@ register int arg2;
|
||||
case (SM_MOVE):
|
||||
if (compu_motor_array[card].mode == VELOCITY_MODE)
|
||||
return(0);
|
||||
i = 0;
|
||||
switch (trigger){
|
||||
case (0):
|
||||
/* move the motor */
|
||||
compu_msg[i++] = SM_MOV_REL_POS;
|
||||
pint = (int *)&compu_msg[i];
|
||||
*pint = arg1;
|
||||
i += 4;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
break;
|
||||
case (1): /* test sequnce buffer */
|
||||
compu_msg[i++] = 0xda; /* delete sequence buffer */
|
||||
compu_msg[i++] = 01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xd9; /* fill sequence buffer */
|
||||
compu_msg[i++] = 01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = SM_MOV_REL_POS;
|
||||
pint = (int *)&compu_msg[i];
|
||||
*pint = arg1;
|
||||
i += 4;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xd8; /* end sequence buffer */
|
||||
compu_msg[i++] = 0x41; /* perform sequence buffer */
|
||||
compu_msg[i++] = 0x01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
break;
|
||||
case (2): /* test move buffer */
|
||||
compu_msg[i++] = 0xc8;
|
||||
compu_msg[i++] = 0x12;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x04;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x04;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
pint = (int *)&compu_msg[i];
|
||||
*pint = arg1;
|
||||
i += 4;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0x40;
|
||||
compu_msg[i++] = 0x12;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
break;
|
||||
case (3): /* test sequence buffer with move buffer */
|
||||
compu_msg[i++] = 0xc8;
|
||||
compu_msg[i++] = 0x12;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x04;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x04;
|
||||
compu_msg[i++] = 0x00;
|
||||
compu_msg[i++] = 0x00;
|
||||
pint = (int *)&compu_msg[i];
|
||||
*pint = arg1;
|
||||
i += 4;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xda; /* delete sequence buffer */
|
||||
compu_msg[i++] = 01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xd9; /* fill sequence buffer */
|
||||
compu_msg[i++] = 01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0x40;
|
||||
compu_msg[i++] = 0x12;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xd8; /* end sequence buffer */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0x41; /* perform sequence buffer */
|
||||
compu_msg[i++] = 0x01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
break;
|
||||
case (4): /* test sequence buffer with move buffer and trigger */
|
||||
compu_msg[i++] = 0xc8;
|
||||
compu_msg[i++] = 0x12;
|
||||
|
||||
compu_msg[i++] = 0x00;
|
||||
/* move the motor */
|
||||
i = 0;
|
||||
compu_msg[i++] = SM_MOV_REL_POS;
|
||||
pint = (int *)&compu_msg[i];
|
||||
*pint = compu_motor_data_array[card].velocity;
|
||||
i += 4;
|
||||
pint++;
|
||||
*pint = compu_motor_data_array[card].accel;
|
||||
i += 4;
|
||||
pint++;
|
||||
*pint = arg1;
|
||||
i += 4;
|
||||
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xda; /* delete sequence buffer */
|
||||
compu_msg[i++] = 01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xd9; /* fill sequence buffer */
|
||||
compu_msg[i++] = 01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0x2c; /* wait for trigger */
|
||||
compu_msg[i++] = 1; /*trigger 1 */
|
||||
compu_msg[i++] = 1; /* don't care about state */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0x40;
|
||||
compu_msg[i++] = 0x12;
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0xd8; /* end sequence buffer */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
compu_msg[i++] = 0x41; /* perform sequence buffer */
|
||||
compu_msg[i++] = 0x01; /* buffer 1 */
|
||||
compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < i; j++){
|
||||
printf("%x ",compu_msg[j]);
|
||||
}
|
||||
/* compu_send_msg(pcompu_motors[card],compu_msg,i);
|
||||
*/
|
||||
|
||||
/* set the motor to active */
|
||||
compu_motor_array[card].active = TRUE;
|
||||
|
||||
@@ -884,6 +768,7 @@ register struct compumotor *pmotor;
|
||||
register char *pmsg;
|
||||
register short count;
|
||||
{
|
||||
(dbscounts < 0xFFFF ? dbscounts++: 0);
|
||||
/* write out this command one byte at a time */
|
||||
while (count){
|
||||
|
||||
@@ -969,4 +854,3 @@ VOID compu_sm_reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
*
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.3 1995/04/25 15:32:23 winans
|
||||
* Changed name of HiDEOS link configuration command/function.
|
||||
*
|
||||
* Revision 1.2 1995/04/12 19:31:41 winans
|
||||
* Added support for the HiDEOS system as a GPIB bus transport agent.
|
||||
*
|
||||
@@ -974,12 +977,36 @@ char *buffer; /* data to transfer */
|
||||
int length; /* number of bytes to transfer */
|
||||
int time; /* time to wait on the DMA operation */
|
||||
{
|
||||
int status;
|
||||
short cnt;
|
||||
register struct ibregs *b;
|
||||
char w_imr2;
|
||||
int temp_addr;
|
||||
int tmoTmp;
|
||||
int status = ERROR;
|
||||
unsigned short cnt;
|
||||
struct ibregs *b;
|
||||
char w_imr2;
|
||||
int temp_addr;
|
||||
int tmoTmp;
|
||||
|
||||
#ifdef NI_GPIB_LOOP_LENGTH
|
||||
#define NI_GPIB_CHUNKSIZE 0x0ffff
|
||||
while (length > 0)
|
||||
{
|
||||
if (length > NI_GPIB_CHUNKSIZE)
|
||||
{
|
||||
cnt = NI_GPIB_CHUNKSIZE;
|
||||
length -= NI_GPIB_CHUNKSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cnt = length;
|
||||
length = 0;
|
||||
}
|
||||
#else
|
||||
cnt = length;
|
||||
|
||||
if (cnt > 0x0fffe)
|
||||
{
|
||||
errMessage(S_IB_SIZE, "NI-1014 max length (65535) exceeded");
|
||||
return(ERROR);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pNiLink[link]->A24BounceBuffer == NULL)
|
||||
{
|
||||
@@ -993,25 +1020,24 @@ int time; /* time to wait on the DMA operation */
|
||||
logMsg("Got a bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer);
|
||||
}
|
||||
|
||||
if (pNiLink[link]->A24BounceSize < length)
|
||||
if (pNiLink[link]->A24BounceSize < cnt)
|
||||
{ /* Reallocate a larger bounce buffer */
|
||||
|
||||
devLibA24Free(pNiLink[link]->A24BounceBuffer); /* Loose the old one */
|
||||
|
||||
if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(length)) == NULL)
|
||||
if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(cnt)) == NULL)
|
||||
{
|
||||
errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!");
|
||||
pNiLink[link]->A24BounceSize = 0;
|
||||
pNiLink[link]->A24BounceBuffer = NULL;
|
||||
return(ERROR);
|
||||
}
|
||||
pNiLink[link]->A24BounceSize = length;
|
||||
pNiLink[link]->A24BounceSize = cnt;
|
||||
if(ibDebug > 5)
|
||||
logMsg("Got a new bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer);
|
||||
}
|
||||
|
||||
b = pNiLink[link]->ibregs;
|
||||
cnt = length;
|
||||
|
||||
b->auxmr = AUX_GTS; /* go to standby mode */
|
||||
b->ch1.ccr = D_SAB; /* halt channel activity */
|
||||
@@ -1049,7 +1075,7 @@ int time; /* time to wait on the DMA operation */
|
||||
else /* (dir == READ) */
|
||||
{
|
||||
/* We will be writing, copy data into the bounce buffer */
|
||||
memcpy(pNiLink[link]->A24BounceBuffer, buffer, length);
|
||||
memcpy(pNiLink[link]->A24BounceBuffer, buffer, cnt);
|
||||
|
||||
if (cnt != 1)
|
||||
pNiLink[link]->DmaStuff->cc_byte = AUX_SEOI; /* send EOI with last byte */
|
||||
@@ -1231,9 +1257,13 @@ int time; /* time to wait on the DMA operation */
|
||||
|
||||
if (dir == READ)
|
||||
{ /* Copy data from the bounce buffer to the user's buffer */
|
||||
memcpy(buffer, pNiLink[link]->A24BounceBuffer, length);
|
||||
memcpy(buffer, pNiLink[link]->A24BounceBuffer, cnt);
|
||||
}
|
||||
#ifdef NI_GPIB_LOOP_LENGTH
|
||||
|
||||
buffer += NI_GPIB_CHUNKSIZE;
|
||||
}
|
||||
#endif
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
@@ -338,13 +338,13 @@ register unsigned int val;
|
||||
/* use structure to handle high and low short swap */
|
||||
/* get current output */
|
||||
|
||||
work = (dio[card].dptr->port6_7 << 16)
|
||||
+ dio[card].dptr->port4_5;
|
||||
work = (dio[card].dptr->port4_5 << 16)
|
||||
+ dio[card].dptr->port6_7;
|
||||
|
||||
work = (work & ~mask) | (val & mask);
|
||||
|
||||
dio[card].dptr->port6_7 = (unsigned short)(work >> 16);
|
||||
dio[card].dptr->port4_5 = (unsigned short)work;
|
||||
dio[card].dptr->port4_5 = (unsigned short)(work >> 16);
|
||||
dio[card].dptr->port6_7 = (unsigned short)work;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ SRCS.c += ../calcPerform.c
|
||||
SRCS.c += ../cvtFast.c
|
||||
SRCS.c += ../ellLib.c
|
||||
SRCS.c += ../envSubr.c
|
||||
SRCS.c += envData.c
|
||||
SRCS.c += ../errInc.c
|
||||
SRCS.c += ../errMtst.c
|
||||
SRCS.c += ../errPrintfUNIX.c
|
||||
@@ -29,6 +30,7 @@ LIBOBJS += calcPerform.o
|
||||
LIBOBJS += cvtFast.o
|
||||
LIBOBJS += ellLib.o
|
||||
LIBOBJS += envSubr.o
|
||||
LIBOBJS += envData.o
|
||||
LIBOBJS += errMtst.o
|
||||
LIBOBJS += errPrintfUNIX.o
|
||||
LIBOBJS += errSymLib.o
|
||||
@@ -54,11 +56,11 @@ errSymTbl.o: errSymTbl.c errInc.o
|
||||
|
||||
errSymTbl.c errInc.o: errInc.c
|
||||
@$(RM) errInc.o
|
||||
@$(EPICS_BASE)/tools/blderrSymTbl;
|
||||
@../blderrSymTbl $(EPICS) $(HOST_ARCH) "$(MAKE)"
|
||||
|
||||
envSubr.o: envData.h
|
||||
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
|
||||
$(EPICS_BASE)/tools/bldEnvData
|
||||
envData.c: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV \
|
||||
$(EPICS)/config/CONFIG_SITE_ENV
|
||||
../bldEnvData $(EPICS)
|
||||
|
||||
pre_build:
|
||||
@test -f errInc.c || ln -s ../errInc.c errInc.c
|
||||
@@ -67,5 +69,5 @@ tsTest: tsSubr.o
|
||||
$(LINK.c) -o $@ tsSubr.o -lCom -lDb -lCom -lm -s
|
||||
|
||||
clean::
|
||||
@$(RM) errInc.c errSymTbl.c envData.h
|
||||
@$(RM) errInc.c errSymTbl.c envData.c
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
SRCS.c += ../calcPerform.c
|
||||
SRCS.c += ../cvtBpt.c
|
||||
SRCS.c += ../cvtFast.c
|
||||
SRCS.c += ../gpHashLib.c
|
||||
SRCS.c += ../freeListLib.c
|
||||
SRCS.c += ../ellLib.c
|
||||
SRCS.c += ../envSubr.c
|
||||
SRCS.c += envData.c
|
||||
SRCS.c += ../errSymLib.c
|
||||
SRCS.c += ../nextFieldSubr.c
|
||||
SRCS.c += ../postfix.c
|
||||
@@ -21,45 +21,41 @@ SRCS.c += errSymTbl.c
|
||||
SRCS.c += ../errPrintfVX.c
|
||||
SRCS.c += ../assertVX.c
|
||||
|
||||
OBJS += calcPerform.o
|
||||
OBJS += cvtBpt.o
|
||||
OBJS += cvtFast.o
|
||||
OBJS += ellLib.o
|
||||
OBJS += envSubr.o
|
||||
OBJS += errSymLib.o
|
||||
OBJS += errSymTbl.o
|
||||
OBJS += nextFieldSubr.o
|
||||
OBJS += postfix.o
|
||||
OBJS += bucketLib.o
|
||||
OBJS += tsSubr.o
|
||||
OBJS += gpHashLib.o
|
||||
OBJS += freeListLib.o
|
||||
OBJS += pal.o
|
||||
OBJS += paldef.o
|
||||
OBJS += errPrintfVX.o
|
||||
OBJS += assertVX.o
|
||||
LIBOBJS += calcPerform.o
|
||||
LIBOBJS += cvtFast.o
|
||||
LIBOBJS += ellLib.o
|
||||
LIBOBJS += envData.o
|
||||
LIBOBJS += envSubr.o
|
||||
LIBOBJS += errSymLib.o
|
||||
LIBOBJS += errSymTbl.o
|
||||
LIBOBJS += nextFieldSubr.o
|
||||
LIBOBJS += postfix.o
|
||||
LIBOBJS += bucketLib.o
|
||||
LIBOBJS += tsSubr.o
|
||||
LIBOBJS += gpHashLib.o
|
||||
LIBOBJS += freeListLib.o
|
||||
LIBOBJS += pal.o
|
||||
LIBOBJS += paldef.o
|
||||
LIBOBJS += errPrintfVX.o
|
||||
LIBOBJS += assertVX.o
|
||||
|
||||
PROD = libCom
|
||||
LIBNAME = libCom
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
clean::
|
||||
@$(RM) errInc.c errSymTbl.c envData.h
|
||||
@$(RM) errInc.c errSymTbl.c envData.c
|
||||
|
||||
build: errSymTbl.o errInc.o
|
||||
|
||||
errSymTbl.c errInc.o: errInc.c
|
||||
@$(RM) errInc.o
|
||||
@$(EPICS_BASE)/tools/blderrSymTbl
|
||||
../blderrSymTbl $(EPICS) $(HOST_ARCH) "$(MAKE)"
|
||||
|
||||
envSubr.o: envData.h
|
||||
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
|
||||
$(EPICS_BASE)/tools/bldEnvData
|
||||
envData.c: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV \
|
||||
$(EPICS)/config/CONFIG_SITE_ENV
|
||||
../bldEnvData $(EPICS)
|
||||
|
||||
pre_build:
|
||||
@test -f errInc.c || ln -s ../errInc.c errInc.c
|
||||
|
||||
libCom: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -58,7 +59,7 @@ void epicsAssert (const char *pFile, const unsigned line, const char *pMsg)
|
||||
"Please contact the author of this software or else send the text of\n");
|
||||
|
||||
epicsPrintf (
|
||||
"this message to \"tech_talk@aps.anl.gov\"\n");
|
||||
"this message to \"tech-talk@aps.anl.gov\"\n");
|
||||
|
||||
abort ();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
@@ -64,7 +65,7 @@ void epicsAssert (const char *pFile, const unsigned line, const char *pMsg)
|
||||
taskId);
|
||||
|
||||
epicsPrintf (
|
||||
"to the author or \"tech_talk@aps.anl.gov\"\n");
|
||||
"to the author or \"tech-talk@aps.anl.gov\"\n");
|
||||
|
||||
taskSuspend (taskId);
|
||||
}
|
||||
|
||||
613
src/libCom/bdt.c
Normal file
613
src/libCom/bdt.c
Normal file
@@ -0,0 +1,613 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef linux
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <in.h>
|
||||
#include <inetLib.h>
|
||||
#include <taskLib.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bdt.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* server mode functions */
|
||||
|
||||
#ifndef vxWorks /* server mode functions */
|
||||
static char* filename=(char*)NULL;
|
||||
|
||||
/* ----------------------------- */
|
||||
/* signal catcher for the server */
|
||||
/* ----------------------------- */
|
||||
static void catch_sig(int sig)
|
||||
{
|
||||
fprintf(stderr,"\nbdt server exiting\n");
|
||||
unlink(filename);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* -------------------------------- */
|
||||
/* child reaper for the server mode */
|
||||
/* -------------------------------- */
|
||||
static void get_child(int sig)
|
||||
{
|
||||
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
|
||||
#ifdef linux
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* Clear the signals for a process */
|
||||
/* ------------------------------- */
|
||||
int BdtServerClearSignals()
|
||||
{
|
||||
signal(SIGCHLD,SIG_DFL);
|
||||
signal(SIGHUP,SIG_DFL);
|
||||
signal(SIGINT,SIG_DFL);
|
||||
signal(SIGTERM,SIG_DFL);
|
||||
signal(SIGQUIT,SIG_DFL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Make a unix process into a generic background process */
|
||||
/* ----------------------------------------------------- */
|
||||
int BdtMakeServer(char** argv)
|
||||
{
|
||||
FILE* fd;
|
||||
|
||||
if(filename) return -1;
|
||||
|
||||
/* set up signal handling for the server */
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
signal(SIGHUP,catch_sig);
|
||||
signal(SIGINT,catch_sig);
|
||||
signal(SIGTERM,catch_sig);
|
||||
signal(SIGQUIT,catch_sig);
|
||||
|
||||
/* disconnect from parent */
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("Cannot fork");
|
||||
return -1;
|
||||
case 0: /* child */
|
||||
#ifdef linux
|
||||
setpgrp();
|
||||
#else
|
||||
setpgrp(0,0);
|
||||
#endif
|
||||
setsid();
|
||||
break;
|
||||
default: /* parent goes away */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* save process ID */
|
||||
filename=(char*)malloc(strlen(argv[0])+10);
|
||||
sprintf(filename,"%s.%d",argv[0],getpid());
|
||||
fd=fopen(filename,"w");
|
||||
fprintf(fd,"%d",getpid());
|
||||
fprintf(stderr,"\npv server pid: %d\n",getpid());
|
||||
fclose(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* server mode functions */
|
||||
|
||||
/* ------------------------------------------ */
|
||||
/* unimplemented channel access open function */
|
||||
/* ------------------------------------------ */
|
||||
BDT* BdtPvOpen(char* name)
|
||||
{
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
/* open a bulk data socket to a server given the server IP address */
|
||||
/* --------------------------------------------------------------- */
|
||||
BDT* BdtIpOpen(char* address, int Port)
|
||||
{
|
||||
struct sockaddr_in tsin;
|
||||
unsigned long addr;
|
||||
int osoc;
|
||||
BDT* bdt;
|
||||
|
||||
/* request the process variables (bulk data?) */
|
||||
addr=inet_addr(address);
|
||||
|
||||
tsin.sin_port=0;
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
|
||||
{
|
||||
perror("BdtIpOpen: create socket failed");
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BdtIpOpen: local address bind failed");
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
tsin.sin_port=htons(Port);
|
||||
memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr));
|
||||
|
||||
if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0)
|
||||
{
|
||||
perror("BdtIpOpen: connect failed");
|
||||
close(osoc);
|
||||
return (BDT*)NULL;
|
||||
}
|
||||
|
||||
bdt=(BDT*)malloc(sizeof(BDT));
|
||||
bdt->soc=osoc;
|
||||
bdt->pending_delta=0;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BdtUnbound;
|
||||
|
||||
/* now connected to the bulk data socket on the IOC */
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* write size bytes from buffer to socket */
|
||||
/* -------------------------------------- */
|
||||
int BdtWrite(int soc,void* buffer,int size)
|
||||
{
|
||||
int rc,total;
|
||||
unsigned char* data;
|
||||
|
||||
data=(unsigned char*)buffer;
|
||||
total=size;
|
||||
|
||||
do
|
||||
{
|
||||
/* send block of data */
|
||||
if((rc=send(soc,&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno==EINTR)
|
||||
rc=0;
|
||||
else
|
||||
{ perror("BdtWrite: Send to remote failed"); }
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* send a message header down a BDT socket */
|
||||
/* --------------------------------------- */
|
||||
int BdtSendHeader(BDT* bdt,unsigned short verb,int size)
|
||||
{
|
||||
BdtMsgHead buf;
|
||||
|
||||
if(bdt->state!=BdtIdle)
|
||||
{
|
||||
fprintf(stderr,"BdtSendHeader: Interface not idle\n");
|
||||
bdt->state=BdtBad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf.verb=htons(verb);
|
||||
buf.size=htonl((unsigned long)size);
|
||||
|
||||
if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't wait for response if data must go out */
|
||||
if(size)
|
||||
{
|
||||
bdt->remaining_send=size;
|
||||
bdt->state=BdtSData;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------- */
|
||||
/* send a message data chunk down a BDT socket */
|
||||
/* ------------------------------------------- */
|
||||
int BdtSendData(BDT* bdt,void* buffer,int size)
|
||||
{
|
||||
int len,remaining,rc;
|
||||
|
||||
if(bdt->state!=BdtSData)
|
||||
{
|
||||
fprintf(stderr,"BdtSendData: Interface not in send data mode\n");
|
||||
bdt->state=BdtBad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
remaining=bdt->remaining_send-size;
|
||||
|
||||
if(remaining<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendData: To much data to send\n");
|
||||
len=bdt->remaining_send;
|
||||
}
|
||||
else
|
||||
len=size;
|
||||
|
||||
/* this function should loop until size bytes is sent */
|
||||
|
||||
/* send out the chunk */
|
||||
if((rc=send(bdt->soc,(char*)buffer,len,0))<0)
|
||||
{
|
||||
perror("BdtSendData: Send data chunk to remote failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bdt->remaining_send-=rc;
|
||||
|
||||
if(bdt->remaining_send<0)
|
||||
{
|
||||
fprintf(stderr,"BdtSendData: To much data Sent\n");
|
||||
bdt->remaining_send=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_send==0)
|
||||
bdt->state=BdtIdle;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
report if data is pending from remote
|
||||
clear the pending data condition
|
||||
------------------------------------------------------------------------ */
|
||||
int BdtPvDeltaPending(BDT* bdt)
|
||||
{
|
||||
int rc = bdt->pending_delta;
|
||||
bdt->pending_delta=0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* Read exactly size bytes from remote */
|
||||
/* ------------------------------------- */
|
||||
int BdtRead(int soc,void* buffer,int size)
|
||||
{
|
||||
int rc,total;
|
||||
unsigned char* data;
|
||||
|
||||
data=(unsigned char*)buffer;
|
||||
total=size;
|
||||
|
||||
do
|
||||
{
|
||||
/* wait for data chunk */
|
||||
if((rc=recv(soc,&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno==EINTR)
|
||||
rc=0;
|
||||
else
|
||||
{ perror("BdtRead: Receive data chunk failed"); }
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* wait for a message header from remote */
|
||||
/* ------------------------------------- */
|
||||
int BdtReceiveHeader(BDT* bdt,int* verb,int* size)
|
||||
{
|
||||
BdtMsgHead buf;
|
||||
|
||||
/* can only receive header when in the idle state */
|
||||
if (bdt->state == BdtEof)
|
||||
return -1;
|
||||
|
||||
if(bdt->state != BdtIdle)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveHeader: Interface not idle\n");
|
||||
bdt->state=BdtBad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy message data to user */
|
||||
*verb=ntohs(buf.verb);
|
||||
*size=ntohl(buf.size);
|
||||
|
||||
if(*size)
|
||||
bdt->state=BdtRData;
|
||||
|
||||
bdt->remaining_recv=*size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Wait for a chunk of data from remote.
|
||||
User can continually call this with a maximum size until it return 0.
|
||||
------------------------------------------------------------------------ */
|
||||
int BdtReceiveData(BDT* bdt,void* buffer,int size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* can only receive data when in the receive data state */
|
||||
switch(bdt->state)
|
||||
{
|
||||
case BdtRData: break;
|
||||
case BdtIdle: return 0;
|
||||
default:
|
||||
fprintf(stderr,"BdtReceiveData: bad receive state\n");
|
||||
bdt->state=BdtBad;
|
||||
break;
|
||||
}
|
||||
|
||||
if(BdtRead(bdt->soc,buffer,size)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveData: Read failed\n");
|
||||
bdt->state = BdtEof;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bdt->remaining_recv-=size;
|
||||
|
||||
if(bdt->remaining_recv<0)
|
||||
{
|
||||
fprintf(stderr,"BdtReceiveData: To much data received\n");
|
||||
bdt->remaining_recv=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_recv==0)
|
||||
bdt->state=BdtIdle;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* connect to a process variable, useful if raw open used */
|
||||
/* ------------------------------------------------------ */
|
||||
int BdtServiceConnect(BDT* bdt, char* service_name)
|
||||
{
|
||||
int len,rc,size,verb;
|
||||
|
||||
if(bdt->state!=BdtUnbound)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: can only bind to one service\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bdt->state=BdtIdle;
|
||||
len=strlen(service_name)+1;
|
||||
|
||||
/* send out connect message */
|
||||
if(BdtSendHeader(bdt,BDT_Connect,len)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: send of connect header failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send out the process variable to connect to */
|
||||
if(BdtSendData(bdt,service_name,len)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: send of connect body failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc=0;
|
||||
|
||||
/* wait for response from connect to process variable */
|
||||
if(BdtReceiveHeader(bdt,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtServiceConnect: receive reponse failed\n");
|
||||
bdt->state=BdtUnbound;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check response */
|
||||
switch(verb)
|
||||
{
|
||||
case BDT_Ok:
|
||||
rc=0;
|
||||
break;
|
||||
case BDT_Error:
|
||||
fprintf(stderr,"BdtServiceConnect: connection rejected\n");
|
||||
bdt->state=BdtUnbound;
|
||||
rc=-1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"BdtServiceConnect: unknown response from remote\n");
|
||||
bdt->state=BdtUnbound;
|
||||
rc=-1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------- */
|
||||
/* close the connection */
|
||||
/* -------------------- */
|
||||
int BdtClose(BDT* bdt)
|
||||
{
|
||||
int verb,size,done;
|
||||
|
||||
/* send a close message out */
|
||||
if(BdtSendHeader(bdt,BDT_Close,0)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtClose: Cannot send close message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
done=0;
|
||||
|
||||
do
|
||||
{
|
||||
/* check response */
|
||||
if(BdtReceiveHeader(bdt,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"BdtClose: Close message response error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case BDT_Ok:
|
||||
done=1;
|
||||
break;
|
||||
case BDT_Error:
|
||||
fprintf(stderr,"BdtClose: Close rejected\n");
|
||||
return -1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
while(done==0);
|
||||
|
||||
bdt->state=BdtUnbound;
|
||||
free(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for UDP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BdtOpenListenerUDP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
tsin.sin_port=htons(Port);
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0)
|
||||
{
|
||||
perror("BdtOpenListenerUDP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BdtOpenListenerUDP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for TCP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BdtOpenListenerTCP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
memset (&tsin, 0, sizeof(struct sockaddr_in));
|
||||
tsin.sin_port=htons(Port);
|
||||
tsin.sin_family=htons(AF_INET);
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0)
|
||||
{
|
||||
perror("BdtOpenListenerTCP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BdtOpenListenerTCP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen(nsoc,5);
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* make BDT from a socket - simple */
|
||||
/* ------------------------------- */
|
||||
BDT* BdtMakeBDT(int soc)
|
||||
{
|
||||
BDT* bdt;
|
||||
bdt=(BDT*)malloc(sizeof(BDT));
|
||||
bdt->soc=soc;
|
||||
bdt->pending_delta=0;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BdtIdle;
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* --------------------------- */
|
||||
/* free a BDT and close socket */
|
||||
/* --------------------------- */
|
||||
int BdtFreeBDT(BDT* bdt)
|
||||
{
|
||||
close(bdt->soc);
|
||||
free(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* connect to a generic service on the remote server */
|
||||
/* ------------------------------------------------- */
|
||||
int BdtPvConnect(BDT* bdt, char* pv_name)
|
||||
{
|
||||
char* data;
|
||||
int len,rc;
|
||||
|
||||
len=strlen(pv_name)+strlen(BDT_PV_SERVICE)+2;
|
||||
data=(char*)malloc(len);
|
||||
sprintf(data,"%s %s",BDT_PV_SERVICE,pv_name);
|
||||
|
||||
rc=BdtServiceConnect(bdt,data);
|
||||
|
||||
free(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
105
src/libCom/bldEnvData
Executable file
105
src/libCom/bldEnvData
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# base/tools $Id$
|
||||
# Author: Andrew Johnson (RGO)
|
||||
# Date: 14-Mar-95
|
||||
#
|
||||
# Experimental Physics and Industrial Control System (EPICS)
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.3 1995/08/14 19:27:24 jhill
|
||||
# extern => epicsShareExtern
|
||||
#
|
||||
# Revision 1.2 1995/05/04 09:49:24 anj
|
||||
# Added CONFIG_SITE_ENV, changed envData to .c file
|
||||
#
|
||||
# Revision 1.1 1995/04/24 16:02:29 anj
|
||||
# Moved environment parameter defaults to config/CONFIG_ENV
|
||||
#
|
||||
#
|
||||
|
||||
# tool to build envData.c from envDefs.h and config/CONFIG*ENV
|
||||
|
||||
# Usage bldEnvData
|
||||
|
||||
HERE=`/bin/pwd`
|
||||
cd $1
|
||||
EPICS=`/bin/pwd`
|
||||
cd ${HERE}
|
||||
SRC=${EPICS}/base/include/envDefs.h
|
||||
ENV_DATA=${EPICS}/config/CONFIG_ENV
|
||||
SITE_DATA=${EPICS}/config/CONFIG_SITE_ENV
|
||||
OBJ=envData.c
|
||||
TOOL=`basename $0`
|
||||
|
||||
# Start by creating a list of the ENV_PARAM declarations
|
||||
PARAMS=`sed -n -e 's/;//' \
|
||||
-e 's/^[ ]*epicsShareExtern[ ][ ]*ENV_PARAM[ ][ ]*//p' \
|
||||
${SRC}`
|
||||
|
||||
# Create a new header file
|
||||
rm -rf ${OBJ}
|
||||
cat >${OBJ} <<!EOF
|
||||
/* ${HERE}/${OBJ}
|
||||
*
|
||||
* created by ${TOOL}
|
||||
*
|
||||
* from:
|
||||
* ${SRC}
|
||||
* ${ENV_DATA}
|
||||
* ${SITE_DATA}
|
||||
*
|
||||
* `date`
|
||||
*
|
||||
*/
|
||||
|
||||
#include <envDefs.h>
|
||||
|
||||
!EOF
|
||||
|
||||
# Make sure no corresponding shell environment variables
|
||||
unset ${PARAMS}
|
||||
|
||||
# Read the default values from the config file into shell variables
|
||||
. ${ENV_DATA}
|
||||
. ${SITE_DATA}
|
||||
|
||||
# Scan through the parameters to create the definition
|
||||
for ENV in ${PARAMS}
|
||||
do
|
||||
# Get the default, complain if not present
|
||||
if [ `set | grep -c ${ENV}=` = 0 ];
|
||||
then
|
||||
echo No default value for ${ENV}
|
||||
DEFAULT=""
|
||||
else
|
||||
VAR='$'${ENV}
|
||||
DEFAULT=`eval echo ${VAR}`
|
||||
fi
|
||||
|
||||
# Add this definition to the header file
|
||||
# echo ${ENV} = ${DEFAULT}
|
||||
echo ENV_PARAM ${ENV}'={"'${ENV}'","'${DEFAULT}'"};' >>${OBJ}
|
||||
done
|
||||
|
||||
# Now create an array pointing to all parameters
|
||||
cat >>${OBJ} <<!EOF
|
||||
|
||||
ENV_PARAM* env_param_list[] = {
|
||||
!EOF
|
||||
|
||||
# Contents are the addresses of each parameter
|
||||
for ENV in ${PARAMS}
|
||||
do
|
||||
echo ' &'${ENV}, >>${OBJ}
|
||||
done
|
||||
|
||||
# Finally finish list with 0
|
||||
cat >>${OBJ} <<!EOF
|
||||
0
|
||||
};
|
||||
|
||||
!EOF
|
||||
|
||||
exit 0
|
||||
|
||||
118
src/libCom/blderrSymTbl
Executable file
118
src/libCom/blderrSymTbl
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# base/tools $Id$
|
||||
# Author: Robert Zieman (ANL)
|
||||
# Date: 6/03/91
|
||||
#
|
||||
# Experimental Physics and Industrial Control System (EPICS)
|
||||
#
|
||||
# Copyright 1991, the Regents of the University of California,
|
||||
# and the University of Chicago Board of Governors.
|
||||
#
|
||||
# This software was produced under U.S. Government contracts:
|
||||
# (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
# and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
#
|
||||
# Initial development by:
|
||||
# The Controls and Automation Group (AT-8)
|
||||
# Ground Test Accelerator
|
||||
# Accelerator Technology Division
|
||||
# Los Alamos National Laboratory
|
||||
#
|
||||
# Co-developed with
|
||||
# The Controls and Computing Group
|
||||
# Accelerator Systems Division
|
||||
# Advanced Photon Source
|
||||
# Argonne National Laboratory
|
||||
#
|
||||
# Modification Log:
|
||||
# -----------------
|
||||
# .00 mm-dd-yy iii Comment
|
||||
# .01 05-04-94 pg HPUX port modifications.
|
||||
# .02 08-25-94 mda use makedepend for HP or Alpha if no GCC
|
||||
# .03 04-28-95 anj use GetVar and case for host arch
|
||||
# ...
|
||||
#
|
||||
|
||||
# tool to rebuild errSymTbl.c when errInc.c or it's depends change
|
||||
|
||||
# Usage blderrSymTbl EPICS HOST_ARCH MAKE VXLIST - IOC and commmon
|
||||
# Usage blderrSymTbl EPICS HOST_ARCH MAKE - just common
|
||||
|
||||
if [ "x" = "x$4" ]; then
|
||||
DEF="XXX"
|
||||
else
|
||||
DEF="${4}"
|
||||
fi
|
||||
|
||||
|
||||
TMPMAKEFILE=/tmp/tmpmakefile
|
||||
SFILES=/tmp/sfiles
|
||||
EPICS=$1
|
||||
HOST_ARCH=$2
|
||||
MAKE=$3
|
||||
|
||||
case $HOST_ARCH in
|
||||
alpha | hp700)
|
||||
# Use gcc if it can be found, or makedepend
|
||||
|
||||
GCC=`which gcc`
|
||||
if [ -x "$GCC" ]; then
|
||||
FILES=`"$GCC" -M -D$DEF -I../../../include \
|
||||
errInc.c 2>/dev/null \
|
||||
| sed -e 's/errInc\.o.*: errInc\.c//' -e 's/\\\//'`
|
||||
else
|
||||
MAKEDEPEND=`which makedepend`
|
||||
if [ -x "$MAKEDEPEND" ]; then
|
||||
FILES=`"$MAKEDEPEND" -f- -D$DEF -I../../../include \
|
||||
errInc.c 2>/dev/null | sed -e 's/errInc.o://' -e 's/\\\//'`
|
||||
else
|
||||
echo Neither GCC or MAKEDEPEND found.
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
solaris)
|
||||
# use -xM option of ACC to list dependencies
|
||||
|
||||
CC=`$EPICS/base/tools/GetVar $EPICS ACC $HOST_ARCH`
|
||||
FILES=`$CC -xM -D$DEF -I../../../include errInc.c \
|
||||
| grep "errInc.o" | grep -v "errInc.c" \
|
||||
| sed -e 's/errInc\.o://'`
|
||||
;;
|
||||
sun4)
|
||||
# use -M option of Sun compiler to list make dependencies
|
||||
|
||||
FILES=`cc -M -D$DEF -I../../../include errInc.c 2>/dev/null \
|
||||
| grep "errInc.o" | grep -v "errInc.c" \
|
||||
| sed -e 's/errInc\.o://'`
|
||||
;;
|
||||
*)
|
||||
# Unrecognised host architecture
|
||||
echo $0: host architecture not supported
|
||||
exit 1
|
||||
esac
|
||||
|
||||
|
||||
# files with S_ defines
|
||||
grep "^#define[ ]*S_" $FILES /dev/null \
|
||||
| sed -e 's-:.*--' | sort -u >$SFILES
|
||||
|
||||
|
||||
# create a tmpmakefile
|
||||
cat $SFILES | (awk '
|
||||
BEGIN {print "errInc.o : errInc.c \\"}
|
||||
{print " "$0" \\" }
|
||||
END {print " ../../../include/errMdef.h"}
|
||||
|
||||
') > $TMPMAKEFILE
|
||||
|
||||
cat >> $TMPMAKEFILE <<!addon
|
||||
/bin/rm -f errSymTbl.c
|
||||
../makeStatTbl \`cat $SFILES\` >errSymTbl.c
|
||||
/bin/rm -f errInc.o
|
||||
touch errInc.o
|
||||
!addon
|
||||
$MAKE -f $TMPMAKEFILE
|
||||
/bin/rm -f $TMPMAKEFILE $SFILES
|
||||
exit 0
|
||||
@@ -119,17 +119,17 @@ main()
|
||||
|
||||
pb = bucketCreate(8);
|
||||
if(!pb){
|
||||
return BUCKET_FAILURE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
id1 = 0x1000a432;
|
||||
pValSave1 = "fred";
|
||||
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
|
||||
assert(s == BUCKET_SUCCESS);
|
||||
assert (s == S_bucket_success);
|
||||
|
||||
pValSave2 = "jane";
|
||||
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
|
||||
assert(s == BUCKET_SUCCESS);
|
||||
assert (s == S_bucket_success);
|
||||
|
||||
start = clock();
|
||||
for(i=0; i<LOOPS; i++){
|
||||
@@ -166,7 +166,7 @@ main()
|
||||
|
||||
bucketShow(pb);
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -364,8 +364,8 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
|
||||
pb->hashIdNBits = nbits;
|
||||
|
||||
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
|
||||
if(!pb->pTable){
|
||||
free(pb);
|
||||
if (!pb->pTable) {
|
||||
free (pb);
|
||||
return NULL;
|
||||
}
|
||||
return pb;
|
||||
@@ -376,9 +376,9 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
|
||||
* bucketFree()
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
int bucketFree(BUCKET *prb)
|
||||
int bucketFree (BUCKET *prb)
|
||||
#else
|
||||
int bucketFree(prb)
|
||||
int bucketFree (prb)
|
||||
BUCKET *prb;
|
||||
#endif
|
||||
{
|
||||
@@ -389,7 +389,7 @@ BUCKET *prb;
|
||||
* deleting a bucket with entries in use
|
||||
* will cause memory leaks and is not allowed
|
||||
*/
|
||||
assert(prb->nInUse==0);
|
||||
assert (prb->nInUse==0);
|
||||
|
||||
/*
|
||||
* free the free list
|
||||
@@ -400,10 +400,10 @@ BUCKET *prb;
|
||||
free (pi);
|
||||
pi = pni;
|
||||
}
|
||||
free(prb->pTable);
|
||||
free(prb);
|
||||
free (prb->pTable);
|
||||
free (prb);
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,6 +425,8 @@ int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
|
||||
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
|
||||
{
|
||||
BUCKETID hashid;
|
||||
ITEM **ppi;
|
||||
ITEM **ppiExists;
|
||||
ITEM *pi;
|
||||
|
||||
/*
|
||||
@@ -436,9 +438,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
|
||||
prb->pFreeItems = pi->pItem;
|
||||
}
|
||||
else {
|
||||
pi = (ITEM *) malloc(sizeof(ITEM));
|
||||
pi = (ITEM *) malloc (sizeof(ITEM));
|
||||
if(!pi){
|
||||
return BUCKET_FAILURE;
|
||||
return S_bucket_noMemory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,12 +452,20 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
|
||||
pi->pApp = pApp;
|
||||
pi->pId = pId;
|
||||
pi->type = pBSET->type;
|
||||
assert((hashid & ~prb->hashIdMask) == 0);
|
||||
pi->pItem = prb->pTable[hashid];
|
||||
assert ((hashid & ~prb->hashIdMask) == 0);
|
||||
ppi = &prb->pTable[hashid];
|
||||
/*
|
||||
* Dont reuse a resource id !
|
||||
*/
|
||||
ppiExists = (*pBSET->pCompare) (ppi, pId);
|
||||
if (ppiExists) {
|
||||
return S_bucket_idInUse;
|
||||
}
|
||||
pi->pItem = *ppi;
|
||||
prb->pTable[hashid] = pi;
|
||||
prb->nInUse++;
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -489,7 +499,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
|
||||
ppi = &prb->pTable[hashid];
|
||||
ppi = (*pBSET->pCompare) (ppi, pId);
|
||||
if(!ppi){
|
||||
return BUCKET_FAILURE;
|
||||
return S_bucket_uknId;
|
||||
}
|
||||
prb->nInUse--;
|
||||
pi = *ppi;
|
||||
@@ -501,7 +511,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
|
||||
pi->pItem = prb->pFreeItems;
|
||||
prb->pFreeItems = pi;
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -521,7 +531,7 @@ void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
|
||||
{
|
||||
return bucketLookupItem(prb, &BSET[bidtString], pId);
|
||||
}
|
||||
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
|
||||
LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId)
|
||||
{
|
||||
BUCKETID hashid;
|
||||
ITEM **ppi;
|
||||
@@ -611,7 +621,7 @@ BUCKET *pb;
|
||||
stdDev,
|
||||
maxEntries);
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -119,17 +119,17 @@ main()
|
||||
|
||||
pb = bucketCreate(8);
|
||||
if(!pb){
|
||||
return BUCKET_FAILURE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
id1 = 0x1000a432;
|
||||
pValSave1 = "fred";
|
||||
s = bucketAddItemUnsignedId(pb, &id1, pValSave1);
|
||||
assert(s == BUCKET_SUCCESS);
|
||||
assert (s == S_bucket_success);
|
||||
|
||||
pValSave2 = "jane";
|
||||
s = bucketAddItemStringId(pb, pValSave2, pValSave2);
|
||||
assert(s == BUCKET_SUCCESS);
|
||||
assert (s == S_bucket_success);
|
||||
|
||||
start = clock();
|
||||
for(i=0; i<LOOPS; i++){
|
||||
@@ -166,7 +166,7 @@ main()
|
||||
|
||||
bucketShow(pb);
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -364,8 +364,8 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
|
||||
pb->hashIdNBits = nbits;
|
||||
|
||||
pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable));
|
||||
if(!pb->pTable){
|
||||
free(pb);
|
||||
if (!pb->pTable) {
|
||||
free (pb);
|
||||
return NULL;
|
||||
}
|
||||
return pb;
|
||||
@@ -376,9 +376,9 @@ BUCKET *bucketCreate (unsigned nHashTableEntries)
|
||||
* bucketFree()
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
int bucketFree(BUCKET *prb)
|
||||
int bucketFree (BUCKET *prb)
|
||||
#else
|
||||
int bucketFree(prb)
|
||||
int bucketFree (prb)
|
||||
BUCKET *prb;
|
||||
#endif
|
||||
{
|
||||
@@ -389,7 +389,7 @@ BUCKET *prb;
|
||||
* deleting a bucket with entries in use
|
||||
* will cause memory leaks and is not allowed
|
||||
*/
|
||||
assert(prb->nInUse==0);
|
||||
assert (prb->nInUse==0);
|
||||
|
||||
/*
|
||||
* free the free list
|
||||
@@ -400,10 +400,10 @@ BUCKET *prb;
|
||||
free (pi);
|
||||
pi = pni;
|
||||
}
|
||||
free(prb->pTable);
|
||||
free(prb);
|
||||
free (prb->pTable);
|
||||
free (prb);
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,6 +425,8 @@ int bucketAddItemStringId(BUCKET *prb, const char *pId, void *pApp)
|
||||
LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pApp)
|
||||
{
|
||||
BUCKETID hashid;
|
||||
ITEM **ppi;
|
||||
ITEM **ppiExists;
|
||||
ITEM *pi;
|
||||
|
||||
/*
|
||||
@@ -436,9 +438,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
|
||||
prb->pFreeItems = pi->pItem;
|
||||
}
|
||||
else {
|
||||
pi = (ITEM *) malloc(sizeof(ITEM));
|
||||
pi = (ITEM *) malloc (sizeof(ITEM));
|
||||
if(!pi){
|
||||
return BUCKET_FAILURE;
|
||||
return S_bucket_noMemory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,12 +452,20 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, void *pA
|
||||
pi->pApp = pApp;
|
||||
pi->pId = pId;
|
||||
pi->type = pBSET->type;
|
||||
assert((hashid & ~prb->hashIdMask) == 0);
|
||||
pi->pItem = prb->pTable[hashid];
|
||||
assert ((hashid & ~prb->hashIdMask) == 0);
|
||||
ppi = &prb->pTable[hashid];
|
||||
/*
|
||||
* Dont reuse a resource id !
|
||||
*/
|
||||
ppiExists = (*pBSET->pCompare) (ppi, pId);
|
||||
if (ppiExists) {
|
||||
return S_bucket_idInUse;
|
||||
}
|
||||
pi->pItem = *ppi;
|
||||
prb->pTable[hashid] = pi;
|
||||
prb->nInUse++;
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -489,7 +499,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
|
||||
ppi = &prb->pTable[hashid];
|
||||
ppi = (*pBSET->pCompare) (ppi, pId);
|
||||
if(!ppi){
|
||||
return BUCKET_FAILURE;
|
||||
return S_bucket_uknId;
|
||||
}
|
||||
prb->nInUse--;
|
||||
pi = *ppi;
|
||||
@@ -501,7 +511,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId)
|
||||
pi->pItem = prb->pFreeItems;
|
||||
prb->pFreeItems = pi;
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -521,7 +531,7 @@ void *bucketLookupItemStringId (BUCKET *prb, const char *pId)
|
||||
{
|
||||
return bucketLookupItem(prb, &BSET[bidtString], pId);
|
||||
}
|
||||
LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId)
|
||||
LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId)
|
||||
{
|
||||
BUCKETID hashid;
|
||||
ITEM **ppi;
|
||||
@@ -611,7 +621,7 @@ BUCKET *pb;
|
||||
stdDev,
|
||||
maxEntries);
|
||||
|
||||
return BUCKET_SUCCESS;
|
||||
return S_bucket_success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
src/libCom/env/envSubr.c
vendored
21
src/libCom/env/envSubr.c
vendored
@@ -31,6 +31,7 @@
|
||||
* .04 01-11-95 joh use getenv()/putenv() to fetch/write env
|
||||
* vars under vxWorks
|
||||
* .05 04-20-95 anj changes to use CONFIG_ENV
|
||||
* .06 05-24-95 joh added return stmnt to epicsPrtEnvParams()
|
||||
*
|
||||
* make options
|
||||
* -DvxWorks makes a version for VxWorks
|
||||
@@ -67,7 +68,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# include <winsock.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
@@ -81,9 +82,13 @@
|
||||
#endif
|
||||
|
||||
#include <envDefs.h>
|
||||
#include "envData.h"
|
||||
#include <errMdef.h>
|
||||
|
||||
/*
|
||||
* for VMS
|
||||
*/
|
||||
unsigned long inet_addr (char *);
|
||||
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME envGetConfigParam - get value of a configuration parameter
|
||||
@@ -243,7 +248,7 @@ struct in_addr *pAddr; /* O pointer to struct to receive inet addr */
|
||||
|
||||
ptext = envGetConfigParam(pParam, sizeof text, text);
|
||||
if (ptext) {
|
||||
status = inet_addr(text);
|
||||
status = inet_addr (text);
|
||||
if (status != -1) {
|
||||
pAddr->s_addr = status;
|
||||
return 0;
|
||||
@@ -422,14 +427,6 @@ char *value; /* I pointer to value string */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* epicsSetEnvParams not required any more - do not use */
|
||||
|
||||
int epicsSetEnvParams()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME epicsPrtEnvParams - print value of all configuration parameters
|
||||
*
|
||||
@@ -454,5 +451,7 @@ epicsPrtEnvParams()
|
||||
|
||||
while (*ppParam != NULL)
|
||||
envPrtConfigParam(*(ppParam++));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
* .04 01-11-95 joh use getenv()/putenv() to fetch/write env
|
||||
* vars under vxWorks
|
||||
* .05 04-20-95 anj changes to use CONFIG_ENV
|
||||
* .06 05-24-95 joh added return stmnt to epicsPrtEnvParams()
|
||||
*
|
||||
* make options
|
||||
* -DvxWorks makes a version for VxWorks
|
||||
@@ -67,7 +68,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# include <winsock.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
@@ -81,9 +82,13 @@
|
||||
#endif
|
||||
|
||||
#include <envDefs.h>
|
||||
#include "envData.h"
|
||||
#include <errMdef.h>
|
||||
|
||||
/*
|
||||
* for VMS
|
||||
*/
|
||||
unsigned long inet_addr (char *);
|
||||
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME envGetConfigParam - get value of a configuration parameter
|
||||
@@ -243,7 +248,7 @@ struct in_addr *pAddr; /* O pointer to struct to receive inet addr */
|
||||
|
||||
ptext = envGetConfigParam(pParam, sizeof text, text);
|
||||
if (ptext) {
|
||||
status = inet_addr(text);
|
||||
status = inet_addr (text);
|
||||
if (status != -1) {
|
||||
pAddr->s_addr = status;
|
||||
return 0;
|
||||
@@ -422,14 +427,6 @@ char *value; /* I pointer to value string */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* epicsSetEnvParams not required any more - do not use */
|
||||
|
||||
int epicsSetEnvParams()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME epicsPrtEnvParams - print value of all configuration parameters
|
||||
*
|
||||
@@ -454,5 +451,7 @@ epicsPrtEnvParams()
|
||||
|
||||
while (*ppParam != NULL)
|
||||
envPrtConfigParam(*(ppParam++));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "dbStaticLib.h"
|
||||
#include "drvEpvxi.h"
|
||||
#include "devLib.h"
|
||||
#include "casdef.h"
|
||||
#include "errMdef.h"
|
||||
#ifdef VXLIST
|
||||
/* epics vxWorks only*/
|
||||
|
||||
@@ -77,7 +77,9 @@ void errPrintf(long status, const char *pFileName,
|
||||
printf("%s ",name);
|
||||
}
|
||||
}
|
||||
vprintf(pformat,pvar);
|
||||
if (pformat) {
|
||||
vprintf(pformat,pvar);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,10 @@ LOCAL int vmprintf (const char *pFormat, va_list pvar)
|
||||
int s0;
|
||||
int s1;
|
||||
|
||||
if (!pFormat) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s0 = vfprintf(stdout,pFormat,pvar);
|
||||
fflush(stdout);
|
||||
s1 = vfprintf(iocLogFile,pFormat,pvar);
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ellLib.h>
|
||||
#include <dbDefs.h>
|
||||
@@ -137,17 +138,25 @@ int errSymBld()
|
||||
unsigned short hashInd;
|
||||
|
||||
if(initialized) return(0);
|
||||
hashtable = (ERRNUMNODE**)dbCalloc(NHASH, sizeof(ERRNUMNODE*));
|
||||
|
||||
hashtable = (ERRNUMNODE**)calloc(NHASH, sizeof(ERRNUMNODE*));
|
||||
if(!hashtable) {
|
||||
printf("errSymBld: Can't allocate storage\n");
|
||||
#ifdef vxWorks
|
||||
taskSuspend(0);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) {
|
||||
modnum = errArray->errNum >> 16;
|
||||
if (modnum < 501) {
|
||||
printf("errSymBld: ERROR - Module number in errSymTbl < 501\n");
|
||||
return (-1);
|
||||
printf("errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%x Name=%s\n",
|
||||
errArray->errNum, errArray->name);
|
||||
continue;
|
||||
}
|
||||
if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) {
|
||||
printf("errSymBld: ERROR - errSymbolAdd() failed \n");
|
||||
return (-1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist);
|
||||
@@ -206,7 +215,15 @@ char *name;
|
||||
ELLLIST *perrnumlist = &errnumlist;
|
||||
ERRNUMNODE *pNew;
|
||||
|
||||
pNew = (ERRNUMNODE*)dbCalloc(1, sizeof(ERRNUMNODE));
|
||||
pNew = (ERRNUMNODE*)calloc(1, sizeof(ERRNUMNODE));
|
||||
if(!pNew) {
|
||||
printf("errSymbolAdd: Can't allocate storage\n");
|
||||
#ifdef vxWorks
|
||||
taskSuspend(0);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
pNew->errNum = errNum;
|
||||
pNew->message = name;
|
||||
ellAdd(perrnumlist,(ELLNODE*)pNew);
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ellLib.h>
|
||||
#include <dbDefs.h>
|
||||
@@ -137,17 +138,25 @@ int errSymBld()
|
||||
unsigned short hashInd;
|
||||
|
||||
if(initialized) return(0);
|
||||
hashtable = (ERRNUMNODE**)dbCalloc(NHASH, sizeof(ERRNUMNODE*));
|
||||
|
||||
hashtable = (ERRNUMNODE**)calloc(NHASH, sizeof(ERRNUMNODE*));
|
||||
if(!hashtable) {
|
||||
printf("errSymBld: Can't allocate storage\n");
|
||||
#ifdef vxWorks
|
||||
taskSuspend(0);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) {
|
||||
modnum = errArray->errNum >> 16;
|
||||
if (modnum < 501) {
|
||||
printf("errSymBld: ERROR - Module number in errSymTbl < 501\n");
|
||||
return (-1);
|
||||
printf("errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%x Name=%s\n",
|
||||
errArray->errNum, errArray->name);
|
||||
continue;
|
||||
}
|
||||
if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) {
|
||||
printf("errSymBld: ERROR - errSymbolAdd() failed \n");
|
||||
return (-1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist);
|
||||
@@ -206,7 +215,15 @@ char *name;
|
||||
ELLLIST *perrnumlist = &errnumlist;
|
||||
ERRNUMNODE *pNew;
|
||||
|
||||
pNew = (ERRNUMNODE*)dbCalloc(1, sizeof(ERRNUMNODE));
|
||||
pNew = (ERRNUMNODE*)calloc(1, sizeof(ERRNUMNODE));
|
||||
if(!pNew) {
|
||||
printf("errSymbolAdd: Can't allocate storage\n");
|
||||
#ifdef vxWorks
|
||||
taskSuspend(0);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
pNew->errNum = errNum;
|
||||
pNew->message = name;
|
||||
ellAdd(perrnumlist,(ELLNODE*)pNew);
|
||||
|
||||
@@ -66,6 +66,10 @@
|
||||
* problem (send call back discarded when fdmgr pend
|
||||
* event time out expires even if the send call back
|
||||
* has not been called at least once).
|
||||
* .18 joh 051995 Changed the semantics of alarm create/delete
|
||||
* routines in a backwards compatible way so that
|
||||
* we eliminate delete ambiguity (chance of the same
|
||||
* being reused).
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
@@ -73,22 +77,7 @@
|
||||
* with the lower likelyhood of select blocking
|
||||
* on a fd write.
|
||||
*
|
||||
* .02 joh 012093 **** WARNING ****
|
||||
* Assume that a timer id returned by fdmgr_add_timeout()
|
||||
* will be reused (and returned from a subsequent call to
|
||||
* fdmgr_add_timeout()) after either of the following two
|
||||
* circumstances occur:
|
||||
* 1) You delete the timer referenced by the timer id with
|
||||
* fdmgr_clear_timeout()
|
||||
* 2) The timer expires (and the handler which you
|
||||
* have established for the timer id is executed)
|
||||
* Take care not to attempt to delete a timer which
|
||||
* has already expired (and therefore executed your timer
|
||||
* expiration handler subroutine). Attempting to
|
||||
* delete a timer which has already expired could
|
||||
* result in deletion of the wrong timer.
|
||||
*
|
||||
* .03 joh 012193 terse DOCUMENTATION has been added to the header file
|
||||
* .02 joh 012193 terse DOCUMENTATION has been added to the header file
|
||||
* share/epicsH/fdmgr.h
|
||||
*
|
||||
*/
|
||||
@@ -102,7 +91,19 @@ static char *pSccsId = "@(#) $Id$";
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Yuk
|
||||
*/
|
||||
#if defined (MULTINET)
|
||||
# define select_errno socket_errno
|
||||
#elif defined (WINTCP)
|
||||
# define select_errno uerrno
|
||||
extern int uerrno;
|
||||
#else
|
||||
# include <errno.h>
|
||||
# define select_errno errno
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
@@ -116,6 +117,10 @@ static char *pSccsId = "@(#) $Id$";
|
||||
|
||||
#include <epicsAssert.h>
|
||||
#include <fdmgr.h>
|
||||
#include <epicsTypes.h>
|
||||
|
||||
#define NOBSDNETPROTO
|
||||
#include <bsdProto.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
@@ -151,6 +156,15 @@ typedef struct{
|
||||
int delete_pending;
|
||||
}fdentry;
|
||||
|
||||
typedef struct{
|
||||
ELLNODE node;
|
||||
struct timeval t;
|
||||
void (*func)(void *pParam);
|
||||
void *param;
|
||||
enum alarm_list_type alt;
|
||||
unsigned id;
|
||||
}fdmgrAlarm;
|
||||
|
||||
#if defined(vxWorks)
|
||||
# define LOCK(PFDCTX) assert(semTake((PFDCTX)->lock, WAIT_FOREVER)==OK);
|
||||
# define UNLOCK(PFDCTX) assert(semGive((PFDCTX)->lock)==OK);
|
||||
@@ -169,7 +183,7 @@ typedef struct{
|
||||
# define UNLOCK_FD_HANDLER(PFDCTX) \
|
||||
assert(semGive((PFDCTX)->fd_handler_lock)==OK);
|
||||
|
||||
#elif defined(UNIX) || defined(VMS) || defined(_WIN32)
|
||||
#elif defined(UNIX) || defined(VMS) || defined(WIN32)
|
||||
# define LOCK(PFDCTX)
|
||||
# define UNLOCK(PFDCTX)
|
||||
# define UNLOCK_FDMGR_PEND_EVENT(PFDCTX) \
|
||||
@@ -228,6 +242,16 @@ fdctx *fdmgr_init(void)
|
||||
fdctx *pfdctx;
|
||||
|
||||
pfdctx = (fdctx *) calloc(1, sizeof(fdctx));
|
||||
if (!pfdctx) {
|
||||
return pfdctx;
|
||||
}
|
||||
|
||||
pfdctx->pAlarmBucket = bucketCreate (1024);
|
||||
if (!pfdctx->pAlarmBucket) {
|
||||
free (pfdctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
# if defined(vxWorks)
|
||||
pfdctx->lock = semMCreate (SEM_DELETE_SAFE);
|
||||
if (pfdctx->lock == NULL){
|
||||
@@ -248,6 +272,7 @@ fdctx *fdmgr_init(void)
|
||||
pfdctx->clk_rate = sysClkRateGet();
|
||||
pfdctx->last_tick_count = tickGet();
|
||||
# endif
|
||||
|
||||
ellInit(&pfdctx->fdentry_list);
|
||||
ellInit(&pfdctx->fdentry_in_use_list);
|
||||
ellInit(&pfdctx->fdentry_free_list);
|
||||
@@ -255,6 +280,7 @@ fdctx *fdmgr_init(void)
|
||||
ellInit(&pfdctx->expired_alarm_list);
|
||||
ellInit(&pfdctx->free_alarm_list);
|
||||
|
||||
|
||||
/*
|
||||
* returns NULL if unsuccessful
|
||||
*/
|
||||
@@ -269,7 +295,9 @@ fdctx *fdmgr_init(void)
|
||||
*/
|
||||
int fdmgr_delete(fdctx *pfdctx)
|
||||
{
|
||||
int status;
|
||||
int status;
|
||||
fdmgrAlarm *palarm;
|
||||
fdmgrAlarm *pnext;
|
||||
|
||||
if(!pfdctx){
|
||||
return ERROR;
|
||||
@@ -289,7 +317,17 @@ int fdmgr_delete(fdctx *pfdctx)
|
||||
ellFree(&pfdctx->fdentry_list);
|
||||
ellFree(&pfdctx->fdentry_in_use_list);
|
||||
ellFree(&pfdctx->fdentry_free_list);
|
||||
ellFree(&pfdctx->alarm_list);
|
||||
for ( palarm = (fdmgrAlarm *) ellFirst (&pfdctx->alarm_list);
|
||||
palarm;
|
||||
palarm = pnext) {
|
||||
pnext = (fdmgrAlarm *) ellNext (&palarm->node);
|
||||
status = bucketRemoveItemUnsignedId(
|
||||
pfdctx->pAlarmBucket,
|
||||
&palarm->id);
|
||||
assert (status == S_bucket_success);
|
||||
free (palarm);
|
||||
}
|
||||
bucketFree (pfdctx->pAlarmBucket);
|
||||
ellFree(&pfdctx->expired_alarm_list);
|
||||
ellFree(&pfdctx->free_alarm_list);
|
||||
|
||||
@@ -300,26 +338,26 @@ int fdmgr_delete(fdctx *pfdctx)
|
||||
/*
|
||||
* fdmgr_add_timeout()
|
||||
*/
|
||||
fdmgrAlarm *fdmgr_add_timeout(
|
||||
fdmgrAlarmId fdmgr_add_timeout(
|
||||
fdctx *pfdctx,
|
||||
struct timeval *ptimeout,
|
||||
void (*func)(void *),
|
||||
void *param
|
||||
)
|
||||
{
|
||||
fdmgrAlarm *palarm=NULL;
|
||||
fdmgrAlarm *pa;
|
||||
fdmgrAlarm *palarm=NULL;
|
||||
fdmgrAlarm *pa;
|
||||
struct timeval t;
|
||||
int status;
|
||||
|
||||
if(ptimeout->tv_sec < 0)
|
||||
return NULL;
|
||||
return fdmgrNoAlarm;
|
||||
if(ptimeout->tv_usec < 0)
|
||||
return NULL;
|
||||
return fdmgrNoAlarm;
|
||||
|
||||
status = fdmgr_gettimeval(pfdctx, &t);
|
||||
if(status < 0)
|
||||
return NULL;
|
||||
return fdmgrNoAlarm;
|
||||
|
||||
LOCK(pfdctx);
|
||||
palarm = (fdmgrAlarm *) ellGet(&pfdctx->free_alarm_list);
|
||||
@@ -327,14 +365,33 @@ void *param
|
||||
if(!palarm){
|
||||
palarm = (fdmgrAlarm *) malloc(sizeof(fdmgrAlarm));
|
||||
if(!palarm){
|
||||
return NULL;
|
||||
return fdmgrNoAlarm;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* force all fields to a known state
|
||||
*/
|
||||
memset((char *)palarm, 0, sizeof(*palarm));
|
||||
memset ((char *)palarm, 0, sizeof(*palarm));
|
||||
|
||||
do {
|
||||
pfdctx->nextAlarmId++;
|
||||
palarm->id = pfdctx->nextAlarmId;
|
||||
status = bucketAddItemUnsignedId (
|
||||
pfdctx->pAlarmBucket,
|
||||
&palarm->id,
|
||||
palarm);
|
||||
if (status == S_bucket_noMemory) {
|
||||
free (palarm);
|
||||
return fdmgrNoAlarm;
|
||||
}
|
||||
} while (status == S_bucket_idInUse);
|
||||
|
||||
if (status != S_bucket_success) {
|
||||
free (palarm);
|
||||
errMessage (status, "Alarm installation failed");
|
||||
return fdmgrNoAlarm;
|
||||
}
|
||||
|
||||
ptimeout->tv_sec += ptimeout->tv_usec/USEC_PER_SEC;
|
||||
ptimeout->tv_usec = ptimeout->tv_usec%USEC_PER_SEC;
|
||||
@@ -364,7 +421,10 @@ void *param
|
||||
}
|
||||
}
|
||||
if(pa){
|
||||
ellInsert(&pfdctx->alarm_list, pa->node.previous, &palarm->node);
|
||||
ellInsert (
|
||||
&pfdctx->alarm_list,
|
||||
pa->node.previous,
|
||||
&palarm->node);
|
||||
}
|
||||
else{
|
||||
ellAdd(&pfdctx->alarm_list, &palarm->node);
|
||||
@@ -372,22 +432,33 @@ void *param
|
||||
palarm->alt = alt_alarm;
|
||||
UNLOCK(pfdctx);
|
||||
|
||||
return (void *) palarm;
|
||||
return pfdctx->nextAlarmId;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* fdmgr_clear_timeout()
|
||||
*
|
||||
*/
|
||||
int fdmgr_clear_timeout(
|
||||
fdctx *pfdctx,
|
||||
fdmgrAlarm *palarm
|
||||
fdmgrAlarmId id
|
||||
)
|
||||
{
|
||||
int status;
|
||||
enum alarm_list_type alt;
|
||||
fdmgrAlarm *palarm;
|
||||
|
||||
palarm = bucketLookupItemUnsignedId (
|
||||
pfdctx->pAlarmBucket,
|
||||
&id);
|
||||
if (!palarm) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
status = bucketRemoveItemUnsignedId(
|
||||
pfdctx->pAlarmBucket,
|
||||
&id);
|
||||
assert (status == S_bucket_success);
|
||||
|
||||
status = ERROR;
|
||||
|
||||
@@ -657,7 +728,7 @@ struct timeval *ptimeout
|
||||
{
|
||||
int status;
|
||||
struct timeval t;
|
||||
fdmgrAlarm *palarm;
|
||||
fdmgrAlarmId alarmId;
|
||||
|
||||
|
||||
lockFDMGRPendEvent(pfdctx);
|
||||
@@ -673,22 +744,22 @@ struct timeval *ptimeout
|
||||
/*
|
||||
* silence gcc warnings
|
||||
*/
|
||||
palarm = NULL;
|
||||
alarmId = fdmgrNoAlarm;
|
||||
}
|
||||
else{
|
||||
pfdctx->select_tmo = FALSE;
|
||||
palarm = fdmgr_add_timeout(
|
||||
alarmId = fdmgr_add_timeout(
|
||||
pfdctx,
|
||||
ptimeout,
|
||||
select_alarm,
|
||||
pfdctx);
|
||||
if(!palarm){
|
||||
if (alarmId==fdmgrNoAlarm) {
|
||||
return ERROR;
|
||||
}
|
||||
process_alarm_queue(pfdctx, &t);
|
||||
}
|
||||
|
||||
while(TRUE){
|
||||
while (TRUE) {
|
||||
status = fdmgr_select(pfdctx, &t);
|
||||
process_alarm_queue(pfdctx, &t);
|
||||
if(status){
|
||||
@@ -698,8 +769,8 @@ struct timeval *ptimeout
|
||||
break;
|
||||
}
|
||||
|
||||
if(pfdctx->select_tmo==FALSE)
|
||||
fdmgr_clear_timeout(pfdctx, palarm);
|
||||
if(pfdctx->select_tmo==FALSE && alarmId != fdmgrNoAlarm)
|
||||
fdmgr_clear_timeout(pfdctx, alarmId);
|
||||
|
||||
UNLOCK_FDMGR_PEND_EVENT(pfdctx);
|
||||
|
||||
@@ -745,7 +816,7 @@ struct timeval *ptimeout
|
||||
taskSafe();
|
||||
# endif
|
||||
# if defined (__hpux)
|
||||
status = select(
|
||||
status = select (
|
||||
pfdctx->maxfd,
|
||||
(int *)&pfdctx->readch,
|
||||
(int *)&pfdctx->writech,
|
||||
@@ -766,9 +837,9 @@ struct timeval *ptimeout
|
||||
return labor_performed;
|
||||
}
|
||||
else if(status < 0){
|
||||
if(errno == EINTR)
|
||||
if(select_errno == EINTR)
|
||||
;
|
||||
else if(errno == EINVAL)
|
||||
else if(select_errno == EINVAL)
|
||||
fdmgrPrintf(
|
||||
"fdmgr: bad select args ? %d %d %d\n",
|
||||
pfdctx->maxfd,
|
||||
@@ -777,7 +848,7 @@ struct timeval *ptimeout
|
||||
else
|
||||
fdmgrPrintf(
|
||||
"fdmgr: error from select %s\n",
|
||||
strerror(errno));
|
||||
strerror(select_errno));
|
||||
|
||||
return labor_performed;
|
||||
}
|
||||
@@ -888,6 +959,10 @@ struct timeval *poffset
|
||||
ellDelete(&pfdctx->alarm_list, &pa->node);
|
||||
ellAdd(&pfdctx->expired_alarm_list, &pa->node);
|
||||
pa->alt = alt_expired;
|
||||
status = bucketRemoveItemUnsignedId(
|
||||
pfdctx->pAlarmBucket,
|
||||
&pa->id);
|
||||
assert (status == S_bucket_success);
|
||||
}
|
||||
UNLOCK(pfdctx);
|
||||
|
||||
@@ -984,7 +1059,7 @@ struct timeval *pt
|
||||
{
|
||||
struct timezone tz;
|
||||
|
||||
return gettimeofday(pt, &tz);
|
||||
return gettimeofday (pt, &tz);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -996,7 +1071,7 @@ struct timeval *pt
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifdef WIN32
|
||||
LOCAL int fdmgr_gettimeval(
|
||||
fdctx *pfdctx,
|
||||
struct timeval *pt
|
||||
@@ -1004,8 +1079,7 @@ struct timeval *pt
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 + (long)st.wHour*360
|
||||
0;
|
||||
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 + (long)st.wHour*3600;
|
||||
pt->tv_usec = st.wMilliseconds*1000;
|
||||
|
||||
return 0;
|
||||
|
||||
75
src/libCom/makeStatTbl
Executable file
75
src/libCom/makeStatTbl
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# makeStatTbl
|
||||
# share/src/misc $Id$
|
||||
# makeStatTbl - Create Error Symbol Table
|
||||
#
|
||||
# modification history
|
||||
# --------------------
|
||||
# 17-JUL-90 mrk Modified vxWorks makeStatTbl
|
||||
#
|
||||
# SYNOPSIS
|
||||
# createErrSymTbl hdir [...] >errSymTbl.c
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This tool creates a symbol table (ERRSYMTAB) structure which contains the
|
||||
# names and values of all the status codes defined in the .h files in the
|
||||
# specified directory(s). The status codes must be prefixed with "S_"
|
||||
# in order to be included in this table.
|
||||
# A "err.h" file must exist in each hdir which defines the module
|
||||
# numbers, eg. "M_". The table is created on standard output.
|
||||
#
|
||||
# This tool's primary use is for creating an error status table used
|
||||
# by errPrint, and errSymFind.
|
||||
#
|
||||
# FILES
|
||||
# errMdef.h module number file for each h directory
|
||||
#
|
||||
# SEE ALSO: errnoLib(1), symLib(1)
|
||||
#*/
|
||||
|
||||
tmp=/tmp/mstt$$
|
||||
|
||||
trap "rm -f $tmp ; exit" 0 1 2 3 15
|
||||
|
||||
cat </dev/null >$tmp
|
||||
|
||||
cat $* | egrep "^#define[ ]*S_" >>$tmp
|
||||
|
||||
|
||||
echo "/* status code symbol table */
|
||||
|
||||
/* CREATED BY makeStatTbl"
|
||||
|
||||
echo " * FROM `pwd`"
|
||||
|
||||
echo " * ON `date`
|
||||
*/
|
||||
"'
|
||||
#include "errMdef.h"
|
||||
#include "errSymTbl.h"
|
||||
'
|
||||
|
||||
echo
|
||||
|
||||
cat $tmp
|
||||
|
||||
echo '
|
||||
|
||||
LOCAL ERRSYMBOL symbols[] =
|
||||
{'
|
||||
|
||||
sed -e 's/^.*define[ ]*\(S_[a-zA-Z0-9_]*\).*\/\*\(.*\)\*\/.*/ {"\2", (long) \1},/' \
|
||||
$tmp
|
||||
|
||||
echo " };
|
||||
|
||||
LOCAL ERRSYMTAB symTbl =
|
||||
{
|
||||
NELEMENTS (symbols), /* current number of symbols in table */
|
||||
symbols, /* ptr to symbol array */
|
||||
};
|
||||
|
||||
ERRSYMTAB_ID errSymTbl = &symTbl;"
|
||||
|
||||
exit 0
|
||||
@@ -39,7 +39,11 @@
|
||||
* .10 05-04-94 pg HPUX cpp changes. (elif to else and if)
|
||||
* .11 01-09-95 joh fixed ts min west out of range test
|
||||
* .12 02-24-95 joh fixed TScurrentTimeStamp() => tsLocalTime ()
|
||||
* return status mapping prob introduced by .09 above
|
||||
* return status mapping prob introduced by .09 above
|
||||
* .13 05-26-95 joh TsAddDouble() macro isnt portable so it becomes
|
||||
* a subroutine - oops - discovered tsAddDouble()
|
||||
* so I left TsAddDouble() code - which works -
|
||||
* at the end of the file but commented it out
|
||||
*
|
||||
* make options
|
||||
* -DvxWorks makes a version for VxWorks
|
||||
@@ -115,19 +119,18 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
|
||||
#if defined(vxWorks)
|
||||
# include <vxWorks.h>
|
||||
# include <stdioLib.h>
|
||||
# include <strLib.h>
|
||||
#else
|
||||
#if VMS
|
||||
#elif defined(VMS)
|
||||
# include <sys/time.h>
|
||||
#elif defined(WIN32)
|
||||
# include <windows.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
#if 0
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <epicsAssert.h>
|
||||
@@ -597,25 +600,36 @@ TS_STAMP *pStamp; /* O pointer to time stamp buffer */
|
||||
{
|
||||
long retStat=S_ts_OK;/* return status to caller */
|
||||
|
||||
#ifdef vxWorks
|
||||
retStat = TScurrentTimeStamp((struct timespec*)pStamp);
|
||||
if (retStat == 0) {
|
||||
return S_ts_OK;
|
||||
}
|
||||
else {
|
||||
return S_ts_sysTimeError;
|
||||
}
|
||||
#else
|
||||
struct timeval curtime;
|
||||
assert(pStamp != NULL);
|
||||
|
||||
assert(pStamp != NULL);
|
||||
if (gettimeofday(&curtime, (struct timezone *)NULL) == -1)
|
||||
retStat = S_ts_sysTimeError;
|
||||
else {
|
||||
pStamp->nsec = ( curtime.tv_usec/1000 ) * 1000000;
|
||||
pStamp->secPastEpoch = curtime.tv_sec - TS_EPOCH_SEC_PAST_1970;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
# if defined(vxWorks)
|
||||
retStat = TScurrentTimeStamp((struct timespec*)pStamp);
|
||||
if (retStat == 0) {
|
||||
return S_ts_OK;
|
||||
}
|
||||
else {
|
||||
return S_ts_sysTimeError;
|
||||
}
|
||||
# elif defined(WIN32)
|
||||
SYSTEMTIME st; /* utc */
|
||||
|
||||
pStamp->secPastEpoch = time(NULL) - TS_EPOCH_SEC_PAST_1970;
|
||||
GetSystemTime(&st);
|
||||
pStamp->nsec = st.wMilliseconds * 1000000;
|
||||
# else
|
||||
struct timeval curtime;
|
||||
|
||||
assert(pStamp != NULL);
|
||||
if (gettimeofday(&curtime, (struct timezone *)NULL) == -1)
|
||||
retStat = S_ts_sysTimeError;
|
||||
else {
|
||||
pStamp->nsec = ( curtime.tv_usec/1000 ) * 1000000;
|
||||
pStamp->secPastEpoch = curtime.tv_sec -
|
||||
TS_EPOCH_SEC_PAST_1970;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
pStamp->nsec = pStamp->nsec - (pStamp->nsec % TS_TRUNC);
|
||||
return retStat;
|
||||
@@ -1465,3 +1479,4 @@ char **pText; /* IO ptr to ptr to string containing time and date */
|
||||
*pStamp = stamp;
|
||||
return retStat;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,15 +5,9 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
SRCS.c = ../iocLogClient.c ../veclist.c
|
||||
|
||||
OBJS = veclist.o iocLogClient.o
|
||||
LIBOBJS = veclist.o iocLogClient.o
|
||||
|
||||
PROD = vxComLib
|
||||
LIBNAME = vxComLib
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
clean::
|
||||
@$(RM) vxComLib
|
||||
|
||||
vxComLib: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
/*
|
||||
* $Id$
|
||||
* @(#)veclist.c 1.10
|
||||
*
|
||||
* list fuctions attached to the interrupt vector table
|
||||
*
|
||||
* Created 28Mar89 Jeffrey O. Hill
|
||||
* hill@atdiv.lanl.gov
|
||||
* johill@lanl.gov
|
||||
* (505) 665 1831
|
||||
*
|
||||
* .01 010393 Applied fix for zero C ISR param causes incorrect
|
||||
* identification as MACRO ISR problem.
|
||||
* .02 022195 Compiler warnings fixed
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,12 +4,9 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
SRCS.c = ../epicsRelease.c
|
||||
|
||||
OBJS = epicsRelease.o
|
||||
LIBOBJS = epicsRelease.o
|
||||
|
||||
PROD = miscLib
|
||||
LIBNAME = miscLib
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
miscLib: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
@@ -42,61 +42,55 @@ SRCS.c += ../recStringin.c
|
||||
SRCS.c += ../recStringout.c
|
||||
SRCS.c += ../recSub.c
|
||||
SRCS.c += ../recSubArray.c
|
||||
# SRCS.c += ../recSwitch.c
|
||||
SRCS.c += ../recTimer.c
|
||||
SRCS.c += ../recWait.c
|
||||
SRCS.c += ../recWaitCa.c
|
||||
SRCS.c += ../recWaveform.c
|
||||
|
||||
# OBJS += recAai.o
|
||||
# OBJS += recAao.o
|
||||
OBJS += recAi.o
|
||||
OBJS += recAo.o
|
||||
OBJS += recBi.o
|
||||
OBJS += recBo.o
|
||||
OBJS += recCalc.o
|
||||
OBJS += recCompress.o
|
||||
OBJS += recDfanout.o
|
||||
OBJS += recEg.o
|
||||
OBJS += recEgevent.o
|
||||
OBJS += recEr.o
|
||||
OBJS += recErevent.o
|
||||
OBJS += recEvent.o
|
||||
OBJS += recFanout.o
|
||||
# OBJS += recGsub.o
|
||||
OBJS += recHistogram.o
|
||||
OBJS += recLongin.o
|
||||
OBJS += recLongout.o
|
||||
OBJS += recMbbi.o
|
||||
OBJS += recMbbiDirect.o
|
||||
OBJS += recMbbo.o
|
||||
OBJS += recMbboDirect.o
|
||||
# OBJS += recPal.o
|
||||
OBJS += recPermissive.o
|
||||
OBJS += recPid.o
|
||||
OBJS += recPulseCounter.o
|
||||
OBJS += recPulseDelay.o
|
||||
OBJS += recPulseTrain.o
|
||||
OBJS += recScan.o
|
||||
OBJS += recSel.o
|
||||
OBJS += recSeq.o
|
||||
OBJS += recState.o
|
||||
OBJS += recSteppermotor.o
|
||||
OBJS += recStringin.o
|
||||
OBJS += recStringout.o
|
||||
OBJS += recSub.o
|
||||
OBJS += recSubArray.o
|
||||
# OBJS += recSwitch.o
|
||||
OBJS += recTimer.o
|
||||
OBJS += recWait.o
|
||||
OBJS += recWaitCa.o
|
||||
OBJS += recWaveform.o
|
||||
# LIBOBJS += recAai.o
|
||||
# LIBOBJS += recAao.o
|
||||
LIBOBJS += recAi.o
|
||||
LIBOBJS += recAo.o
|
||||
LIBOBJS += recBi.o
|
||||
LIBOBJS += recBo.o
|
||||
LIBOBJS += recCalc.o
|
||||
LIBOBJS += recCompress.o
|
||||
LIBOBJS += recDfanout.o
|
||||
LIBOBJS += recEg.o
|
||||
LIBOBJS += recEgevent.o
|
||||
LIBOBJS += recEr.o
|
||||
LIBOBJS += recErevent.o
|
||||
LIBOBJS += recEvent.o
|
||||
LIBOBJS += recFanout.o
|
||||
# LIBOBJS += recGsub.o
|
||||
LIBOBJS += recHistogram.o
|
||||
LIBOBJS += recLongin.o
|
||||
LIBOBJS += recLongout.o
|
||||
LIBOBJS += recMbbi.o
|
||||
LIBOBJS += recMbbiDirect.o
|
||||
LIBOBJS += recMbbo.o
|
||||
LIBOBJS += recMbboDirect.o
|
||||
# LIBOBJS += recPal.o
|
||||
LIBOBJS += recPermissive.o
|
||||
LIBOBJS += recPid.o
|
||||
LIBOBJS += recPulseCounter.o
|
||||
LIBOBJS += recPulseDelay.o
|
||||
LIBOBJS += recPulseTrain.o
|
||||
LIBOBJS += recScan.o
|
||||
LIBOBJS += recSel.o
|
||||
LIBOBJS += recSeq.o
|
||||
LIBOBJS += recState.o
|
||||
LIBOBJS += recSteppermotor.o
|
||||
LIBOBJS += recStringin.o
|
||||
LIBOBJS += recStringout.o
|
||||
LIBOBJS += recSub.o
|
||||
LIBOBJS += recSubArray.o
|
||||
LIBOBJS += recTimer.o
|
||||
LIBOBJS += recWait.o
|
||||
LIBOBJS += recWaitCa.o
|
||||
LIBOBJS += recWaveform.o
|
||||
|
||||
PROD = recSup
|
||||
LIBNAME = recSup
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
$(PROD): $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ static long init_record(pao,pass)
|
||||
break;
|
||||
}
|
||||
}
|
||||
pao->pval = pao->val;
|
||||
pao->oval = pao->pval = pao->val;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -267,7 +267,7 @@ static void monitor(pdfanout)
|
||||
monitor_mask = recGblResetAlarms(pdfanout);
|
||||
monitor_mask |= (DBE_LOG|DBE_VALUE);
|
||||
if(monitor_mask)
|
||||
db_post_events(pdfanout,pdfanout->val,monitor_mask);
|
||||
db_post_events(pdfanout,&pdfanout->val,monitor_mask);
|
||||
|
||||
/* check for value change */
|
||||
delta = pdfanout->mlst - pdfanout->val;
|
||||
|
||||
@@ -256,7 +256,7 @@ static void monitor(pmbbiDirect)
|
||||
monitor_mask = recGblResetAlarms(pmbbiDirect);
|
||||
monitor_mask |= (DBE_LOG|DBE_VALUE);
|
||||
if(monitor_mask)
|
||||
db_post_events(pmbbiDirect,pmbbiDirect->val,monitor_mask);
|
||||
db_post_events(pmbbiDirect,&pmbbiDirect->val,monitor_mask);
|
||||
|
||||
/* check for value change */
|
||||
if (pmbbiDirect->mlst != pmbbiDirect->val) {
|
||||
|
||||
@@ -1,751 +0,0 @@
|
||||
/* recSwitch.c */
|
||||
/* base/src/rec $Id$ */
|
||||
|
||||
/* recSwitch.c - Record Support Routines for Switch records */
|
||||
/*
|
||||
* Author: Matthew Needes
|
||||
* Date: 9-21-93
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <types.h>
|
||||
#include <stdioLib.h>
|
||||
#include <lstLib.h>
|
||||
#include <string.h>
|
||||
#include <wdLib.h>
|
||||
|
||||
#include <alarm.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <devSup.h>
|
||||
#include <errMdef.h>
|
||||
#include <recSup.h>
|
||||
#include <special.h>
|
||||
#include <callback.h>
|
||||
#include <switchRecord.h>
|
||||
|
||||
/* RSET - Record Support Entry Table */
|
||||
#define report NULL
|
||||
#define initialize NULL
|
||||
static long init_record();
|
||||
static long process();
|
||||
static long special();
|
||||
static long get_value();
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
#define put_array_info NULL
|
||||
#define get_units NULL
|
||||
static long get_precision();
|
||||
static long get_enum_str();
|
||||
static long get_enum_strs();
|
||||
#define put_enum_str NULL
|
||||
#define get_graphic_double NULL
|
||||
#define get_control_double NULL
|
||||
#define get_alarm_double NULL
|
||||
|
||||
struct rset switchRSET = {
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double };
|
||||
|
||||
static long init_state();
|
||||
static long output_and_watch();
|
||||
static long check_readback();
|
||||
static void monitor();
|
||||
static void callback();
|
||||
static void watchdog();
|
||||
|
||||
/* defs for initialization choices */
|
||||
#define INIT_RESET 0
|
||||
#define INIT_SET 1
|
||||
#define INIT_READBACK 2
|
||||
|
||||
/* defs for readback set threshold */
|
||||
#define ABOVE 0
|
||||
#define BELOW 1
|
||||
|
||||
/* defs for transition fail action choices */
|
||||
#define FAIL_FOLLOW_RDBK 0
|
||||
#define FAIL_KEEP_VALUE 1
|
||||
|
||||
/* state definitions for switch */
|
||||
#define UNINITIALIZED 0
|
||||
#define SET 1
|
||||
#define RESET 2
|
||||
#define RESET_TO_SET 3
|
||||
#define SET_TO_RESET 4
|
||||
|
||||
/* states above this number signify transition */
|
||||
#define TRANS_STATE 2
|
||||
|
||||
/* number of strings */
|
||||
#define STRING_COUNT 5
|
||||
|
||||
/*
|
||||
* Bitmask to check to see if the switch
|
||||
* is set or in the process of setting.
|
||||
*/
|
||||
#define TO_SET 0x01
|
||||
|
||||
/* private structure in record */
|
||||
struct PVT {
|
||||
CALLBACK callback;
|
||||
WDOG_ID watchdog;
|
||||
};
|
||||
|
||||
/* post an event on a field */
|
||||
#define MON_FIELD(CUR,PREV) \
|
||||
if ((CUR) != (PREV)) { \
|
||||
db_post_events(pswitch, &(CUR), DBE_VALUE); \
|
||||
(PREV) = (CUR); }
|
||||
|
||||
/* initialize record */
|
||||
static long init_record(
|
||||
struct switchRecord *pswitch,
|
||||
int pass
|
||||
)
|
||||
{
|
||||
long status;
|
||||
|
||||
/* ignore second pass */
|
||||
if (!pass)
|
||||
return(0);
|
||||
|
||||
/* initialize readback input link */
|
||||
status = recGblInitFastInLink(&pswitch->rbkl, (void *) pswitch, DBR_DOUBLE, "RBKV");
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* initialize master reset link */
|
||||
status = recGblInitFastInLink(&pswitch->mrsl, (void *) pswitch, DBR_UCHAR, "MRSV");
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* initialize master set link */
|
||||
status = recGblInitFastInLink(&pswitch->mstl, (void *) pswitch, DBR_UCHAR, "MSTV");
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* initialize reset link */
|
||||
status = recGblInitFastInLink(&pswitch->rstl, (void *) pswitch, DBR_UCHAR, "RSTV");
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* initialize set link */
|
||||
status = recGblInitFastInLink(&pswitch->setl, (void *) pswitch, DBR_UCHAR, "SETV");
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* initialize toggle link */
|
||||
status = recGblInitFastInLink(&pswitch->togl, (void *) pswitch, DBR_UCHAR, "TOGV");
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* clear alarm severity */
|
||||
pswitch->sevr = NO_ALARM;
|
||||
|
||||
/*
|
||||
* Allocate private structure
|
||||
*/
|
||||
pswitch->pvt = (void *) malloc(sizeof(struct PVT));
|
||||
|
||||
if (!pswitch->pvt)
|
||||
return(S_rec_outMem);
|
||||
|
||||
/*
|
||||
* Create watchdog
|
||||
*/
|
||||
((struct PVT *)pswitch->pvt)->watchdog = (void *) wdCreate();
|
||||
|
||||
if (!((struct PVT *)pswitch->pvt)->watchdog)
|
||||
return(S_rec_outMem);
|
||||
|
||||
/*
|
||||
* Initialize EPICS callback
|
||||
*/
|
||||
callbackSetCallback(callback, &((struct PVT *)pswitch->pvt)->callback);
|
||||
callbackSetUser(pswitch, &((struct PVT *)pswitch->pvt)->callback);
|
||||
callbackSetPriority(pswitch->prio, &((struct PVT *)pswitch->pvt)->callback);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* initialize record's state */
|
||||
static long init_state(struct switchRecord *pswitch)
|
||||
{
|
||||
long status = 0;
|
||||
|
||||
/* set initial state */
|
||||
switch (pswitch->ini) {
|
||||
case INIT_RESET:
|
||||
pswitch->val = SET_TO_RESET;
|
||||
pswitch->pint = RESET;
|
||||
pswitch->outv = pswitch->offv;
|
||||
status = output_and_watch(pswitch);
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
break;
|
||||
case INIT_SET:
|
||||
pswitch->val = RESET_TO_SET;
|
||||
pswitch->pint = SET;
|
||||
pswitch->outv = pswitch->onv;
|
||||
status = output_and_watch(pswitch);
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
break;
|
||||
case INIT_READBACK:
|
||||
/*
|
||||
* If uninitialized, get state from readback
|
||||
*/
|
||||
status = recGblGetFastLink(&pswitch->rbkl, (void *) pswitch,
|
||||
&pswitch->rbkv);
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
if (pswitch->dthr == BELOW)
|
||||
pswitch->pint = pswitch->val = (pswitch->rbkv <= pswitch->rthr) ? SET : RESET;
|
||||
else
|
||||
pswitch->pint = pswitch->val = (pswitch->rbkv >= pswitch->rthr) ? SET : RESET;
|
||||
|
||||
pswitch->outv = (pswitch->val == SET) ? pswitch->onv : pswitch->offv;
|
||||
|
||||
/*
|
||||
* Drive output
|
||||
*/
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return(0);
|
||||
break;
|
||||
}
|
||||
|
||||
pswitch->udf = FALSE;
|
||||
|
||||
pswitch->intn = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* process record */
|
||||
static long process(struct switchRecord *pswitch)
|
||||
{
|
||||
long status = 0;
|
||||
unsigned char value = 0;
|
||||
|
||||
pswitch->pact = TRUE;
|
||||
|
||||
/* initialize record if not already initialized */
|
||||
if (pswitch->val == UNINITIALIZED)
|
||||
status = init_state(pswitch);
|
||||
|
||||
/*
|
||||
* Check master set and reset links.
|
||||
*/
|
||||
status = recGblGetFastLink(&pswitch->mrsl, (void *) pswitch,
|
||||
&pswitch->mrsv);
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
MON_FIELD(pswitch->mrsv, pswitch->lmrs);
|
||||
|
||||
status = recGblGetFastLink(&pswitch->mstl, (void *) pswitch,
|
||||
&pswitch->mstv);
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
MON_FIELD(pswitch->mstv, pswitch->lmst);
|
||||
|
||||
/* Check master reset value */
|
||||
if (pswitch->mrsv) {
|
||||
pswitch->pint = RESET;
|
||||
|
||||
if (pswitch->val & TO_SET) {
|
||||
if (pswitch->val > TRANS_STATE) {
|
||||
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
|
||||
}
|
||||
pswitch->val = SET_TO_RESET;
|
||||
pswitch->outv = pswitch->offv;
|
||||
status = output_and_watch(pswitch);
|
||||
if (status)
|
||||
return(status);
|
||||
}
|
||||
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
|
||||
pswitch->outv = pswitch->offv;
|
||||
pswitch->nsta = pswitch->nsev = 0;
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
}
|
||||
|
||||
pswitch->setv = pswitch->rstv = pswitch->togv = 0;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Check master set link
|
||||
*/
|
||||
if (pswitch->mstv) {
|
||||
pswitch->pint = SET;
|
||||
if (!(pswitch->val & TO_SET)) {
|
||||
if (pswitch->val > TRANS_STATE) {
|
||||
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
|
||||
}
|
||||
pswitch->val = RESET_TO_SET;
|
||||
pswitch->outv = pswitch->onv;
|
||||
status = output_and_watch(pswitch);
|
||||
if (status)
|
||||
return(status);
|
||||
}
|
||||
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
|
||||
pswitch->outv = pswitch->onv;
|
||||
pswitch->nsta = pswitch->nsev = 0;
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
}
|
||||
|
||||
pswitch->setv = pswitch->rstv = pswitch->togv = 0;
|
||||
}
|
||||
/*
|
||||
* Check input links if record is in closed loop mode
|
||||
*/
|
||||
else {
|
||||
if (pswitch->omsl == CLOSED_LOOP) {
|
||||
/*
|
||||
* Check set/reset/toggle input links - and check monitor
|
||||
*/
|
||||
status = recGblGetFastLink(&pswitch->rstl, (void *) pswitch, &pswitch->rstv);
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
MON_FIELD(pswitch->rstv, pswitch->lrst);
|
||||
|
||||
status = recGblGetFastLink(&pswitch->setl, (void *) pswitch, &pswitch->setv);
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
MON_FIELD(pswitch->setv, pswitch->lsst);
|
||||
|
||||
status = recGblGetFastLink(&pswitch->togl, (void *) pswitch, &pswitch->togv);
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
MON_FIELD(pswitch->togv, pswitch->ltog);
|
||||
|
||||
pswitch->intn = 1;
|
||||
}
|
||||
/*
|
||||
* If "intention" is set, a non-master switch has been
|
||||
* modified (by a put, for example). Check the switches.
|
||||
*/
|
||||
if (pswitch->intn) {
|
||||
/*
|
||||
* Ignore command if in transition state and ignore flag set
|
||||
*/
|
||||
if (!((pswitch->val > TRANS_STATE) && pswitch->iti)) {
|
||||
if (pswitch->rstv) {
|
||||
/* reset */
|
||||
pswitch->pint = RESET;
|
||||
if (pswitch->val & TO_SET) {
|
||||
if (pswitch->val > TRANS_STATE) {
|
||||
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
|
||||
}
|
||||
pswitch->val = SET_TO_RESET;
|
||||
pswitch->outv = pswitch->offv;
|
||||
status = output_and_watch(pswitch);
|
||||
}
|
||||
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
|
||||
pswitch->outv = pswitch->offv;
|
||||
pswitch->nsta = pswitch->nsev = 0;
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pswitch->setv) {
|
||||
/* set */
|
||||
pswitch->pint = SET;
|
||||
if (!(pswitch->val & TO_SET)) {
|
||||
if (pswitch->val > TRANS_STATE) {
|
||||
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
|
||||
}
|
||||
pswitch->val = RESET_TO_SET;
|
||||
pswitch->outv = pswitch->onv;
|
||||
status = output_and_watch(pswitch);
|
||||
}
|
||||
else if (pswitch->aftt == FAIL_KEEP_VALUE) {
|
||||
pswitch->outv = pswitch->onv;
|
||||
pswitch->nsta = pswitch->nsev = 0;
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pswitch->togv) {
|
||||
/* toggle */
|
||||
if (pswitch->val > TRANS_STATE) {
|
||||
wdCancel((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog);
|
||||
}
|
||||
if (pswitch->val & TO_SET) {
|
||||
pswitch->pint = RESET;
|
||||
pswitch->val = SET_TO_RESET;
|
||||
pswitch->outv = pswitch->offv;
|
||||
}
|
||||
else {
|
||||
pswitch->pint = SET;
|
||||
pswitch->val = RESET_TO_SET;
|
||||
pswitch->outv = pswitch->onv;
|
||||
}
|
||||
status = output_and_watch(pswitch);
|
||||
}
|
||||
if (status)
|
||||
return(status);
|
||||
}
|
||||
pswitch->setv = pswitch->rstv = pswitch->togv = 0;
|
||||
|
||||
/*
|
||||
* Intention resets when setv, rstv, togv are activated,
|
||||
* and only after mstv/mrsv are cleared
|
||||
*/
|
||||
pswitch->intn = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not check readback if the link isn't specified or
|
||||
* if a watchdog is in existence.
|
||||
*/
|
||||
if (pswitch->rbkl.type != CONSTANT && pswitch->val <= TRANS_STATE) {
|
||||
status = check_readback(pswitch);
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
}
|
||||
|
||||
/* store time in record */
|
||||
recGblGetTimeStamp(pswitch);
|
||||
|
||||
/* alarm checking is done in check_readback */
|
||||
|
||||
/*
|
||||
* check event list - though some monitors are
|
||||
* performed in other areas of the code.
|
||||
*/
|
||||
monitor(pswitch);
|
||||
|
||||
/* process forward link */
|
||||
recGblFwdLink(pswitch);
|
||||
|
||||
pswitch->pact = FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
/* special processing */
|
||||
static long special(
|
||||
struct dbAddr *paddr,
|
||||
int after
|
||||
)
|
||||
{
|
||||
if (after && ((struct switchRecord *) paddr->precord)->omsl == SUPERVISORY) {
|
||||
((struct switchRecord *) paddr->precord)->intn = 1;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* monitor fields */
|
||||
static void monitor(struct switchRecord *pswitch)
|
||||
{
|
||||
int monitor_mask = 0;
|
||||
short stat, sevr, nsta, nsev;
|
||||
|
||||
if (pswitch->aftt == FAIL_FOLLOW_RDBK) {
|
||||
monitor_mask = recGblResetAlarms(pswitch);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* recGblResetAlarms() is not used here, because alarm resets
|
||||
* are not supposed to be done when this record is processed.
|
||||
* (i.e. nsta and nsev are not set to zero) However, these
|
||||
* alarms are reset in check_readback().
|
||||
*/
|
||||
stat = pswitch->stat; sevr = pswitch->sevr; nsta = pswitch->nsta;
|
||||
nsev = pswitch->nsev; pswitch->stat = nsta; pswitch->sevr = nsev;
|
||||
|
||||
/*
|
||||
* Check alarm condition -
|
||||
* normally done automatically by recGblResetAlarms()
|
||||
*/
|
||||
if (stat != nsta || sevr != nsev) {
|
||||
monitor_mask |= DBE_ALARM;
|
||||
db_post_events(pswitch, &pswitch->stat, DBE_VALUE);
|
||||
db_post_events(pswitch, &pswitch->sevr, DBE_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* check value */
|
||||
if (pswitch->val != pswitch->mlst) {
|
||||
/* trigger monitor on value */
|
||||
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
||||
pswitch->mlst = pswitch->val;
|
||||
}
|
||||
|
||||
if (monitor_mask) {
|
||||
db_post_events(pswitch, &pswitch->val, monitor_mask);
|
||||
}
|
||||
|
||||
/* check outv */
|
||||
MON_FIELD(pswitch->outv, pswitch->lout);
|
||||
}
|
||||
|
||||
/* get state */
|
||||
static long get_value(
|
||||
struct switchRecord *pswitch,
|
||||
struct valueDes *pvdes
|
||||
)
|
||||
{
|
||||
pvdes->field_type = DBF_ENUM;
|
||||
pvdes->no_elements = 1;
|
||||
(unsigned short *)(pvdes->pvalue) = &pswitch->val;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* get precision */
|
||||
static long get_precision(
|
||||
struct dbAddr *paddr,
|
||||
long *precision
|
||||
)
|
||||
{
|
||||
struct switchRecord *pswitch = (struct switchRecord *) paddr->precord;
|
||||
|
||||
if (paddr->pfield == &pswitch->xtim)
|
||||
*precision = pswitch->prec;
|
||||
else
|
||||
*precision = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* get state string */
|
||||
static long get_enum_str(
|
||||
struct dbAddr *paddr,
|
||||
char *dest
|
||||
)
|
||||
{
|
||||
struct switchRecord *pswitch = (struct switchRecord *) paddr->precord;
|
||||
char *string;
|
||||
|
||||
if (pswitch->val < STRING_COUNT-1) {
|
||||
string = pswitch->ssi + (pswitch->val * sizeof(pswitch->ssi));
|
||||
strncpy(dest, string, sizeof(pswitch->ssi));
|
||||
}
|
||||
else {
|
||||
strcpy(dest, "Illegal Value");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* get all strings */
|
||||
static long get_enum_strs(
|
||||
struct dbAddr *paddr,
|
||||
struct dbr_enumStrs *pes
|
||||
)
|
||||
{
|
||||
struct switchRecord *pswitch = (struct switchRecord *) paddr->precord;
|
||||
char *string;
|
||||
int i;
|
||||
short count = 0;
|
||||
|
||||
memset(pes->strs, '\0', sizeof(pes->strs));
|
||||
string = pswitch->ssi;
|
||||
for (i=0; i<STRING_COUNT; i++) {
|
||||
strncpy(pes->strs[i], string, sizeof(pswitch->ssi));
|
||||
if (*string)
|
||||
count = i + 1;
|
||||
string += sizeof(pswitch->ssi);
|
||||
}
|
||||
pes->no_str = count;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* output to "switch" link, and set watchdog */
|
||||
static long output_and_watch(struct switchRecord *pswitch)
|
||||
{
|
||||
long status;
|
||||
|
||||
/* Process switch forward link */
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
|
||||
if (pswitch->rbkl.type == CONSTANT) {
|
||||
pswitch->val = (pswitch->val == SET_TO_RESET) ? RESET : SET;
|
||||
}
|
||||
else {
|
||||
if (pswitch->xtim) {
|
||||
/* activate watchdog */
|
||||
wdStart((WDOG_ID) ((struct PVT *)pswitch->pvt)->watchdog,
|
||||
(int) pswitch->xtim * sysClkRateGet(),
|
||||
(FUNCPTR) watchdog, (int) pswitch);
|
||||
}
|
||||
else {
|
||||
/* check readback immediately */
|
||||
status = check_readback(pswitch);
|
||||
if (status)
|
||||
return(status);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check readback value */
|
||||
static long check_readback(struct switchRecord *pswitch)
|
||||
{
|
||||
long status;
|
||||
int condition;
|
||||
|
||||
/* get readback */
|
||||
status = recGblGetFastLink(&pswitch->rbkl, (void *) pswitch, &pswitch->rbkv);
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
/* choose which condition to check */
|
||||
condition = (pswitch->dthr == BELOW) ? (pswitch->rbkv <= pswitch->rthr) : (pswitch->rbkv >= pswitch->rthr);
|
||||
|
||||
/* check readback value */
|
||||
if (condition) {
|
||||
if (pswitch->pint == SET) {
|
||||
/* Switch set properly */
|
||||
pswitch->val = SET;
|
||||
pswitch->nsta = pswitch->nsev = 0;
|
||||
}
|
||||
else {
|
||||
/* SET ALARM - Was supposed to be reset, but was found to be set */
|
||||
recGblSetSevr(pswitch, STATE_ALARM, pswitch->srfs);
|
||||
pswitch->val = SET;
|
||||
}
|
||||
|
||||
/* Drive output to what it should be given readback, if FOLLOW RDBK set */
|
||||
if (pswitch->aftt == FAIL_FOLLOW_RDBK) {
|
||||
if (pswitch->outv != pswitch->onv) {
|
||||
pswitch->outv = pswitch->onv;
|
||||
|
||||
/* drive output */
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
}
|
||||
pswitch->pint = SET;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pswitch->pint == RESET) {
|
||||
/* switch reset properly */
|
||||
pswitch->val = RESET;
|
||||
pswitch->nsta = pswitch->nsev = 0;
|
||||
}
|
||||
else {
|
||||
/* SET ALARM - Was supposed to be set, but was found to be reset */
|
||||
recGblSetSevr(pswitch, STATE_ALARM, pswitch->rsfs);
|
||||
pswitch->val = RESET;
|
||||
}
|
||||
|
||||
/* Drive output to what it should be given readback, if FOLLOW RDBK set */
|
||||
if (pswitch->aftt == FAIL_FOLLOW_RDBK) {
|
||||
if (pswitch->outv != pswitch->offv) {
|
||||
pswitch->outv = pswitch->offv;
|
||||
|
||||
/* drive output */
|
||||
if (pswitch->swtc.type == DB_LINK) {
|
||||
dbScanPassive((void *) pswitch, ((struct dbAddr *)pswitch->swtc.value.db_link.pdbAddr)->precord);
|
||||
}
|
||||
}
|
||||
pswitch->pint = RESET;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* callback */
|
||||
static void callback(CALLBACK *pcallback)
|
||||
{
|
||||
struct switchRecord *pswitch;
|
||||
|
||||
/*
|
||||
* Retrieve pointer to record from callback structure.
|
||||
* This value is fixed at initialization, and will
|
||||
* not be changed, so the database does not have to
|
||||
* be locked for this actiion.
|
||||
*/
|
||||
callbackGetUser((void *) pswitch, pcallback);
|
||||
|
||||
/* lock the database */
|
||||
dbScanLock((struct dbCommon *) pswitch);
|
||||
|
||||
/* check the readback value */
|
||||
check_readback(pswitch);
|
||||
|
||||
/* monitor any changes */
|
||||
monitor(pswitch);
|
||||
|
||||
/* unlock database */
|
||||
dbScanUnlock((struct dbCommon *) pswitch);
|
||||
}
|
||||
|
||||
/* watchdog process adds callback to queue */
|
||||
static void watchdog(struct switchRecord *pswitch)
|
||||
{
|
||||
callbackRequest(&((struct PVT *)pswitch->pvt)->callback);
|
||||
}
|
||||
|
||||
@@ -44,11 +44,13 @@
|
||||
* 2.00 02-20-95 nda added queuing to SCAN_IO_EVENT mode so no transitions of data
|
||||
* would be missed. Can put back to cached mode by setting
|
||||
* recWaitCacheMode (effects all wait records !)
|
||||
* 2.01 08-07-95 nda Multiple records with DOLN's didn't work,
|
||||
* added calloc for dola structure.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#define VERSION 2.00
|
||||
#define VERSION 2.01
|
||||
|
||||
|
||||
|
||||
@@ -229,6 +231,7 @@ static long init_record(pwait,pass)
|
||||
pwait->inka = calloc(1,sizeof(struct dbAddr));
|
||||
pwait->inla = calloc(1,sizeof(struct dbAddr));
|
||||
pwait->outa = calloc(1,sizeof(struct dbAddr));
|
||||
pwait->dola = calloc(1,sizeof(struct dbAddr));
|
||||
|
||||
pwait->cbst = calloc(1,sizeof(struct cbStruct));
|
||||
|
||||
@@ -555,7 +558,7 @@ static long special(paddr,after)
|
||||
db_post_events(pwait,&pwait->clcv,DBE_VALUE);
|
||||
memcpy(pwait->rpcl,rpbuf,sizeof(pwait->rpcl));
|
||||
db_post_events(pwait,pwait->calc,DBE_VALUE);
|
||||
db_post_events(pwait,pwait->clcv,DBE_VALUE);
|
||||
db_post_events(pwait,&pwait->clcv,DBE_VALUE);
|
||||
return(0);
|
||||
break;
|
||||
default:
|
||||
@@ -766,10 +769,10 @@ static void reqOutput(pwait)
|
||||
void execOutput(pcbst)
|
||||
struct cbStruct *pcbst;
|
||||
{
|
||||
static long status;
|
||||
static long nRequest = 1;
|
||||
static long options = 0;
|
||||
static double oldDold;
|
||||
long status;
|
||||
long nRequest = 1;
|
||||
long options = 0;
|
||||
double oldDold;
|
||||
|
||||
/* if output link is valid , decide between VAL and DOL */
|
||||
if(!pcbst->pwait->outv) {
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/*
|
||||
* 07-27-95 nda made QUEUE_SIZE a global variable so it could
|
||||
* be changed at boot time for LOTS OF WAIT records
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#include <string.h>
|
||||
@@ -18,7 +25,8 @@
|
||||
|
||||
extern int interruptAccept;
|
||||
|
||||
#define QUEUE_SIZE 256
|
||||
int recWaitCaQsize = 256;
|
||||
|
||||
LOCAL int taskid=0;
|
||||
LOCAL RING_ID ringQ;;
|
||||
LOCAL FAST_LOCK lock;
|
||||
@@ -50,7 +58,7 @@ LOCAL void eventCallback(struct event_handler_args eha)
|
||||
LOCAL void recWaitCaStart(void)
|
||||
{
|
||||
FASTLOCKINIT(&lock);
|
||||
if((ringQ = rngCreate(sizeof(void *) * QUEUE_SIZE)) == NULL) {
|
||||
if((ringQ = rngCreate(sizeof(void *) * recWaitCaQsize)) == NULL) {
|
||||
errMessage(0,"recWaitCaStart failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
@@ -12,14 +13,10 @@ OBJS = \
|
||||
caserverio.o caservertask.o camsgtask.o camessage.o \
|
||||
rsrv_init.o cast_server.o online_notify.o globalsource.o
|
||||
|
||||
PROD = dbgLib rsrvLib
|
||||
PROD = rsrvLib
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
dbgLib: $(OBJS) globalsource.o
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) globalsource.o $(LDLIBS)
|
||||
|
||||
rsrvLib: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
@@ -187,7 +187,6 @@ struct db_addr *pAddr,
|
||||
unsigned cid
|
||||
);
|
||||
|
||||
LOCAL unsigned bucketID;
|
||||
|
||||
|
||||
/*
|
||||
@@ -1215,7 +1214,8 @@ struct client *client
|
||||
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
status = bucketRemoveItemUnsignedId (pCaBucket, &pciu->sid);
|
||||
if(status != BUCKET_SUCCESS){
|
||||
if(status != S_bucket_success){
|
||||
errMessage (status, "Bad resource id during channel clear");
|
||||
logBadId(client, mp);
|
||||
}
|
||||
ellAdd(&rsrv_free_addrq, &pciu->node);
|
||||
@@ -1623,7 +1623,7 @@ struct client *client
|
||||
if (CA_V44(CA_PROTOCOL_VERSION,htons(mp->m_count))) {
|
||||
sid = ~0U;
|
||||
count = 0;
|
||||
type = -1;
|
||||
type = ca_server_port;
|
||||
}
|
||||
else {
|
||||
struct channel_in_use *pchannel;
|
||||
@@ -1685,9 +1685,9 @@ struct db_addr *pAddr,
|
||||
unsigned cid
|
||||
)
|
||||
{
|
||||
static unsigned bucketID;
|
||||
unsigned *pCID;
|
||||
struct channel_in_use *pchannel;
|
||||
unsigned sid;
|
||||
int status;
|
||||
|
||||
/* get block off free list if possible */
|
||||
@@ -1715,23 +1715,37 @@ unsigned cid
|
||||
/*
|
||||
* allocate a server id and enter the channel pointer
|
||||
* in the table
|
||||
*
|
||||
* NOTE: This detects the case where the PV id wraps
|
||||
* around and we attempt to have two resources on the same id.
|
||||
* The lock is applied here because on some architectures the
|
||||
* ++ operator isnt atomic.
|
||||
*/
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
sid = bucketID++;
|
||||
/*
|
||||
* bypass read only warning
|
||||
*/
|
||||
pCID = (unsigned *) &pchannel->sid;
|
||||
*pCID = sid;
|
||||
status = bucketAddItemUnsignedId (
|
||||
pCaBucket,
|
||||
&pchannel->sid,
|
||||
pchannel);
|
||||
|
||||
do {
|
||||
/*
|
||||
* bypass read only warning
|
||||
*/
|
||||
pCID = (unsigned *) &pchannel->sid;
|
||||
*pCID = bucketID++;
|
||||
|
||||
/*
|
||||
* Verify that this id is not in use
|
||||
*/
|
||||
status = bucketAddItemUnsignedId (
|
||||
pCaBucket,
|
||||
&pchannel->sid,
|
||||
pchannel);
|
||||
} while (status != S_bucket_success);
|
||||
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
if(status!=BUCKET_SUCCESS){
|
||||
|
||||
if(status!=S_bucket_success){
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
ellAdd(&rsrv_free_addrq, &pchannel->node);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
errMessage (status, "Unable to allocate server id");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1984,7 +1998,7 @@ struct client *pc
|
||||
*
|
||||
* used to be a macro
|
||||
*/
|
||||
LOCAL struct channel_in_use *MPTOPCIU(struct extmsg *mp)
|
||||
LOCAL struct channel_in_use *MPTOPCIU (struct extmsg *mp)
|
||||
{
|
||||
struct channel_in_use *pciu;
|
||||
const unsigned id = mp->m_cid;
|
||||
|
||||
@@ -111,22 +111,37 @@ int lock_needed;
|
||||
|
||||
anerrno = errnoGet();
|
||||
|
||||
if( (anerrno!=ECONNABORTED&&
|
||||
anerrno!=ECONNRESET&&
|
||||
anerrno!=EPIPE&&
|
||||
anerrno!=ETIMEDOUT)||
|
||||
CASDEBUG>2){
|
||||
if(pclient->proto == IPPROTO_TCP) {
|
||||
if( (anerrno!=ECONNABORTED&&
|
||||
anerrno!=ECONNRESET&&
|
||||
anerrno!=EPIPE&&
|
||||
anerrno!=ETIMEDOUT)||
|
||||
CASDEBUG>2){
|
||||
|
||||
logMsg(
|
||||
"CAS: client unreachable \"%s\"\n",
|
||||
(int)strerror(anerrno),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
logMsg(
|
||||
"CAS: TCP send failed because \"%s\"\n",
|
||||
(int)strerror(anerrno),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
pclient->disconnect = TRUE;
|
||||
}
|
||||
else if (pclient->proto == IPPROTO_UDP) {
|
||||
logMsg(
|
||||
"CAS: UDP send failed because \"%s\"\n",
|
||||
(int)strerror(anerrno),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
else {
|
||||
assert (0);
|
||||
}
|
||||
pclient->disconnect = TRUE;
|
||||
}
|
||||
else{
|
||||
logMsg(
|
||||
|
||||
@@ -88,11 +88,10 @@ int req_server(void)
|
||||
struct sockaddr_in serverAddr; /* server's address */
|
||||
int status;
|
||||
int i;
|
||||
short port;
|
||||
|
||||
taskwdInsert((int)taskIdCurrent,NULL,NULL);
|
||||
|
||||
port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
|
||||
ca_server_port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
|
||||
|
||||
if (IOC_sock != 0 && IOC_sock != ERROR)
|
||||
if ((status = close(IOC_sock)) == ERROR)
|
||||
@@ -122,7 +121,7 @@ int req_server(void)
|
||||
/* Zero the sock_addr structure */
|
||||
bfill((char *)&serverAddr, sizeof(serverAddr), 0);
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(port);
|
||||
serverAddr.sin_port = htons(ca_server_port);
|
||||
|
||||
/* get server's Internet address */
|
||||
if (bind(IOC_sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == ERROR) {
|
||||
@@ -322,15 +321,13 @@ LOCAL int terminate_one_client(struct client *client)
|
||||
pCaBucket,
|
||||
&pciu->sid);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
if(status != BUCKET_SUCCESS){
|
||||
logMsg(
|
||||
"%s: Bad id=%d at close",
|
||||
(int)__FILE__,
|
||||
pciu->sid,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if(status != S_bucket_success){
|
||||
errPrintf (
|
||||
status,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"Bad id=%d at close",
|
||||
pciu->sid);
|
||||
}
|
||||
status = asRemoveClient(&pciu->asClientPVT);
|
||||
if(status!=0 && status != S_asLib_asNotActive){
|
||||
@@ -469,7 +466,7 @@ int client_stat(void)
|
||||
if(pCaBucket){
|
||||
printf( "The server's resource id conversion table:\n");
|
||||
FASTLOCK(&rsrv_free_addrq_lck);
|
||||
bucketShow(pCaBucket);
|
||||
bucketShow (pCaBucket);
|
||||
FASTUNLOCK(&rsrv_free_addrq_lck);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user