Compare commits
152 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
297f0b8c31 | ||
|
|
cc20412693 | ||
|
|
7021cd3589 | ||
|
|
b7acf453c2 | ||
|
|
c9abc2c82e | ||
|
|
a7484494c4 | ||
|
|
52cfbe92bf | ||
|
|
75f0fb2b0c | ||
|
|
ed36723d6c | ||
|
|
f7a5da9139 | ||
|
|
254c5b1620 | ||
|
|
c6aab85d79 | ||
|
|
d54724fce1 | ||
|
|
60c0acab3c | ||
|
|
69f33b9e23 | ||
|
|
9191863094 | ||
|
|
1beb157ab0 | ||
|
|
41ae285075 | ||
|
|
222063ac53 | ||
|
|
3342ca120f | ||
|
|
13b785e594 | ||
|
|
6931273fef | ||
|
|
8d52177933 | ||
|
|
b64fa8bd87 | ||
|
|
34ce2ab6ac | ||
|
|
43ef20b90c | ||
|
|
818bc0d475 | ||
|
|
ca2f9aff52 | ||
|
|
64a93df872 | ||
|
|
ecc03e9ad9 | ||
|
|
db1b46e5f9 | ||
|
|
d87295397e | ||
|
|
7277c336f7 | ||
|
|
30ad5b1149 | ||
|
|
c6bcd1a10b | ||
|
|
f3cf369071 | ||
|
|
adffe02a2d | ||
|
|
e635080cef | ||
|
|
be85da6a3a | ||
|
|
c16006f34d | ||
|
|
72491d8829 | ||
|
|
cb78c5adb8 | ||
|
|
1a2cd5953d | ||
|
|
5da79a5f56 | ||
|
|
9f2d9587f0 | ||
|
|
74e405969a | ||
|
|
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 |
45
COPYRIGHT_UniversityOfChicago
Normal file
45
COPYRIGHT_UniversityOfChicago
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
|
||||
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
|
||||
AND IN ALL SOURCE LISTINGS OF THE CODE.
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
Argonne National Laboratory (ANL), with facilities in the States of
|
||||
Illinois and Idaho, is owned by the United States Government, and
|
||||
operated by the University of Chicago under provision of a contract
|
||||
with the Department of Energy.
|
||||
|
||||
Portions of this material resulted from work developed under a U.S.
|
||||
Government contract and are subject to the following license: For
|
||||
a period of five years from March 30, 1993, the Government is
|
||||
granted for itself and others acting on its behalf a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, and perform
|
||||
publicly and display publicly. With the approval of DOE, this
|
||||
period may be renewed for two additional five year periods.
|
||||
Following the expiration of this period or periods, the Government
|
||||
is granted for itself and others acting on its behalf, a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, distribute copies
|
||||
to the public, perform publicly and display publicly, and to permit
|
||||
others to do so.
|
||||
|
||||
*****************************************************************
|
||||
DISCLAIMER
|
||||
*****************************************************************
|
||||
|
||||
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
|
||||
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
|
||||
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
|
||||
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
||||
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
|
||||
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
|
||||
OWNED RIGHTS.
|
||||
|
||||
*****************************************************************
|
||||
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
140
MakeRelease
Executable file
140
MakeRelease
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/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.2 1995/08/28 15:49:54 jba
|
||||
# Added startup directory to release tar file
|
||||
#
|
||||
# Revision 1.1 1995/08/17 20:14:56 jba
|
||||
# Added base/tools scripts functionality to base/Makefile, removed scripts
|
||||
# Moved base/tools/MakeRelease to base dir.
|
||||
#
|
||||
# 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.$$;
|
||||
|
||||
ls base/*COPYRIGHT* >> /tmp/make_release.out.$$;
|
||||
|
||||
if [ -d startup ];
|
||||
then
|
||||
find startup -name CVS -prune -o ! -type d -print \
|
||||
>> /tmp/make_release.out.$$;
|
||||
fi
|
||||
|
||||
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.
|
||||
|
||||
|
||||
10
SkeletonCOPYRIGHT_UniversityOfChicago
Normal file
10
SkeletonCOPYRIGHT_UniversityOfChicago
Normal file
@@ -0,0 +1,10 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
@@ -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) $<
|
||||
|
||||
|
||||
274
src/ca/access.c
274
src/ca/access.c
@@ -1,3 +1,4 @@
|
||||
/* $Id$ */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* L O S A L A M O S */
|
||||
@@ -92,7 +93,34 @@
|
||||
/* 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.77 1995/09/01 14:31:32 mrk
|
||||
* Fixed bug causing memory problem
|
||||
*
|
||||
* Revision 1.76 1995/08/23 00:34:06 jhill
|
||||
* fixed vxWorks specific SPARC data alignment problem
|
||||
*
|
||||
* Revision 1.75 1995/08/22 00:15:19 jhill
|
||||
* Use 1.0/USEC_PER_SEC and not 1.0e-6
|
||||
* Check for S_db_Pending when calling dbPutNotify()
|
||||
*
|
||||
* 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 +471,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 +594,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 +649,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 +704,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 +759,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 +887,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 +909,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 +934,7 @@ int APIENTRY ca_build_and_connect
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_search_and_connect
|
||||
int epicsShareAPI ca_search_and_connect
|
||||
(
|
||||
char *name_str,
|
||||
chid *chixptr,
|
||||
@@ -950,13 +979,14 @@ int APIENTRY ca_search_and_connect
|
||||
* also allocate enough for the channel name & paddr
|
||||
* block
|
||||
*/
|
||||
size = sizeof(*chix) + strcnt + sizeof(struct db_addr);
|
||||
size = CA_MESSAGE_ALIGN(sizeof(*chix) + strcnt) +
|
||||
sizeof(struct db_addr);
|
||||
*chixptr = chix = (chid) calloc(1,size);
|
||||
if (!chix){
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
chix->id.paddr = (struct db_addr *)
|
||||
(strcnt + (char *) (chix + 1));
|
||||
(CA_MESSAGE_ALIGN(sizeof(*chix)+strcnt) + (char *)chix);
|
||||
*chix->id.paddr = tmp_paddr;
|
||||
chix->puser = puser;
|
||||
chix->pConnFunc = conn_func;
|
||||
@@ -1010,13 +1040,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 +1164,7 @@ int reply_type
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_array_get
|
||||
int epicsShareAPI ca_array_get
|
||||
(
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -1195,8 +1232,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 +1251,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 +1312,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 +1346,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 +1377,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 +1477,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 +1581,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 +1621,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 +1688,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 +1929,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 +1961,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))
|
||||
{
|
||||
@@ -1929,7 +1975,7 @@ void (*pfunc)(struct access_rights_handler_args))
|
||||
/*
|
||||
* make certain that it runs at least once
|
||||
*/
|
||||
if(chan->state == cs_conn){
|
||||
if(chan->state == cs_conn && chan->pAccessRightsFunc){
|
||||
args.chid = chan;
|
||||
args.ar = chan->ar;
|
||||
(*chan->pAccessRightsFunc)(args);
|
||||
@@ -1943,7 +1989,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 +2021,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 +2056,7 @@ void *astarg
|
||||
*
|
||||
*
|
||||
*/
|
||||
int APIENTRY ca_add_masked_array_event
|
||||
int epicsShareAPI ca_add_masked_array_event
|
||||
(
|
||||
chtype type,
|
||||
unsigned long count,
|
||||
@@ -2140,8 +2186,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 +2421,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 +2496,7 @@ int APIENTRY ca_clear_event (evid monix)
|
||||
else{
|
||||
LOCK;
|
||||
ellDelete(&monix->chan->eventq, &monix->node);
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
status = ECA_NORMAL;
|
||||
}
|
||||
@@ -2471,7 +2520,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;
|
||||
@@ -2485,6 +2534,8 @@ int APIENTRY ca_clear_channel (chid chix)
|
||||
chix->type = TYPENOTINUSE;
|
||||
old_chan_state = chix->state;
|
||||
chix->state = cs_closed;
|
||||
chix->pAccessRightsFunc = NULL;
|
||||
chix->pConnFunc = NULL;
|
||||
|
||||
/* the while is only so I can break to the lock exit */
|
||||
LOCK;
|
||||
@@ -2614,7 +2665,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 +2684,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 +2699,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 +2712,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 +2727,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 +2777,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 +2865,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 +2902,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 +2922,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 +2938,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 +2947,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 +3310,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 +3341,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 +3357,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 +3434,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;
|
||||
}
|
||||
|
||||
232
src/ca/acctst.c
232
src/ca/acctst.c
@@ -5,6 +5,13 @@
|
||||
|
||||
static char *sccsId = "@(#) $Id$";
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.29 1995/08/22 00:16:34 jhill
|
||||
* Added test of the duration of ca_pend_event()
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#include <LIB$ROUTINES.H>
|
||||
#endif
|
||||
@@ -19,7 +26,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 +34,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 +46,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)
|
||||
@@ -82,25 +106,45 @@ int doacctst(char *pname)
|
||||
chid chix4;
|
||||
struct dbr_gr_float *ptr = NULL;
|
||||
struct dbr_gr_float *pgrfloat = NULL;
|
||||
float *pfloat = NULL;
|
||||
double *pdouble = NULL;
|
||||
dbr_float_t *pfloat = NULL;
|
||||
dbr_double_t *pdouble = NULL;
|
||||
long status;
|
||||
long i, j;
|
||||
evid monix;
|
||||
char pstring[NUM][MAX_STRING_SIZE];
|
||||
|
||||
unsigned size;
|
||||
|
||||
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*/
|
||||
|
||||
ptr = (struct dbr_gr_float *)
|
||||
malloc(dbr_size_n(DBR_GR_FLOAT, NUM));
|
||||
{
|
||||
TS_STAMP end_time;
|
||||
TS_STAMP start_time;
|
||||
dbr_double_t delay;
|
||||
dbr_double_t request = 0.5;
|
||||
dbr_double_t 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);
|
||||
}
|
||||
|
||||
size = dbr_size_n(DBR_GR_FLOAT, NUM);
|
||||
ptr = (struct dbr_gr_float *) malloc(size);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
|
||||
@@ -213,41 +257,81 @@ 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;
|
||||
dbr_double_t incr;
|
||||
dbr_double_t epsil;
|
||||
dbr_double_t 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
|
||||
* solicitations
|
||||
*/
|
||||
if(ca_read_access(chix4)){
|
||||
float temp;
|
||||
dbr_float_t temp;
|
||||
|
||||
printf("Performing multiple get test...");
|
||||
fflush(stdout);
|
||||
@@ -268,7 +352,7 @@ int doacctst(char *pname)
|
||||
printf("Performing multiple put test...");
|
||||
fflush(stdout);
|
||||
for(i=0; i<10000; i++){
|
||||
double fval = 3.3;
|
||||
dbr_double_t fval = 3.3;
|
||||
status = ca_put(DBR_DOUBLE, chix4, &fval);
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
@@ -315,7 +399,7 @@ int doacctst(char *pname)
|
||||
printf("Performing multiple put callback test...");
|
||||
fflush(stdout);
|
||||
for(i=0; i<10000; i++){
|
||||
float fval = 3.3;
|
||||
dbr_float_t fval = 3.3F;
|
||||
status = ca_array_put_callback(
|
||||
DBR_FLOAT,
|
||||
1,
|
||||
@@ -339,8 +423,8 @@ int doacctst(char *pname)
|
||||
printf("Performing multiple monitor test...");
|
||||
fflush(stdout);
|
||||
{
|
||||
evid mid[1000];
|
||||
float temp;
|
||||
evid mid[1000];
|
||||
dbr_float_t temp;
|
||||
|
||||
for(i=0; i<NELEMENTS(mid); i++){
|
||||
SEVCHK(ca_add_event(DBR_GR_FLOAT, chix4, null_event,
|
||||
@@ -418,8 +502,8 @@ int doacctst(char *pname)
|
||||
SEVCHK(status, NULL);
|
||||
}
|
||||
|
||||
pfloat = (float *) calloc(sizeof(float),NUM);
|
||||
pdouble = (double *) calloc(sizeof(double),NUM);
|
||||
pfloat = (dbr_float_t *) calloc(sizeof(*pfloat),NUM);
|
||||
pdouble = (dbr_double_t *) calloc(sizeof(*pdouble),NUM);
|
||||
pgrfloat = (struct dbr_gr_float *) calloc(sizeof(*pgrfloat),NUM);
|
||||
|
||||
if (VALID_DB_REQ(chix1->type))
|
||||
@@ -475,13 +559,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 +589,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)
|
||||
{
|
||||
@@ -521,9 +657,15 @@ void null_event(struct event_handler_args args)
|
||||
void write_event(struct event_handler_args args)
|
||||
{
|
||||
int status;
|
||||
float a = *(float *) args.dbr;
|
||||
dbr_float_t *pFloat = (dbr_float_t *) args.dbr;
|
||||
dbr_float_t a;
|
||||
|
||||
a += 10.1;
|
||||
if (!args.dbr) {
|
||||
return;
|
||||
}
|
||||
|
||||
a = *pFloat;
|
||||
a += 10.1F;
|
||||
|
||||
status = ca_array_put(
|
||||
DBR_FLOAT,
|
||||
@@ -544,15 +686,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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -612,10 +754,10 @@ void test_sync_groups(chid chix)
|
||||
*/
|
||||
void multiple_sg_requests(chid chix, CA_SYNC_GID gid)
|
||||
{
|
||||
int status;
|
||||
unsigned i;
|
||||
static float fvalput = 3.3;
|
||||
static float fvalget;
|
||||
int status;
|
||||
unsigned i;
|
||||
static dbr_float_t fvalput = 3.3F;
|
||||
static dbr_float_t fvalget;
|
||||
|
||||
for(i=0; i<1000; i++){
|
||||
if(ca_write_access(chix)){
|
||||
|
||||
@@ -19,7 +19,7 @@ void caAddConfiguredAddr(
|
||||
int port);
|
||||
|
||||
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
|
||||
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort);
|
||||
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort);
|
||||
|
||||
union caAddr{
|
||||
struct sockaddr_in inetAddr;
|
||||
|
||||
@@ -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;
|
||||
|
||||
211
src/ca/iocinf.c
211
src/ca/iocinf.c
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -755,7 +757,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
|
||||
CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status);
|
||||
|
||||
if (status != sendCnt) {
|
||||
if (((unsigned long)status) != sendCnt) {
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
@@ -926,7 +928,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
|
||||
break;
|
||||
}
|
||||
|
||||
assert (status<=writeSpace);
|
||||
assert (((unsigned long)status)<=writeSpace);
|
||||
|
||||
CAC_RING_BUFFER_WRITE_ADVANCE(&piiu->recv, status);
|
||||
|
||||
@@ -936,7 +938,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
|
||||
*/
|
||||
piiu->timeAtLastRecv = ca_static->currentTime;
|
||||
|
||||
if (status != writeSpace) {
|
||||
if (((unsigned long)status) != writeSpace) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -1195,6 +1196,8 @@ void close_ioc (struct ioc_in_use *piiu)
|
||||
piiuCast = NULL;
|
||||
}
|
||||
else {
|
||||
chid *pNext;
|
||||
|
||||
/*
|
||||
* remove IOC from the hash table
|
||||
*/
|
||||
@@ -1208,73 +1211,20 @@ void close_ioc (struct ioc_in_use *piiu)
|
||||
* handler tries to use a channel before
|
||||
* I mark it disconnected.
|
||||
*/
|
||||
chix = (chid) &piiu->chidlist.node.next;
|
||||
while (chix = (chid) chix->node.next) {
|
||||
chix->type = TYPENOTCONN;
|
||||
chix->count = 0U;
|
||||
chix = (chid) ellFirst(&piiu->chidlist);
|
||||
while (chix) {
|
||||
chix->state = cs_prev_conn;
|
||||
chix->id.sid = ~0U;
|
||||
chix->ar.read_access = FALSE;
|
||||
chix->ar.write_access = FALSE;
|
||||
/*
|
||||
* try to reconnect
|
||||
*/
|
||||
chix->retry = 0U;
|
||||
chix = (chid) ellNext(&chix->node);
|
||||
}
|
||||
|
||||
if (piiu->chidlist.count) {
|
||||
ca_signal (ECA_DISCONN,piiu->host_name_str);
|
||||
chix = (chid) ellFirst(&piiu->chidlist);
|
||||
while (chix) {
|
||||
pNext = (chid) ellNext(&chix->node);
|
||||
cacDisconnectChannel(chix, TRUE);
|
||||
chix = pNext;
|
||||
}
|
||||
|
||||
/*
|
||||
* clear outstanding get call backs
|
||||
*/
|
||||
caIOBlockListFree (&pend_read_list, chix, TRUE, ECA_DISCONN);
|
||||
|
||||
/*
|
||||
* clear outstanding put call backs
|
||||
*/
|
||||
caIOBlockListFree (&pend_write_list, chix, TRUE, ECA_DISCONN);
|
||||
|
||||
/*
|
||||
* call their connection handler as required
|
||||
*/
|
||||
chix = (chid) &piiu->chidlist.node.next;
|
||||
while (chix = (chid) chix->node.next) {
|
||||
LOCKEVENTS;
|
||||
if (chix->pConnFunc) {
|
||||
struct connection_handler_args args;
|
||||
|
||||
args.chid = chix;
|
||||
args.op = CA_OP_CONN_DOWN;
|
||||
(*chix->pConnFunc) (args);
|
||||
}
|
||||
if (chix->pAccessRightsFunc) {
|
||||
struct access_rights_handler_args args;
|
||||
|
||||
args.chid = chix;
|
||||
args.ar = chix->ar;
|
||||
(*chix->pAccessRightsFunc) (args);
|
||||
}
|
||||
UNLOCKEVENTS;
|
||||
chix->piiu = piiuCast;
|
||||
}
|
||||
|
||||
/*
|
||||
* move all channels to the broadcast IIU
|
||||
*
|
||||
* if we loose the broadcast IIU its a severe error
|
||||
*/
|
||||
assert (piiuCast);
|
||||
ellConcat (&piiuCast->chidlist, &piiu->chidlist);
|
||||
assert (piiu->chidlist.count==0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to reconnect
|
||||
*/
|
||||
ca_static->ca_search_retry = 0;
|
||||
|
||||
if (fd_register_func) {
|
||||
LOCKEVENTS;
|
||||
(*fd_register_func) (fd_register_arg, piiu->sock_chan, FALSE);
|
||||
@@ -1297,11 +1247,78 @@ void close_ioc (struct ioc_in_use *piiu)
|
||||
|
||||
ellFree (&piiu->destAddr);
|
||||
|
||||
ca_signal (ECA_DISCONN,piiu->host_name_str);
|
||||
|
||||
free (piiu);
|
||||
|
||||
UNLOCK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* cacDisconnectChannel()
|
||||
*/
|
||||
void cacDisconnectChannel(chid chix, int fullDisconnect)
|
||||
{
|
||||
struct ioc_in_use *piiu;
|
||||
|
||||
chix->type = TYPENOTCONN;
|
||||
chix->count = 0U;
|
||||
chix->id.sid = ~0U;
|
||||
chix->ar.read_access = FALSE;
|
||||
chix->ar.write_access = FALSE;
|
||||
|
||||
/*
|
||||
* try to reconnect
|
||||
*/
|
||||
chix->retry = 0U;
|
||||
|
||||
/*
|
||||
* call their connection handler as required
|
||||
*/
|
||||
if (fullDisconnect) {
|
||||
chix->state = cs_prev_conn;
|
||||
|
||||
/*
|
||||
* clear outstanding get call backs
|
||||
*/
|
||||
caIOBlockListFree (&pend_read_list, chix,
|
||||
TRUE, ECA_DISCONN);
|
||||
|
||||
/*
|
||||
* clear outstanding put call backs
|
||||
*/
|
||||
caIOBlockListFree (&pend_write_list, chix,
|
||||
TRUE, ECA_DISCONN);
|
||||
|
||||
LOCKEVENTS;
|
||||
if (chix->pConnFunc) {
|
||||
struct connection_handler_args args;
|
||||
|
||||
args.chid = chix;
|
||||
args.op = CA_OP_CONN_DOWN;
|
||||
(*chix->pConnFunc) (args);
|
||||
}
|
||||
if (chix->pAccessRightsFunc) {
|
||||
struct access_rights_handler_args args;
|
||||
|
||||
args.chid = chix;
|
||||
args.ar = chix->ar;
|
||||
(*chix->pAccessRightsFunc) (args);
|
||||
}
|
||||
UNLOCKEVENTS;
|
||||
}
|
||||
piiu = (struct ioc_in_use *)chix->piiu;
|
||||
ellDelete(&piiu->chidlist, &chix->node);
|
||||
assert (piiuCast);
|
||||
chix->piiu = piiuCast;
|
||||
ellAdd(&piiuCast->chidlist, &chix->node);
|
||||
|
||||
/*
|
||||
* Try to reconnect this channel
|
||||
*/
|
||||
ca_static->ca_search_retry = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -1704,7 +1721,7 @@ void caPrintAddrList(ELLLIST *pList)
|
||||
/*
|
||||
* caFetchPortConfig()
|
||||
*/
|
||||
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
|
||||
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort)
|
||||
{
|
||||
long longStatus;
|
||||
long epicsParam;
|
||||
@@ -1712,29 +1729,29 @@ int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
|
||||
|
||||
longStatus = envGetLongConfigParam(pEnv, &epicsParam);
|
||||
if (longStatus!=0) {
|
||||
epicsParam = defaultPort;
|
||||
epicsParam = (long) defaultPort;
|
||||
ca_printf ("EPICS \"%s\" integer fetch failed\n", pEnv->name);
|
||||
ca_printf ("setting \"%s\" = %ld\n", pEnv->name, epicsParam);
|
||||
}
|
||||
|
||||
/*
|
||||
* This must be a server port that will fit in a signed
|
||||
* This must be a server port that will fit in an unsigned
|
||||
* short
|
||||
*/
|
||||
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>SHRT_MAX) {
|
||||
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>USHRT_MAX) {
|
||||
ca_printf ("EPICS \"%s\" out of range\n", pEnv->name);
|
||||
/*
|
||||
* Quit if the port is wrong due CA coding error
|
||||
*/
|
||||
assert (epicsParam != defaultPort);
|
||||
epicsParam = defaultPort;
|
||||
assert (epicsParam != (long) defaultPort);
|
||||
epicsParam = (long) defaultPort;
|
||||
ca_printf ("Setting \"%s\" = %ld\n", pEnv->name, epicsParam);
|
||||
}
|
||||
|
||||
/*
|
||||
* ok to clip to int here because we checked the range
|
||||
*/
|
||||
port = (int) epicsParam;
|
||||
port = (unsigned short) epicsParam;
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* $Id */
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* L O S A L A M O S */
|
||||
@@ -28,6 +29,10 @@
|
||||
/* .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$
|
||||
* Revision 1.47 1995/08/22 00:20:27 jhill
|
||||
* added KLUDGE def of S_db_Pending
|
||||
* */
|
||||
/* */
|
||||
/*_begin */
|
||||
/************************************************************************/
|
||||
@@ -86,6 +91,7 @@ HDRVERSIONID(iocinfh, "$Id$")
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
/*
|
||||
* OS dependent includes
|
||||
@@ -409,9 +415,11 @@ struct ca_static{
|
||||
void (*ca_exception_func)
|
||||
(struct exception_handler_args);
|
||||
void *ca_exception_arg;
|
||||
#if 0
|
||||
void (*ca_connection_func)
|
||||
(struct connection_handler_args);
|
||||
void *ca_connection_arg;
|
||||
#endif
|
||||
int (*ca_printf_func)(const char *pformat, va_list args);
|
||||
void (*ca_fd_register_func)
|
||||
(void *, SOCKET, int);
|
||||
@@ -511,7 +519,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 +529,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 +574,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 +586,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);
|
||||
@@ -603,7 +613,7 @@ ca_time cac_time_sum(ca_time *pTVA, ca_time *pTVB);
|
||||
void caIOBlockFree(evid pIOBlock);
|
||||
void clearChannelResources(unsigned id);
|
||||
void caSetDefaultPrintfHandler ();
|
||||
|
||||
void cacDisconnectChannel(chid chix, int fullDisconnect);
|
||||
/*
|
||||
* !!KLUDGE!!
|
||||
*
|
||||
@@ -613,5 +623,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 */
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#ifndef __IOCMSG__
|
||||
/* $Id$ */
|
||||
/*
|
||||
* History
|
||||
* .01 01xx90 joh removed status field in favor of a independent m_cmmd-
|
||||
@@ -23,6 +24,10 @@
|
||||
* .09 050594 joh New command added for CA V4.3 - repeater fanout register
|
||||
*
|
||||
* .10 050594 joh New command added for CA V4.3 - wakeup the server
|
||||
* $Log$
|
||||
* Revision 1.23 1995/08/23 00:35:17 jhill
|
||||
* added log entries
|
||||
*
|
||||
*/
|
||||
|
||||
#define __IOCMSG__
|
||||
@@ -31,23 +36,29 @@ 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 6
|
||||
#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)
|
||||
#define CA_V46(MAJOR,MINOR) ((MINOR)>=6)
|
||||
#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 )
|
||||
#define CA_V46(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 )
|
||||
#define CA_V46(MAJOR,MINOR) ( 0 )
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -56,7 +67,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
|
||||
* environment variables "EPICS_CA_REPEATER_PORT" and
|
||||
* "EPICS_CA_SERVER_PORT"
|
||||
*/
|
||||
#define CA_PORT_BASE IPPORT_USERRESERVED + 56
|
||||
#define CA_PORT_BASE IPPORT_USERRESERVED + 56U
|
||||
#define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2)
|
||||
#define CA_REPEATER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1)
|
||||
|
||||
@@ -72,7 +83,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 */
|
||||
@@ -101,6 +112,7 @@ typedef float ca_float32_t;
|
||||
#define IOC_ECHO 23 /* CA V4.3 connection verify */
|
||||
#define REPEATER_REGISTER 24 /* registr for repeater fan out */
|
||||
#define IOC_SIGNAL 25 /* knock the server out of select */
|
||||
#define IOC_CLAIM_CIU_FAILED 26 /* unable to create chan resource in server */
|
||||
|
||||
/*
|
||||
* for use with search and not_found (if search fails and
|
||||
@@ -110,15 +122,15 @@ typedef float ca_float32_t;
|
||||
#define DONTREPLY 5
|
||||
|
||||
/* size of object in bytes rounded up to nearest oct word */
|
||||
#define OCT_ROUND(A) ((((unsigned long)A)+7)>>3)
|
||||
#define OCT_ROUND(A) ((((unsigned long)(A))+7)>>3)
|
||||
#define OCT_SIZEOF(A) (OCT_ROUND(sizeof(A)))
|
||||
|
||||
/* size of object in bytes rounded up to nearest long word */
|
||||
#define QUAD_ROUND(A) (((unsigned long)A)+3)>>2)
|
||||
#define QUAD_ROUND(A) (((unsigned long)(A))+3)>>2)
|
||||
#define QUAD_SIZEOF(A) (QUAD_ROUND(sizeof(A)))
|
||||
|
||||
/* size of object in bytes rounded up to nearest short word */
|
||||
#define BI_ROUND(A) ((((unsigned long)A)+1)>>1)
|
||||
#define BI_ROUND(A) ((((unsigned long)(A))+1)>>1)
|
||||
#define BI_SIZEOF(A) (BI_ROUND(sizeof(A)))
|
||||
|
||||
/*
|
||||
@@ -169,4 +181,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,25 +300,26 @@ static char *os_depenhSccsId = "$Id$";
|
||||
# define INVALID_SOCKET (-1)
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# define LOCK
|
||||
# define UNLOCK
|
||||
# define LOCKEVENTS
|
||||
# define UNLOCKEVENTS
|
||||
# define EVENTLOCKTEST (post_msg_active)
|
||||
# define MAXHOSTNAMELEN 75
|
||||
# define IPPORT_USERRESERVED 5000
|
||||
# define IPPORT_USERRESERVED 5000U
|
||||
# define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
# define ENOBUFS WSAENOBUFS
|
||||
# define ECONNRESET WSAECONNRESET
|
||||
# define ETIMEDOUT WSAETIMEDOUT
|
||||
# define EADDRINUSE WSAEADDRINUSE
|
||||
# define ECONNREFUSED WSAECONNREFUSED
|
||||
# define socket_close(S) closesocket(S)
|
||||
# define socket_ioctl(A,B,C) ioctlsocket(A,B,C)
|
||||
# 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 0U
|
||||
LOCAL SOCKET makeSocket(unsigned short port);
|
||||
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize);
|
||||
|
||||
|
||||
/*
|
||||
@@ -93,14 +101,10 @@ 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;
|
||||
unsigned short port;
|
||||
|
||||
port = caFetchPortConfig(
|
||||
&EPICS_CA_REPEATER_PORT,
|
||||
@@ -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 SOCKET makeSocket(unsigned short port)
|
||||
{
|
||||
int status;
|
||||
struct sockaddr_in bd;
|
||||
SOCKET 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));
|
||||
}
|
||||
|
||||
|
||||
127
src/ca/service.c
127
src/ca/service.c
@@ -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;
|
||||
@@ -263,8 +263,6 @@ struct in_addr *pnet_addr
|
||||
&piiu->curMsg.m_available);
|
||||
UNLOCK;
|
||||
if(!monix){
|
||||
ca_signal(ECA_INTERNAL,
|
||||
"bad client write io id from server");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -293,9 +291,8 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
LOCK;
|
||||
ellDelete(&pend_write_list, &monix->node);
|
||||
UNLOCK;
|
||||
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
|
||||
break;
|
||||
|
||||
@@ -314,8 +311,6 @@ struct in_addr *pnet_addr
|
||||
&piiu->curMsg.m_available);
|
||||
UNLOCK;
|
||||
if(!monix){
|
||||
ca_signal(ECA_INTERNAL,
|
||||
"bad client read notify io id from server");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -366,8 +361,8 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
LOCK;
|
||||
ellDelete(&pend_read_list, &monix->node);
|
||||
UNLOCK;
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -385,8 +380,6 @@ struct in_addr *pnet_addr
|
||||
&piiu->curMsg.m_available);
|
||||
UNLOCK;
|
||||
if(!monix){
|
||||
ca_signal(ECA_INTERNAL,
|
||||
"bad client event id from server");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -398,8 +391,8 @@ struct in_addr *pnet_addr
|
||||
if (!piiu->curMsg.m_postsize) {
|
||||
LOCK;
|
||||
ellDelete(&monix->chan->eventq, &monix->node);
|
||||
UNLOCK;
|
||||
caIOBlockFree(monix);
|
||||
UNLOCK;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -466,8 +459,6 @@ struct in_addr *pnet_addr
|
||||
&piiu->curMsg.m_available);
|
||||
UNLOCK;
|
||||
if(!pIOBlock){
|
||||
ca_signal(ECA_INTERNAL,
|
||||
"bad client read io id from server");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -509,8 +500,8 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
LOCK;
|
||||
ellDelete(&pend_read_list, &pIOBlock->node);
|
||||
UNLOCK;
|
||||
caIOBlockFree(pIOBlock);
|
||||
UNLOCK;
|
||||
break;
|
||||
}
|
||||
case IOC_SEARCH:
|
||||
@@ -548,6 +539,7 @@ struct in_addr *pnet_addr
|
||||
|
||||
case IOC_ERROR:
|
||||
{
|
||||
ELLLIST *pList = NULL;
|
||||
evid monix;
|
||||
char nameBuf[64];
|
||||
char context[255];
|
||||
@@ -584,32 +576,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 +609,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 +629,12 @@ struct in_addr *pnet_addr
|
||||
}
|
||||
|
||||
if (monix) {
|
||||
if (pList) {
|
||||
ellDelete(pList, &monix->node);
|
||||
}
|
||||
caIOBlockFree(monix);
|
||||
}
|
||||
|
||||
LOCK;
|
||||
args.chid = bucketLookupItemUnsignedId
|
||||
(pSlowBucket, &piiu->curMsg.m_cid);
|
||||
UNLOCK;
|
||||
@@ -710,6 +701,31 @@ struct in_addr *pnet_addr
|
||||
reconnect_channel(piiu, chan);
|
||||
break;
|
||||
}
|
||||
case IOC_CLAIM_CIU_FAILED:
|
||||
{
|
||||
chid chan;
|
||||
|
||||
LOCK;
|
||||
chan = bucketLookupItemUnsignedId(
|
||||
pSlowBucket, &piiu->curMsg.m_cid);
|
||||
UNLOCK;
|
||||
if(!chan){
|
||||
/*
|
||||
* end up here if they delete the channel
|
||||
* prior to this response
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* need to move the channel back to the cast IIU
|
||||
* (so we will be able to reconnect)
|
||||
*/
|
||||
LOCK;
|
||||
cacDisconnectChannel(chan, FALSE);
|
||||
UNLOCK;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ca_printf("CAC: post_msg(): Corrupt cmd in msg %x\n",
|
||||
piiu->curMsg.m_cmmd);
|
||||
@@ -728,16 +744,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 +810,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;
|
||||
@@ -801,7 +842,7 @@ struct in_addr *pnet_addr
|
||||
case ECA_DISCONN:
|
||||
/*
|
||||
* This indicates that the connection is tagged
|
||||
* is tagged for shutdown and we are waiting for
|
||||
* for shutdown and we are waiting for
|
||||
* it to go away. Search replies are ignored
|
||||
* in the interim.
|
||||
*/
|
||||
@@ -818,22 +859,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 +872,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);
|
||||
}
|
||||
@@ -963,9 +993,6 @@ chid chan
|
||||
/* decrement the outstanding IO count */
|
||||
CLRPENDRECV(TRUE);
|
||||
}
|
||||
|
||||
|
||||
UNLOCK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.16 1995/08/22 00:27:55 jhill
|
||||
* added cvs style mod log
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
* 1) Need to fix if the OP is on a FD that
|
||||
@@ -97,7 +101,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 +134,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 +175,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 +196,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 +213,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 +250,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 +265,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 +298,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 +309,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 +331,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 +357,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 +422,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,
|
||||
@@ -505,7 +523,7 @@ LOCAL void io_complete(struct event_handler_args args)
|
||||
* Update the user's variable
|
||||
* (if its a get)
|
||||
*/
|
||||
if(pcasgop->pValue){
|
||||
if(pcasgop->pValue && args.dbr){
|
||||
size = dbr_size_n(args.type, args.count);
|
||||
memcpy(pcasgop->pValue, args.dbr, size);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*
|
||||
* 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)
|
||||
@@ -27,6 +26,8 @@
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Lawrence Berkley National Laboratory
|
||||
*
|
||||
* Modification 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]);
|
||||
@@ -57,8 +58,7 @@ void cac_gettimeval(struct timeval *pt)
|
||||
SYSTEMTIME st;
|
||||
|
||||
GetSystemTime(&st);
|
||||
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 +
|
||||
(long)st.wHour*360;
|
||||
pt->tv_sec = time(NULL);
|
||||
pt->tv_usec = st.wMilliseconds*1000;
|
||||
}
|
||||
|
||||
@@ -290,11 +290,8 @@ int local_addr (SOCKET s, struct sockaddr_in *plcladdr)
|
||||
*/
|
||||
void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port)
|
||||
{
|
||||
struct sockaddr_in localAddr;
|
||||
struct sockaddr_in InetAddr;
|
||||
struct in_addr bcast_addr;
|
||||
caAddrNode *pNode;
|
||||
int status;
|
||||
|
||||
pNode = (caAddrNode *) calloc(1,sizeof(*pNode));
|
||||
if(!pNode){
|
||||
@@ -352,6 +349,13 @@ static int get_subnet_mask ( char SubNetMaskStr[256])
|
||||
return RegTcpParams (localadr, SubNetMaskStr);
|
||||
}
|
||||
|
||||
/* For NT 3.51, enumerates network interfaces returns the ip address */
|
||||
/* and subnet mask for the LAST interface found. This needs to be changed */
|
||||
/* to work in conjuction with caDiscoverInterfaces to add all the */
|
||||
/* add all the interfaces to the elist. Also could be more efficient in
|
||||
calling */
|
||||
/* RegKeyOpen */
|
||||
|
||||
static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
|
||||
{
|
||||
#define MAX_VALUE_NAME 128
|
||||
@@ -360,37 +364,65 @@ static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
|
||||
DWORD cbDataLen;
|
||||
CHAR cbData[256];
|
||||
DWORD dwType;
|
||||
int status;
|
||||
int status, i, card_cnt;
|
||||
char *pNetCard[16], *pData;
|
||||
|
||||
static char IpAddr[256], SubNetMask[256];
|
||||
|
||||
cbDataLen = sizeof(cbData);
|
||||
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\1");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
|
||||
|
||||
/****
|
||||
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows
|
||||
NT\\CurrentVersion\\NetworkCards\\1");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType,
|
||||
cbData, &cbDataLen);
|
||||
if (status) {
|
||||
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\01");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
|
||||
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows
|
||||
NT\\CurrentVersion\\NetworkCards\\01");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType,
|
||||
cbData, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
****/
|
||||
|
||||
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
|
||||
strcat(RegPath,cbData);
|
||||
strcat(RegPath,"\\Parameters\\Tcpip");
|
||||
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage");
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "Route", &dwType, cbData,
|
||||
&cbDataLen);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
i=0; card_cnt = 0; pData = cbData; /* enumerate network interfaces */
|
||||
|
||||
while( i < 16 && (pNetCard[i]=strtok(pData,"\"")) ) {
|
||||
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
|
||||
strcat(RegPath,pNetCard[i]);
|
||||
strcat(RegPath,"\\Parameters\\Tcpip");
|
||||
|
||||
cbDataLen = sizeof(IpAddr);
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType,
|
||||
IpAddr, &cbDataLen);
|
||||
if (status == 0) {
|
||||
cbDataLen = sizeof(SubNetMask);
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask",
|
||||
&dwType, SubNetMask, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
card_cnt++;
|
||||
}
|
||||
pData += strlen(pNetCard[i])+3;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (card_cnt == 0)
|
||||
return 1;
|
||||
|
||||
cbDataLen = sizeof(IpAddr);
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType, IpAddr, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
strcpy(IpAddrStr,IpAddr);
|
||||
|
||||
cbDataLen = sizeof(SubNetMask);
|
||||
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask", &dwType, SubNetMask, &cbDataLen);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
strcpy(SubNetMaskStr,SubNetMask);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -417,7 +449,8 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
|
||||
}
|
||||
|
||||
|
||||
retCode = RegQueryValueEx (hKey, // Key handle returned from RegOpenKeyEx.
|
||||
retCode = RegQueryValueEx (hKey, // Key handle returned from
|
||||
RegOpenKeyEx.
|
||||
lpzValueName, // Name of value.
|
||||
NULL, // Reserved, dword = NULL.
|
||||
lpdwType, // Type of data.
|
||||
@@ -434,7 +467,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 +478,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:
|
||||
@@ -459,11 +494,15 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
#if _DEBUG
|
||||
fprintf(stderr, "Thread attached to ca.dll R12\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
#if _DEBUG
|
||||
fprintf(stderr, "Thread detached from ca.dll R12\n");
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -473,3 +512,5 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -90,10 +90,12 @@
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbRecDes.h>
|
||||
#include <dbRecType.h>
|
||||
#include <dbEvent.h>
|
||||
#include <db_field_log.h>
|
||||
#include <errMdef.h>
|
||||
#include <recSup.h>
|
||||
#include <special.h>
|
||||
#include <asLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
extern long lset_stack_not_empty;
|
||||
@@ -297,8 +299,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 +377,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 +681,7 @@ long dbFastLinkPut(
|
||||
}
|
||||
}
|
||||
else if (special == SPC_AS) {
|
||||
asChangeGroup(&pdest->asp, pdest->asg);
|
||||
asChangeGroup((ASMEMBERPVT *)&pdest->asp, pdest->asg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -622,14 +622,16 @@ int db_post_single_event(struct event_block *pevent)
|
||||
*
|
||||
*/
|
||||
int db_post_events(
|
||||
struct dbCommon *precord,
|
||||
union native_value *pvalue,
|
||||
unsigned int select
|
||||
void *prec,
|
||||
void *pval,
|
||||
unsigned int select
|
||||
)
|
||||
{
|
||||
struct event_block *event;
|
||||
struct event_que *ev_que;
|
||||
unsigned int putix;
|
||||
struct dbCommon *precord = (struct dbCommon *)prec;
|
||||
union native_value *pvalue = (union native_value *)pval;
|
||||
struct event_block *event;
|
||||
struct event_que *ev_que;
|
||||
unsigned int putix;
|
||||
|
||||
if (precord->mlis.count == 0) return OK; /* no monitors set */
|
||||
|
||||
|
||||
@@ -83,10 +83,12 @@
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbRecDes.h>
|
||||
#include <dbRecType.h>
|
||||
#include <dbEvent.h>
|
||||
#include <db_field_log.h>
|
||||
#include <errMdef.h>
|
||||
#include <recSup.h>
|
||||
#include <special.h>
|
||||
#include <asLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
|
||||
@@ -186,6 +188,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*/
|
||||
@@ -2782,7 +2785,6 @@ void *pflin
|
||||
long (*pconvert_routine)();
|
||||
struct dbCommon *pcommon;
|
||||
long status;
|
||||
long *perr_status=NULL;
|
||||
|
||||
|
||||
prset=GET_PRSET(pdbBase->precSup,paddr->record_type);
|
||||
@@ -2801,16 +2803,18 @@ void *pflin
|
||||
}
|
||||
*((unsigned short *)pbuffer)++ = pcommon->acks;
|
||||
*((unsigned short *)pbuffer)++ = pcommon->ackt;
|
||||
*perr_status = 0;
|
||||
}
|
||||
if( (*options) & DBR_UNITS ) {
|
||||
if( prset && prset->get_units ){
|
||||
(*prset->get_units)(paddr,pbuffer);
|
||||
char * pchr = (char *)pbuffer;
|
||||
|
||||
(*prset->get_units)(paddr,pchr);
|
||||
pchr[DB_UNITS_SIZE-1] = '\0';
|
||||
} else {
|
||||
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 +2827,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) {
|
||||
@@ -2852,7 +2856,6 @@ GET_DATA:
|
||||
|
||||
sprintf(message,"dbGet - database request type is %d",dbrType);
|
||||
recGblDbaddrError(S_db_badDbrtype,paddr,message);
|
||||
if(perr_status) *perr_status = S_db_badDbrtype;
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
|
||||
@@ -2867,7 +2870,6 @@ GET_DATA:
|
||||
|
||||
sprintf(message,"dbGet - database request type is %d",dbrType);
|
||||
recGblDbaddrError(S_db_badDbrtype,paddr,message);
|
||||
if(perr_status) *perr_status = S_db_badDbrtype;
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
/* convert database field to buffer type and place it in the buffer */
|
||||
@@ -2883,7 +2885,6 @@ GET_DATA:
|
||||
status=(*pconvert_routine)(paddr,pbuffer,*nRequest,
|
||||
no_elements,offset);
|
||||
}
|
||||
if(perr_status) *perr_status = status;
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -2961,7 +2962,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 +2987,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 +3000,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 +3026,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 +3039,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 +3067,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 +3082,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 +3228,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 +3298,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 +5680,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 +5835,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);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <ellLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <dbAccess.h>
|
||||
@@ -66,7 +67,6 @@
|
||||
#include <dbStaticLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
extern volatile int interruptAccept;
|
||||
|
||||
/* SCAN ONCE */
|
||||
#define ONCE_QUEUE_SIZE 256
|
||||
@@ -146,7 +146,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 +156,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 +381,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 +603,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 +615,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 +629,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 +642,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 +708,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"};
|
||||
@@ -430,7 +439,6 @@ DBBASE *pdbbase;
|
||||
ELLLIST *preclist;
|
||||
int recType;
|
||||
if (!pdbbase || !ppvd || !precType) return;
|
||||
dbPvdFreeMem(pdbbase);
|
||||
/* loop thru the recLocs - removing lists then recLoc only */
|
||||
for (recType = 0; recType < precType->number; recType++) {
|
||||
if (!(precLoc = GET_PRECLOC(precHeader, recType))) continue;
|
||||
@@ -452,6 +460,7 @@ DBBASE *pdbbase;
|
||||
free((void *) precLoc);
|
||||
}
|
||||
/* free the rest of the memory allocations */
|
||||
dbPvdFreeMem(pdbbase);
|
||||
if (pdbbase->pchoiceCvt)
|
||||
free((void *) pdbbase->pchoiceCvt);
|
||||
if (pdbbase->pchoiceDev)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -4291,7 +4316,8 @@ RECNODE *precnode;
|
||||
ppvdlist=ppvd[hashInd];
|
||||
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
|
||||
while(ppvdNode) {
|
||||
if(strcmp(name,(char *)ppvdNode->precnode->precord) == 0) {
|
||||
if(ppvdNode->precnode && ppvdNode->precnode->precord
|
||||
&& strcmp(name,(char *)ppvdNode->precnode->precord) == 0) {
|
||||
ellDelete(ppvdlist, (ELLNODE*)ppvdNode);
|
||||
free((void *)ppvdNode);
|
||||
return;
|
||||
@@ -4315,7 +4341,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 +4357,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 +4371,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);
|
||||
|
||||
173
src/db/dbTest.c
173
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
|
||||
@@ -99,6 +96,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <timexLib.h>
|
||||
|
||||
#include <ellLib.h>
|
||||
#include <fast_lock.h>
|
||||
@@ -115,6 +113,7 @@
|
||||
#include <special.h>
|
||||
#include <dbRecDes.h>
|
||||
#include <dbStaticLib.h>
|
||||
#include <dbEvent.h>
|
||||
#include <ellLib.h>
|
||||
#include <callback.h>
|
||||
|
||||
@@ -173,18 +172,6 @@ long dba(char*pname)
|
||||
if(status) return(1); else return(0);
|
||||
}
|
||||
|
||||
/*Following definition is from dbEvent.c*/
|
||||
struct event_block{
|
||||
ELLNODE node;
|
||||
struct dbAddr *paddr;
|
||||
void (*user_sub)();
|
||||
void *user_arg;
|
||||
struct event_que *ev_que;
|
||||
unsigned char select;
|
||||
char valque;
|
||||
unsigned short npend; /* n times this event is on the que */
|
||||
};
|
||||
|
||||
long dbel(char*pname)
|
||||
{
|
||||
struct dbAddr addr;
|
||||
@@ -203,7 +190,7 @@ long dbel(char*pname)
|
||||
return(0);
|
||||
}
|
||||
while(peb) {
|
||||
pfldDes = peb->paddr->pfldDes;
|
||||
pfldDes = ((struct dbAddr *)peb->paddr)->pfldDes;
|
||||
printf("%4.4s",&pfldDes->fldname[0]);
|
||||
if(peb->select&&DBE_VALUE) printf(" VALUE");
|
||||
if(peb->select&&DBE_LOG) printf(" LOG");
|
||||
@@ -292,8 +279,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 +684,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 +846,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 +856,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 +867,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 +878,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 +889,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 +900,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 +911,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 +922,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 +933,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 +945,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 +957,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 +976,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 +991,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 +1006,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 +1020,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 +1034,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 +1048,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 +1062,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 +1076,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 +1090,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 +1104,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:
|
||||
@@ -1814,9 +1746,62 @@ char *record_name;
|
||||
* Time the record
|
||||
*/
|
||||
dbScanLock(precord);
|
||||
timexN(timing_routine, precord);
|
||||
timexN((FUNCPTR)timing_routine, (int)precord,
|
||||
0,0,0,0,0,0,0);
|
||||
dbScanUnlock(precord);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -129,6 +129,9 @@
|
||||
#define MAX_STRING_SIZE 40
|
||||
#endif
|
||||
|
||||
#ifndef MAX_UNITS_SIZE
|
||||
#define MAX_UNITS_SIZE 8
|
||||
#endif
|
||||
|
||||
/* VALUES WITH STATUS STRUCTURES */
|
||||
|
||||
@@ -269,7 +272,7 @@ struct dbr_time_double{
|
||||
struct dbr_gr_int{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
short upper_disp_limit; /* upper limit of graph */
|
||||
short lower_disp_limit; /* lower limit of graph */
|
||||
short upper_alarm_limit;
|
||||
@@ -281,7 +284,7 @@ struct dbr_gr_int{
|
||||
struct dbr_gr_short{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
short upper_disp_limit; /* upper limit of graph */
|
||||
short lower_disp_limit; /* lower limit of graph */
|
||||
short upper_alarm_limit;
|
||||
@@ -297,7 +300,7 @@ struct dbr_gr_float{
|
||||
short severity; /* severity of alarm */
|
||||
short precision; /* number of decimal places */
|
||||
short RISC_pad0; /* RISC alignment */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
float upper_disp_limit; /* upper limit of graph */
|
||||
float lower_disp_limit; /* lower limit of graph */
|
||||
float upper_alarm_limit;
|
||||
@@ -320,7 +323,7 @@ struct dbr_gr_enum{
|
||||
struct dbr_gr_char{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
unsigned char upper_disp_limit; /* upper limit of graph */
|
||||
unsigned char lower_disp_limit; /* lower limit of graph */
|
||||
unsigned char upper_alarm_limit;
|
||||
@@ -335,7 +338,7 @@ struct dbr_gr_char{
|
||||
struct dbr_gr_long{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
long upper_disp_limit; /* upper limit of graph */
|
||||
long lower_disp_limit; /* lower limit of graph */
|
||||
long upper_alarm_limit;
|
||||
@@ -351,7 +354,7 @@ struct dbr_gr_double{
|
||||
short severity; /* severity of alarm */
|
||||
short precision; /* number of decimal places */
|
||||
short RISC_pad0; /* RISC alignment */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
double upper_disp_limit; /* upper limit of graph */
|
||||
double lower_disp_limit; /* lower limit of graph */
|
||||
double upper_alarm_limit;
|
||||
@@ -370,7 +373,7 @@ struct dbr_gr_double{
|
||||
struct dbr_ctrl_int{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
short upper_disp_limit; /* upper limit of graph */
|
||||
short lower_disp_limit; /* lower limit of graph */
|
||||
short upper_alarm_limit;
|
||||
@@ -384,7 +387,7 @@ struct dbr_ctrl_int{
|
||||
struct dbr_ctrl_short{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
short upper_disp_limit; /* upper limit of graph */
|
||||
short lower_disp_limit; /* lower limit of graph */
|
||||
short upper_alarm_limit;
|
||||
@@ -402,7 +405,7 @@ struct dbr_ctrl_float{
|
||||
short severity; /* severity of alarm */
|
||||
short precision; /* number of decimal places */
|
||||
short RISC_pad; /* RISC alignment */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
float upper_disp_limit; /* upper limit of graph */
|
||||
float lower_disp_limit; /* lower limit of graph */
|
||||
float upper_alarm_limit;
|
||||
@@ -427,7 +430,7 @@ struct dbr_ctrl_enum{
|
||||
struct dbr_ctrl_char{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
unsigned char upper_disp_limit; /* upper limit of graph */
|
||||
unsigned char lower_disp_limit; /* lower limit of graph */
|
||||
unsigned char upper_alarm_limit;
|
||||
@@ -444,7 +447,7 @@ struct dbr_ctrl_char{
|
||||
struct dbr_ctrl_long{
|
||||
short status; /* status of value */
|
||||
short severity; /* severity of alarm */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
long upper_disp_limit; /* upper limit of graph */
|
||||
long lower_disp_limit; /* lower limit of graph */
|
||||
long upper_alarm_limit;
|
||||
@@ -462,7 +465,7 @@ struct dbr_ctrl_double{
|
||||
short severity; /* severity of alarm */
|
||||
short precision; /* number of decimal places */
|
||||
short RISC_pad0; /* RISC alignment */
|
||||
char units[8]; /* units of value */
|
||||
char units[MAX_UNITS_SIZE]; /* units of value */
|
||||
double upper_disp_limit; /* upper limit of graph */
|
||||
double lower_disp_limit; /* lower limit of graph */
|
||||
double upper_alarm_limit;
|
||||
@@ -1017,7 +1020,8 @@ void *pfl;
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1051,7 +1055,8 @@ void *pfl;
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1083,7 +1088,8 @@ void *pfl;
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1114,7 +1120,8 @@ void *pfl;
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1148,7 +1155,8 @@ void *pfl;
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1182,7 +1190,8 @@ void *pfl;
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1219,7 +1228,8 @@ void *pfl;
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1286,7 +1296,8 @@ void *pfl;
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1320,7 +1331,8 @@ void *pfl;
|
||||
status = dbGetField(paddr,DBR_LONG,&new,&options,&nRequest,pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
@@ -1357,7 +1369,8 @@ void *pfl;
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision;
|
||||
strncpy(pold->units,new.units,8);
|
||||
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
|
||||
@@ -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);
|
||||
|
||||
540
src/db/drvTS.c
540
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <dbBase.h>
|
||||
#include <dbRecType.h>
|
||||
#include <dbRecDes.h>
|
||||
#include <dbEvent.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <devSup.h>
|
||||
@@ -328,10 +329,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 +343,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) {
|
||||
|
||||
986
src/dbtools/BSlib.c
Normal file
986
src/dbtools/BSlib.c
Normal file
@@ -0,0 +1,986 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "BSlib.h"
|
||||
|
||||
#ifdef linux
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <in.h>
|
||||
#include <ioctl.h>
|
||||
#include <inetLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <selectLib.h>
|
||||
#else
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef SOLARIS
|
||||
#define BSD_COMP
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
|
||||
|
||||
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* 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)
|
||||
{
|
||||
#ifdef SOLARIS
|
||||
while(waitpid(-1,(int*)NULL,WNOHANG)>0);
|
||||
#else
|
||||
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
|
||||
#endif
|
||||
|
||||
#if defined linux || defined SOLARIS
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* Clear the signals for a process */
|
||||
/* ------------------------------- */
|
||||
int BSserverClearSignals()
|
||||
{
|
||||
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 BSmakeServer(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 */
|
||||
#if defined linux || defined SOLARIS
|
||||
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 */
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
/* open a bulk data socket to a server given the server IP address */
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
BS* BSipOpen(char* address, int Port)
|
||||
{
|
||||
struct hostent* pHostent;
|
||||
unsigned long addr;
|
||||
BSDATA info;
|
||||
struct sockaddr_in* tsin;
|
||||
|
||||
tsin=(struct sockaddr_in*)&(info.sin);
|
||||
|
||||
#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;
|
||||
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
tsin->sin_port=htons(Port);
|
||||
tsin->sin_family=AF_INET;
|
||||
memcpy((char*)&(tsin->sin_addr),(char*)&addr,sizeof(addr));
|
||||
|
||||
return BSipOpenData(&info);
|
||||
}
|
||||
|
||||
BS* BSipOpenData(BSDATA* info)
|
||||
{
|
||||
struct sockaddr_in tsin;
|
||||
int osoc;
|
||||
BS* bdt;
|
||||
|
||||
tsin.sin_port=0;
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((osoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
|
||||
{
|
||||
perror("BSipOpen: create socket failed");
|
||||
return (BS*)NULL;
|
||||
}
|
||||
|
||||
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BSipOpen: local address bind failed");
|
||||
return (BS*)NULL;
|
||||
}
|
||||
|
||||
if(connect(osoc,(struct sockaddr*)&(info->sin),sizeof(info->sin))<0)
|
||||
{
|
||||
perror("BSipOpen: connect failed");
|
||||
close(osoc);
|
||||
return (BS*)NULL;
|
||||
}
|
||||
|
||||
bdt=(BS*)malloc(sizeof(BS));
|
||||
bdt->soc=osoc;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BSidle;
|
||||
|
||||
#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 BSwrite(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(FD_SETSIZE,NULL,&fds,NULL,&to) != 1)
|
||||
{
|
||||
printf("BSwrite: timeout waiting to write data\n");
|
||||
return -1;
|
||||
}
|
||||
/* send block of data */
|
||||
if((rc=send(soc,(char*)&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno == EINTR)
|
||||
rc = 0;
|
||||
else
|
||||
perror("BSwrite: Send to remote failed");
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* send a message header down a BS socket */
|
||||
/* --------------------------------------- */
|
||||
int BSsendHeader(BS* bdt,unsigned short verb,int size)
|
||||
{
|
||||
BSmsgHead buf;
|
||||
|
||||
if(bdt->state!=BSidle)
|
||||
{
|
||||
fprintf(stderr,"BSsendHeader: Interface not idle\n");
|
||||
bdt->state=BSbad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf.verb=htons(verb);
|
||||
buf.size=htonl((unsigned long)size);
|
||||
|
||||
if(BSwrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BSsendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
if(BSwrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BSsendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't wait for response if data must go out */
|
||||
if(size)
|
||||
{
|
||||
bdt->remaining_send=size;
|
||||
bdt->state=BSsData;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------- */
|
||||
/* send a message data chunk down a BS socket */
|
||||
/* ------------------------------------------- */
|
||||
int BSsendData(BS* bdt,void* buffer,int size)
|
||||
{
|
||||
int len;
|
||||
int remaining;
|
||||
int rc;
|
||||
|
||||
if(bdt->state!=BSsData)
|
||||
{
|
||||
fprintf(stderr,"BSsendData: Interface not in send data mode\n");
|
||||
bdt->state=BSbad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
remaining=bdt->remaining_send-size;
|
||||
|
||||
if(remaining<0)
|
||||
{
|
||||
fprintf(stderr,"WARNING -- BSsendData: To much data to send\n");
|
||||
len=bdt->remaining_send;
|
||||
}
|
||||
else
|
||||
len=size;
|
||||
|
||||
if (BSwrite(bdt->soc, buffer, len) < 0)
|
||||
return -1;
|
||||
|
||||
bdt->remaining_send-=len;
|
||||
|
||||
if(bdt->remaining_send<0)
|
||||
{
|
||||
fprintf(stderr,"BSsendData: To much data Sent\n");
|
||||
bdt->remaining_send=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_send==0)
|
||||
bdt->state=BSidle;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int BSflushOutput(BS* bdt)
|
||||
{
|
||||
#ifdef vxWorks
|
||||
ioctl(bdt->soc, FIOWFLUSH, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* Read exactly size bytes from remote */
|
||||
/* ------------------------------------- */
|
||||
int BSread(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("BSread: timeout waiting for data\n");
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
if((rc=recv(soc,(char*)&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno==EINTR)
|
||||
{
|
||||
printf("BSread: EINTR");
|
||||
rc=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("BSread: 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 BSreceiveHeader(BS* bdt,int* verb,int* size)
|
||||
{
|
||||
BSmsgHead buf;
|
||||
|
||||
/* can only receive header when in the idle state */
|
||||
if (bdt->state == BSeof)
|
||||
return -1;
|
||||
|
||||
if(bdt->state != BSidle)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveHeader: Interface not idle\n");
|
||||
bdt->state=BSbad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSread(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(BSread(bdt->soc,&buf.size,sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy message data to user */
|
||||
*verb=ntohs(buf.verb);
|
||||
*size=ntohl(buf.size);
|
||||
|
||||
if(*size)
|
||||
bdt->state=BSrData;
|
||||
|
||||
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 BSreceiveData(BS* bdt,void* buffer,int size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* can only receive data when in the receive data state */
|
||||
switch(bdt->state)
|
||||
{
|
||||
case BSrData: break;
|
||||
case BSidle: return 0;
|
||||
default:
|
||||
fprintf(stderr,"BSreceiveData: bad receive state\n");
|
||||
bdt->state=BSbad;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bdt->remaining_recv < size)
|
||||
size = bdt->remaining_recv;
|
||||
|
||||
if(BSread(bdt->soc,buffer,size)<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveData: Read failed\n");
|
||||
bdt->state = BSeof;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bdt->remaining_recv-=size;
|
||||
|
||||
if(bdt->remaining_recv<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveData: To much data received\n");
|
||||
bdt->remaining_recv=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_recv==0)
|
||||
bdt->state=BSidle;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* -------------------- */
|
||||
/* close the connection */
|
||||
/* -------------------- */
|
||||
int BSclose(BS* bdt)
|
||||
{
|
||||
int verb,size,done;
|
||||
|
||||
/* send a close message out */
|
||||
if(BSsendHeader(bdt,BS_Close,0)<0)
|
||||
{
|
||||
fprintf(stderr,"BSclose: Cannot send close message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
done=0;
|
||||
|
||||
do
|
||||
{
|
||||
/* check response */
|
||||
if(BSreceiveHeader(bdt,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"BSclose: Close message response error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case BS_Ok:
|
||||
done=1;
|
||||
break;
|
||||
case BS_Error:
|
||||
fprintf(stderr,"BSclose: Close rejected\n");
|
||||
return -1;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
while(done==0);
|
||||
|
||||
BSfreeBS(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for UDP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BSopenListenerUDP(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,BS_UDP))<0)
|
||||
{
|
||||
perror("BSopenListenerUDP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BSopenListenerUDP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for TCP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BSopenListenerTCP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
memset ((void *)&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,BS_TCP))<0)
|
||||
{
|
||||
perror("BSopenListenerTCP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BSopenListenerTCP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen(nsoc,5);
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* make BS from a socket - simple */
|
||||
/* ------------------------------- */
|
||||
BS* BSmakeBS(int soc)
|
||||
{
|
||||
BS* bdt;
|
||||
bdt=(BS*)malloc(sizeof(BS));
|
||||
bdt->soc=soc;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BSidle;
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* --------------------------- */
|
||||
/* free a BS and close socket */
|
||||
/* --------------------------- */
|
||||
int BSfreeBS(BS* bdt)
|
||||
{
|
||||
close(bdt->soc);
|
||||
free(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Next three function adjust the fields of the BSDATA structure.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
int BSgetAddressPort(BSDATA* info, char* ip_addr, int* dest_port)
|
||||
{
|
||||
char* name;
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
|
||||
|
||||
*dest_port=sin->sin_port;
|
||||
name=inet_ntoa(sin->sin_addr);
|
||||
strcpy(ip_addr,name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSsetAddressPort(BSDATA* info, char* ip_addr, int dest_port)
|
||||
{
|
||||
BSsetPort(info, dest_port);
|
||||
return BSsetAddress(info, ip_addr);
|
||||
}
|
||||
|
||||
int BSsetPort(BSDATA* info, int dest_port)
|
||||
{
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
|
||||
sin->sin_family=AF_INET;
|
||||
sin->sin_port=htons(dest_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSsetAddress(BSDATA* info, char* ip_addr)
|
||||
{
|
||||
struct hostent *pHostent;
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
|
||||
unsigned long addr;
|
||||
|
||||
#ifndef vxWorks
|
||||
/* Deal with the name -vs- IP number issue. */
|
||||
if (isdigit(ip_addr[0]))
|
||||
{
|
||||
#endif
|
||||
if((addr=inet_addr(ip_addr))==-1) return -1;
|
||||
#ifndef vxWorks
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pHostent=gethostbyname(ip_addr))==NULL) return -1;
|
||||
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
sin->sin_family=AF_INET;
|
||||
memcpy((char*)&(sin->sin_addr),(char*)&addr,sizeof(addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/*
|
||||
All this function does is send a broadcast message and return the
|
||||
addressing info to the caller of a responder to the broadcast.
|
||||
|
||||
arguments:
|
||||
soc - broadcast socket to use for sending data
|
||||
trys - number of times to send if no response
|
||||
o_info - outgoing BSDATA, address/port info
|
||||
i_info - incoming BSDATA, address/port where response came from
|
||||
omsg/osize - outgoing message and size
|
||||
imsg/isize - incoming message and buffer size
|
||||
|
||||
Returns the number of bytes read.
|
||||
*/
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
|
||||
void* omsg,int osize,void* imsg,int isize)
|
||||
{
|
||||
int i;
|
||||
int rc=0;
|
||||
|
||||
for(i=0;rc==0 && i<trys;i++)
|
||||
{
|
||||
/* send out the message */
|
||||
rc=BSwriteUDP(soc,o_info,omsg,osize);
|
||||
if(rc<0) return rc;
|
||||
|
||||
/* wait for a response */
|
||||
rc=BSreadUDP(soc,i_info,1,imsg,isize);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int BSbroadcast(int soc,BSDATA* o_info, void* omsg,int osize)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* send out the message */
|
||||
rc=BSwriteUDP(soc,o_info,omsg,osize);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*
|
||||
This function waits for a message and sends out an ACK when it gets one.
|
||||
addressing info to the caller of a responder to the broadcast.
|
||||
|
||||
Lots of arguments:
|
||||
|
||||
soc - The socket to send the message down.
|
||||
info - The socket information telling where the data read came from
|
||||
(returned to the user).
|
||||
tout - Timeout for read in seconds. 0=no wait, -1=wait forever.
|
||||
buf - Buffer to populate with read data.
|
||||
size - Size of the buf.
|
||||
|
||||
returns the length the read message, 0 is timeout, -1 is error
|
||||
*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size)
|
||||
{
|
||||
int mlen,rc;
|
||||
fd_set fds;
|
||||
struct timeval to;
|
||||
int error=0;
|
||||
|
||||
do
|
||||
{
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc, &fds);
|
||||
|
||||
if(tout==-1)
|
||||
rc=select(FD_SETSIZE,&fds,NULL,NULL,NULL);
|
||||
else
|
||||
{
|
||||
to.tv_sec=tout;
|
||||
to.tv_usec=0;
|
||||
rc=select(FD_SETSIZE,&fds,NULL,NULL,&to);
|
||||
}
|
||||
|
||||
switch(rc)
|
||||
{
|
||||
case -1: /* bad */
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR: break;
|
||||
default: error=-1; break;
|
||||
}
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
break;
|
||||
default: /* data ready */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(rc<0 && error==0);
|
||||
|
||||
error=0;
|
||||
|
||||
if(rc>0)
|
||||
{
|
||||
error=0;
|
||||
do
|
||||
{
|
||||
info->len=sizeof(info->sin);
|
||||
mlen=recvfrom(soc,(char*)buf,size,0, &info->sin,&info->len);
|
||||
|
||||
if(mlen<0)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR: break;
|
||||
default: error=-1; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(mlen<0 && error==0);
|
||||
|
||||
if(mlen<0)
|
||||
rc=-1;
|
||||
else
|
||||
rc=mlen;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Write a chuck of data to a UDP socket at an internet address
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSwriteDataUDP(int soc,int dest_port,char* ip_addr,void* buf,int size)
|
||||
{
|
||||
BSDATA data;
|
||||
|
||||
BSsetAddress(&data,ip_addr);
|
||||
BSsetPort(&data,dest_port);
|
||||
|
||||
return BSwriteUDP(soc,&data,buf,size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Write a chunk of data to a UDP socket using BSDATA.
|
||||
Arguments:
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize)
|
||||
{
|
||||
int mlen;
|
||||
|
||||
mlen=sendto(soc,(char*)obuf,osize,0,&info->sin,sizeof(info->sin));
|
||||
|
||||
return mlen;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Write/Read a chuck of data to a UDP socket using BSDATA.
|
||||
Arguments:
|
||||
soc - socket to send message down and read from
|
||||
info - address/port to send message to
|
||||
obuf/osize - outgoing message and size of it.
|
||||
ibuf/isize - incoming message and size of the buffer.
|
||||
|
||||
Returns the number of bytes read, -1 for error.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize)
|
||||
{
|
||||
int done,i,mlen,flen;
|
||||
struct sockaddr fromsin;
|
||||
fd_set fds;
|
||||
struct timeval tout;
|
||||
|
||||
done=0;
|
||||
mlen=0;
|
||||
|
||||
for(i=0;i<BS_RETRY_COUNT && done==0;i++)
|
||||
{
|
||||
mlen=sendto(soc,(char*)obuf,osize,0,&(info->sin),sizeof(info->sin));
|
||||
if(mlen<0)
|
||||
{
|
||||
printf("send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tout.tv_sec=0;
|
||||
tout.tv_usec=200000;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc,&fds);
|
||||
|
||||
switch(select(FD_SETSIZE,&fds,(fd_set*)0,(fd_set*)0,&tout))
|
||||
{
|
||||
case 0: /* timeout */ break;
|
||||
case -1: /* error */
|
||||
printf("select failed\n");
|
||||
return -1;
|
||||
default: /* data ready */
|
||||
flen=sizeof(fromsin);
|
||||
mlen=recvfrom(soc,(char*)ibuf,isize,0,&fromsin,&flen);
|
||||
if(mlen<0) return -1;
|
||||
done=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i>=BS_RETRY_COUNT) return 0;
|
||||
|
||||
return mlen;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Open a broadcast socket and set port to a default.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSipBroadcastOpen(BSDATA* info, int default_dest_port)
|
||||
{
|
||||
struct sockaddr_in* sin;
|
||||
int soc;
|
||||
|
||||
sin=(struct sockaddr_in*)&(info->sin);
|
||||
|
||||
if( (soc=BSgetBroadcastSocket(0,sin)) <0) return -1;
|
||||
|
||||
sin->sin_port=htons(default_dest_port);
|
||||
|
||||
return soc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
BSgetBroadcastSocket() - return a broadcast socket for a port, return
|
||||
a sockaddr also.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin)
|
||||
{
|
||||
int on=1;
|
||||
int soc;
|
||||
BS bs;
|
||||
|
||||
sin->sin_port=htons(port);
|
||||
sin->sin_family=AF_INET;
|
||||
sin->sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if( (soc=socket(AF_INET,SOCK_DGRAM,BS_UDP)) < 0 )
|
||||
{
|
||||
perror("socket create failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
setsockopt(soc,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on));
|
||||
|
||||
if( bind(soc,(struct sockaddr*)sin,sizeof(struct sockaddr_in)) < 0 )
|
||||
{
|
||||
perror("socket bind failed");
|
||||
close(soc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( BSgetBroadcastAddr(soc,(struct sockaddr*)sin) < 0 )
|
||||
return -1;
|
||||
|
||||
return soc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
BSgetBroadcastAddr() - Determine the broadcast address, this is
|
||||
directly from the Sun Network Programmer's guide.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin)
|
||||
{
|
||||
struct ifconf ifc;
|
||||
struct ifreq* ifr;
|
||||
struct ifreq* save;
|
||||
char buf[BUFSIZ];
|
||||
int tot,i;
|
||||
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if(ioctl(soc,SIOCGIFCONF,(int)&ifc) < 0)
|
||||
{ perror("ioctl SIOCGIFCONF failed"); return -1; }
|
||||
|
||||
ifr = ifc.ifc_req;
|
||||
tot = ifc.ifc_len/sizeof(struct ifreq);
|
||||
save=(struct ifreq*)NULL;
|
||||
i=0;
|
||||
|
||||
do
|
||||
{
|
||||
if(ifr[i].ifr_addr.sa_family==AF_INET)
|
||||
{
|
||||
if(ioctl(soc,SIOCGIFFLAGS,(int)&ifr[i])<0)
|
||||
{ perror("ioctl SIOCGIFFLAGS failed"); return -1; }
|
||||
|
||||
if( (ifr[i].ifr_flags&IFF_UP) &&
|
||||
!(ifr[i].ifr_flags&IFF_LOOPBACK) &&
|
||||
(ifr[i].ifr_flags&IFF_BROADCAST))
|
||||
{ save=&ifr[i]; }
|
||||
}
|
||||
} while( !save && ++i<tot );
|
||||
|
||||
if(save)
|
||||
{
|
||||
if(ioctl(soc,SIOCGIFBRDADDR,(int)save)<0)
|
||||
{ perror("ioctl SIOCGIFBRDADDR failed"); return -1; }
|
||||
|
||||
memcpy((char*)sin,(char*)&save->ifr_broadaddr,
|
||||
sizeof(save->ifr_broadaddr));
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
188
src/dbtools/BSlib.h
Normal file
188
src/dbtools/BSlib.h
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef ___BS_H
|
||||
#define ___BS_H
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jim Kowalkowski
|
||||
Date: 9/1/95
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* got from protocols(5) (cheated) or /etc/protocols */
|
||||
#define BS_UDP 17
|
||||
#define BS_TCP 6
|
||||
|
||||
/* server ports - in the user reserved area - above 50000 */
|
||||
#define BS_UDP_PORT 50296
|
||||
#define BS_TCP_PORT 50297
|
||||
|
||||
/* message types */
|
||||
#define BS_Ok 0
|
||||
#define BS_Error 1
|
||||
#define BS_Close 2
|
||||
#define BS_Ping 3
|
||||
#define BS_Done 4
|
||||
|
||||
#define BS_LAST_VERB 4
|
||||
#define BS_RETRY_COUNT 3
|
||||
|
||||
/* protocol states */
|
||||
typedef enum { BSidle,BSunbound,BSsData,BSrData,BSbad,BSeof } BSstate;
|
||||
|
||||
struct bs
|
||||
{
|
||||
int soc;
|
||||
int remaining_send;
|
||||
int remaining_recv;
|
||||
BSstate state;
|
||||
};
|
||||
typedef struct bs BS;
|
||||
|
||||
struct bs_udp_data
|
||||
{
|
||||
struct sockaddr sin;
|
||||
int len;
|
||||
};
|
||||
typedef struct bs_udp_data BSDATA;
|
||||
|
||||
struct BSmsgHead
|
||||
{
|
||||
unsigned short verb;
|
||||
unsigned long size;
|
||||
};
|
||||
typedef struct BSmsgHead BSmsgHead;
|
||||
|
||||
typedef unsigned long BS_ULONG;
|
||||
|
||||
#define BSgetSocket(BS) (BS->soc)
|
||||
#define BSgetResidualWrite(BS) (BS->remaining_send)
|
||||
#define BSgetResidualRead(BS) (BS->remaining_recv)
|
||||
#define BSgetProtoState(BS) (BS->state)
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Server functions:
|
||||
|
||||
BSopenListenerTCP:
|
||||
Open a socket locally bound to the bulk data transfer TCP server port.
|
||||
Set the socket up as a listener. Return the open socket.
|
||||
|
||||
BSopenListenerUDP:
|
||||
Open a socket locally bound to the bulk data transfer UDP server port.
|
||||
Return the open socket.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
int BSopenListenerTCP(int Port);
|
||||
int BSopenListenerUDP(int Port);
|
||||
int BSopenTCP(BSDATA*);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Utilities functions:
|
||||
|
||||
BSmakeServer:
|
||||
Available under unix only. Put process in the background, disassociate
|
||||
process from controlling terminal and parent process, and prepare
|
||||
signals for reaping children spawned by the process.
|
||||
|
||||
BSserverClearSignals:
|
||||
Clear the signal handlers for a process, set them to default.
|
||||
|
||||
BSmakeBS:
|
||||
Allocate and initialize a BS from a socket.
|
||||
|
||||
BSfreeBS:
|
||||
Close the open socket and free the memory for the BS.
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef vxWorks
|
||||
int BSmakeServer(char** argv);
|
||||
int BSserverClearSignals();
|
||||
#endif
|
||||
|
||||
BS* BSmakeBS(int socket); /* make a BS from a socket */
|
||||
int BSfreeBS(BS* bdt); /* free a BS */
|
||||
|
||||
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin);
|
||||
int BSipBroadcastOpen(BSDATA* info, int default_dest_port);
|
||||
int BSgetAddressPort(BSDATA* info,char* ip_addr, int* dest_port);
|
||||
int BSsetAddressPort(BSDATA* info,char* ip_addr, int dest_port);
|
||||
int BSsetAddress(BSDATA* info,char* ip_addr);
|
||||
int BSsetPort(BSDATA* info,int dest_port);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
UDP functions:
|
||||
------------------------------------------------------------------------ */
|
||||
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize);
|
||||
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize);
|
||||
int BSwriteDataUDP(int soc,int dest_port, char* ip_addr,void* obuf,int osize);
|
||||
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size);
|
||||
int BSbroadcast(int soc,BSDATA* info,void* buf,int size);
|
||||
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
|
||||
void* obuf,int osize,void* ibuf,int isize);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Client functions:
|
||||
|
||||
BSipOpen:
|
||||
Open a connection to an bulk data transfer given the IP address of the
|
||||
machine where the server exists. The returned BS is returned unbound,
|
||||
a connect must be issued before data transactions can take place.
|
||||
|
||||
BSclose:
|
||||
Completely close a connection to a server and free the BS.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
BS* BSipOpen(char* address, int port);
|
||||
BS* BSipOpenData(BSDATA* info);
|
||||
int BSclose(BS* bdt);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Client and Server shared functions:
|
||||
|
||||
BSsendHeader:
|
||||
Send a message header out to a connect BS with command and message body
|
||||
size information.
|
||||
|
||||
BSsendData:
|
||||
Send a portion or all the message body out a connected BS. A header
|
||||
must have previously been sent with length information. The interface
|
||||
will only allow the amount of data specified in the header to be sent.
|
||||
|
||||
BSwrite:
|
||||
This call will block until all the data specified in the size parameter
|
||||
are sent down the socket.
|
||||
|
||||
BSread:
|
||||
This call will block until all the data specified in the size parameter
|
||||
is read from the socket.
|
||||
|
||||
BSreceiveHeader:
|
||||
Wait until a message header appears at the BS, return the action and
|
||||
remaining message body size.
|
||||
|
||||
BSreceiveData:
|
||||
Wait for a chunk or the entire body of a message to appear at the BS.
|
||||
Put the data into the buffer for a maximum size. Return the amount of
|
||||
data actually received, or zero if there is no data remaining for the
|
||||
current message.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
int BSsendHeader(BS* bdt, unsigned short verb, int size);
|
||||
int BSsendData(BS* bdt, void* buffer, int size);
|
||||
int BSreceiveHeader(BS* bdt, int* verb, int* size);
|
||||
int BSreceiveData(BS* bdt, void* buffer, int size);
|
||||
int BSread(int socket, void* buffer, int size);
|
||||
int BSwrite(int socket, void* buffer, int size);
|
||||
int BSflushOutput(BS* bdt);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,29 +2,45 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
# USR_CFLAGS = -v
|
||||
|
||||
LEX = $(ELEX)
|
||||
YACC = $(EYACC)
|
||||
YACCOPT = -l
|
||||
LEXOPT = -L
|
||||
|
||||
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
|
||||
dbLoadRecords_lex.c dbLoadRecords.c
|
||||
dbLoadRecords_lex.c dbLoadRecords.c \
|
||||
../BSlib.c ../PVSserver.c ../rdbapplist.c ../rdbls.o
|
||||
|
||||
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
VAR_OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
OBJS = $(VAR_OBJS) BSlib.o PVSserver.o rdbapplist.o rdbls.o
|
||||
|
||||
PROD = subtool dbLoadTemplate
|
||||
PROD = subtool dbLoadTemplate rdbls rdbapplist
|
||||
TARGETS = PVSserver
|
||||
|
||||
include $(EPICS)/config/RULES.Unix
|
||||
|
||||
dbLoadTemplate.o: dbLoadTemplate_lex.c
|
||||
dbLoadRecords.o: dbLoadRecords_lex.c
|
||||
|
||||
subtool: dbLoadTemplate.c dbLoadTemplate_lex.c dbVarSub.o
|
||||
$(RM) $@
|
||||
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o subtool dbLoadTemplate.c dbVarSub.o -s
|
||||
PVSserver: PVSserver.o BSlib.o
|
||||
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
dbLoadTemplate: $(OBJS)
|
||||
$(LINK.c) -o $@ $(OBJS) $(LDLIBS) -lDb
|
||||
rdbls: rdbls.o BSlib.o
|
||||
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
rdbapplist: rdbapplist.o BSlib.o
|
||||
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
subtool.o: dbLoadTemplate.c dbLoadTemplate_lex.c
|
||||
$(COMPILE.c) $(CFLAGS) -DSUB_TOOL -o $@ $<
|
||||
|
||||
subtool: subtool.o dbVarSub.o
|
||||
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o $@ $^ -s
|
||||
|
||||
dbLoadTemplate: $(VAR_OBJS)
|
||||
$(LINK.c) -o $@ $^ $(LDLIBS) -lDb
|
||||
|
||||
clean::
|
||||
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \
|
||||
|
||||
@@ -8,10 +8,11 @@ YACCOPT = -l
|
||||
LEXOPT = -L
|
||||
|
||||
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
|
||||
dbLoadRecords_lex.c dbLoadRecords.c
|
||||
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
dbLoadRecords_lex.c dbLoadRecords.c ../BSlib.c ../PVSvx.c
|
||||
|
||||
PROD = dbSubs
|
||||
LIBOBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o BSlib.o PVSvx.o
|
||||
|
||||
LIBNAME = dbSubs
|
||||
|
||||
include $(EPICS)/config/RULES.Vx
|
||||
|
||||
@@ -29,7 +30,4 @@ clean::
|
||||
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \
|
||||
dbLoadRecords.c
|
||||
|
||||
dbSubs: $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
|
||||
31
src/dbtools/PVS.h
Normal file
31
src/dbtools/PVS.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef __PVS_H
|
||||
#define __PVS_H
|
||||
|
||||
#include "BSlib.h"
|
||||
|
||||
#define PVS_RETRY_COUNT 4
|
||||
#define PVS_TRANSFER_SIZE 1024
|
||||
#define PVS_UDP 17
|
||||
#define PVS_TCP 6
|
||||
#define PVS_UDP_PORT 50298
|
||||
#define PVS_TCP_PORT 50299
|
||||
#define PVS_UDP_CPORT 50300
|
||||
|
||||
#define PVS_Data (BS_LAST_VERB+1)
|
||||
#define PVS_Alive (BS_LAST_VERB+2)
|
||||
#define PVS_RecList (BS_LAST_VERB+3)
|
||||
#define PVS_AppList (BS_LAST_VERB+4)
|
||||
#define PVS_RecDump (BS_LAST_VERB+5)
|
||||
|
||||
#define PVS_LAST_VERB PVS_RecDump
|
||||
|
||||
struct pvs_info_packet
|
||||
{
|
||||
unsigned short cmd;
|
||||
char text[90];
|
||||
};
|
||||
typedef struct pvs_info_packet PVS_INFO_PACKET;
|
||||
|
||||
#define PVS_SET_CMD(pvs_info,command) (pvs_info)->cmd=htons(command)
|
||||
|
||||
#endif
|
||||
263
src/dbtools/PVSserver.c
Normal file
263
src/dbtools/PVSserver.c
Normal file
@@ -0,0 +1,263 @@
|
||||
|
||||
/* only runable on work station now */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct PVSnode
|
||||
{
|
||||
BSDATA info;
|
||||
int alive;
|
||||
struct PVSnode* next;
|
||||
};
|
||||
typedef struct PVSnode PVSNODE;
|
||||
|
||||
static PVSNODE* ioc_list = (PVSNODE*)NULL;
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname);
|
||||
|
||||
#ifndef PVS_SERVER_PROG
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
BSDATA info;
|
||||
int serv;
|
||||
int rc;
|
||||
|
||||
if(argc<4)
|
||||
{
|
||||
fprintf(stderr,"usage: %s IOC-name server-number [server-name]\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
serv=atoi(argv[2]);
|
||||
BSsetAddress(&info,argv[1]);
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rc=read_pvs(&info,serv,argv[3]);
|
||||
else
|
||||
rc=read_pvs(&info,serv,(char*)NULL);
|
||||
|
||||
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
int soc,mlen;
|
||||
unsigned short buf,in_buf,ping;
|
||||
BSDATA info;
|
||||
PVSNODE* node;
|
||||
|
||||
if(BSmakeServer(argv)<0)
|
||||
{
|
||||
fprintf(stderr,"Cannot make into a server\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((soc=BSopenListenerUDP(PVS_UDP_PORT))<0)
|
||||
{
|
||||
fprintf(stderr,"Open of UDP listener socket failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf=htons(BS_Ok); /* always sends this out */
|
||||
ping=htons(BS_Ping); /* always sends this out */
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* wait forever until a message comes in */
|
||||
|
||||
mlen=BSreadUDP(soc,&info,7,&in_buf,sizeof(in_buf));
|
||||
|
||||
/* check for errors */
|
||||
switch(mlen)
|
||||
{
|
||||
case 0: /* timeout */
|
||||
printf("Why did a timeout occur?\n");
|
||||
/* send out a ping to each of the IOCs in the ioc_list */
|
||||
for(node=ioc_list;node;node=node->next)
|
||||
{
|
||||
mlen=BStransUDP(soc,&(node->info),&ping,sizeof(ping),
|
||||
&in_buf,sizeof(in_buf));
|
||||
|
||||
/* check for errors */
|
||||
switch(mlen)
|
||||
{
|
||||
case 0: /* timeout */
|
||||
printf("IOC dead\n");
|
||||
node->alive=0;
|
||||
break;
|
||||
case -1: /* error */
|
||||
printf("Communications failed\n");
|
||||
break;
|
||||
default: /* ok */
|
||||
if(node->alive==0)
|
||||
{
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("fork failure");
|
||||
break;
|
||||
case 0: /* child */
|
||||
close(soc);
|
||||
BSserverClearSignals();
|
||||
sleep(1);
|
||||
if(read_pvs(&(node->info))==0)
|
||||
node->alive=1;
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case -1: /* error */
|
||||
fprintf(stderr,"Communications failure\n");
|
||||
break;
|
||||
default: /* ok */
|
||||
if(BSwriteUDP(soc,&info,&buf,sizeof(buf))<0)
|
||||
fprintf(stderr,"respone send failed\n");
|
||||
else
|
||||
{
|
||||
node=(PVSNODE*)malloc(sizeof(PVSNODE));
|
||||
node->alive=1;
|
||||
node->info=info;
|
||||
BSsetPort(&(node->info),PVS_UDP_CPORT);
|
||||
node->next=ioc_list;
|
||||
ioc_list=node;
|
||||
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("fork failure");
|
||||
break;
|
||||
case 0: /* child */
|
||||
close(soc);
|
||||
BSserverClearSignals();
|
||||
sleep(1);
|
||||
return read_pvs(&info,PVS_RecList,NULL);
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(soc);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname)
|
||||
{
|
||||
BS* bs;
|
||||
int verb,size,done,len,i,port,rsize;
|
||||
char* buffer;
|
||||
char ip_from[40];
|
||||
FILE* fd;
|
||||
|
||||
BSgetAddressPort(info,ip_from,&port);
|
||||
|
||||
/* printf("IOC %s starting\n",ip_from); */
|
||||
|
||||
/* verify ioc not already added */
|
||||
if(access(ip_from,F_OK)==0)
|
||||
{
|
||||
/* delete the existing file for this IOC */
|
||||
unlink(ip_from);
|
||||
}
|
||||
|
||||
done=0;
|
||||
BSsetPort(info,PVS_TCP_PORT);
|
||||
|
||||
if((bs=BSipOpenData(info))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of socket to IOC failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rsize=strlen(sname)+1;
|
||||
else
|
||||
rsize=0;
|
||||
|
||||
if(BSsendHeader(bs,serv,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"Command send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rsize>0)
|
||||
{
|
||||
if(BSsendData(bs,sname,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"send of command name failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PVS_SERVER_PROG
|
||||
if((fd=fopen(ip_from,"w"))==(FILE*)NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of name file failed\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
fd=stdout;
|
||||
#endif
|
||||
|
||||
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
|
||||
|
||||
while(done==0)
|
||||
{
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"Receive header failed\n");
|
||||
done=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_Data: /* read a block of names */
|
||||
if((len=BSreceiveData(bs,buffer,size))<0)
|
||||
{
|
||||
fprintf(stderr,"Receive data failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
if(buffer[i]==' ') buffer[i]='\n';
|
||||
}
|
||||
buffer[len]='\n';
|
||||
buffer[len+1]='\0';
|
||||
|
||||
fputs(buffer,fd);
|
||||
}
|
||||
break;
|
||||
case BS_Done: /* transfers complete */
|
||||
BSclose(bs);
|
||||
done=-1;
|
||||
break;
|
||||
default:
|
||||
if(size>0) done=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PVS_SERVER_PROG
|
||||
fclose(fd);
|
||||
#endif
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
361
src/dbtools/PVSvx.c
Normal file
361
src/dbtools/PVSvx.c
Normal file
@@ -0,0 +1,361 @@
|
||||
|
||||
/* This file not really set up to run under Unix yet, just under vxWorks. */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <taskLib.h>
|
||||
#include <sysSymTbl.h>
|
||||
#include <sysLib.h>
|
||||
#include <symLib.h>
|
||||
#include <dbStaticLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static void PVSserver(int want_annouce,char* name);
|
||||
static int PVSannouce(int want_annouce,char* name);
|
||||
static void handle_requests(BS* bs);
|
||||
static void handle_reclist(BS* bs);
|
||||
static void handle_applist(BS* bs);
|
||||
static void handle_recdump(BS* bs);
|
||||
static void handle_spylist(BS* bs);
|
||||
static void handle_tasklist(BS* bs);
|
||||
void PVS_test_server(BS* bs);
|
||||
|
||||
static char* names = (char*)NULL;
|
||||
static char* buffer = (char*)NULL;
|
||||
|
||||
#ifdef vxWorks
|
||||
int PVSstart(int want_annouce, char* name)
|
||||
#else
|
||||
int main(int argc,char** argv)
|
||||
#endif
|
||||
{
|
||||
#ifndef vxWorks
|
||||
char* name;
|
||||
int want_annouce;
|
||||
#endif
|
||||
|
||||
#ifndef vxWorks
|
||||
if(argc<3)
|
||||
{
|
||||
fprintf(stderr,"bad args\n");
|
||||
fprintf(stderr," usage: %s a_flag host_name\n",
|
||||
argv[0]);
|
||||
fprintf(stderr," where\n");
|
||||
fprintf(stderr," a_flag=0(want),1(don't want) to annouce boot\n");
|
||||
fprintf(stderr," host_name=PV master host (if one exists)\n");
|
||||
return -1;
|
||||
}
|
||||
name=argv[2];
|
||||
if(sscanf(argv[1],"%d",&want_annouce)<1)
|
||||
{
|
||||
fprintf(stderr,"bad a_flag\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
taskSpawn("PVS",150,VX_FP_TASK|VX_STDIO,5000,
|
||||
(FUNCPTR)PVSserver,want_annouce,(int)name,0,0,0,0,0,0,0,0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PVSannouce(int want_annouce,char* name)
|
||||
{
|
||||
int soc,mlen;
|
||||
PVS_INFO_PACKET buf,in_buf;
|
||||
BSDATA info,in_info;
|
||||
|
||||
if(want_annouce==0 && name)
|
||||
{
|
||||
if((soc=BSopenListenerUDP(0))<0)
|
||||
{
|
||||
printf("Open of UDP socket failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSsetAddressPort(&info,name,PVS_UDP_PORT)<0)
|
||||
{
|
||||
printf("Set send port failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PVS_SET_CMD(&buf,PVS_Alive);
|
||||
mlen=BStransUDP(soc,&info,&buf,sizeof(buf),&in_buf,sizeof(in_buf));
|
||||
|
||||
/* check for errors */
|
||||
switch(mlen)
|
||||
{
|
||||
case 0: /* timeout */
|
||||
printf("No server running on host\n");
|
||||
break;
|
||||
case -1: /* error */
|
||||
printf("Communications failed\n");
|
||||
break;
|
||||
default: /* ok */
|
||||
break;
|
||||
}
|
||||
|
||||
close(soc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PVSserver(int want_annouce,char* name)
|
||||
{
|
||||
fd_set fds,rfds;
|
||||
int tsoc,usoc,nsoc,len,s;
|
||||
struct sockaddr stemp;
|
||||
int stemp_len;
|
||||
PVS_INFO_PACKET buf;
|
||||
BSDATA info;
|
||||
BS* bs;
|
||||
|
||||
bs=(BS*)NULL;
|
||||
buffer=(char*)malloc(100); /* just make the buffer */
|
||||
names=(char*)malloc(PVS_TRANSFER_SIZE);
|
||||
|
||||
if((tsoc=BSopenListenerTCP(PVS_TCP_PORT))<0)
|
||||
{
|
||||
printf("PVSserver: Open of TCP listener socket failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if((usoc=BSopenListenerUDP(PVS_UDP_CPORT))<0)
|
||||
{
|
||||
printf("PVSserver: Open of UDP listener socket failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(tsoc,&fds);
|
||||
FD_SET(usoc,&fds);
|
||||
|
||||
PVSannouce(want_annouce,name);
|
||||
|
||||
while(1)
|
||||
{
|
||||
rfds=fds;
|
||||
if(select(FD_SETSIZE,&rfds,(fd_set*)NULL,(fd_set*)NULL,
|
||||
(struct timeval*)NULL)<0)
|
||||
{
|
||||
printf("PVSserver: Select failure\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(FD_ISSET(tsoc,&rfds))
|
||||
{
|
||||
/* handle the request here - single threaded server */
|
||||
|
||||
stemp_len=sizeof(stemp);
|
||||
if((nsoc=accept(tsoc,&stemp,&stemp_len))<0)
|
||||
printf("PVSserver: Bad accept\n");
|
||||
else
|
||||
{
|
||||
bs=BSmakeBS(nsoc);
|
||||
handle_requests(bs);
|
||||
BSfreeBS(bs);
|
||||
}
|
||||
}
|
||||
if(FD_ISSET(usoc,&rfds))
|
||||
{
|
||||
/* only pings will come in here for now */
|
||||
len=BSreadUDP(usoc,&info,0,&buf,sizeof(buf));
|
||||
if(len<=0)
|
||||
printf("PVSserver: UDP listener read failure\n");
|
||||
else
|
||||
{
|
||||
if(BSwriteUDP(usoc,&info,&buf,sizeof(buf))<0)
|
||||
printf("PVSserver: UDP listener ping write failure\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_reclist(BS* bs)
|
||||
{
|
||||
DBENTRY db;
|
||||
long rc;
|
||||
char* n;
|
||||
unsigned long names_len;
|
||||
int s;
|
||||
|
||||
dbInitEntry(pdbBase,&db);
|
||||
names_len=0;
|
||||
|
||||
for(rc=dbFirstRecdes(&db);rc==0;rc=dbNextRecdes(&db))
|
||||
{
|
||||
for(rc=dbFirstRecord(&db);rc==0;rc=dbNextRecord(&db))
|
||||
{
|
||||
/* collect the names util we excede the max */
|
||||
n=dbGetRecordName(&db);
|
||||
s=strlen(n);
|
||||
if((names_len+s)>PVS_TRANSFER_SIZE)
|
||||
{
|
||||
names[names_len++]='\0';
|
||||
if(BSsendHeader(bs,PVS_Data,names_len)<0)
|
||||
printf("PVSserver: data cmd failed\n");
|
||||
else
|
||||
{
|
||||
if(BSsendData(bs,names,names_len)<0)
|
||||
printf("PVSserver: data send failed\n");
|
||||
}
|
||||
names_len=0;
|
||||
}
|
||||
memcpy(&names[names_len],n,s);
|
||||
names_len+=s;
|
||||
names[names_len++]=' ';
|
||||
}
|
||||
}
|
||||
if(names_len>0)
|
||||
{
|
||||
names[names_len++]='\0';
|
||||
if(BSsendHeader(bs,PVS_Data,names_len)<0)
|
||||
printf("PVSserver: data cmd failed\n");
|
||||
else
|
||||
{
|
||||
if(BSsendData(bs,names,names_len)<0)
|
||||
printf("PVSserver: data send failed\n");
|
||||
}
|
||||
}
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
static void handle_requests(BS* bs)
|
||||
{
|
||||
int verb,size,notdone,len;
|
||||
void (*func)(BS*);
|
||||
SYM_TYPE stype;
|
||||
|
||||
notdone=1;
|
||||
while(notdone)
|
||||
{
|
||||
/* at this point I should be getting a command */
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
printf("PVSserver: receive header failed\n");
|
||||
notdone=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_RecList: handle_reclist(bs); break;
|
||||
case PVS_AppList: handle_applist(bs); break;
|
||||
case PVS_RecDump: handle_recdump(bs); break;
|
||||
case BS_Close:
|
||||
BSsendHeader(bs,BS_Ok,0);
|
||||
notdone=0;
|
||||
break;
|
||||
case PVS_Data: break;
|
||||
case PVS_Alive: break;
|
||||
case BS_Ok: break;
|
||||
case BS_Error: break;
|
||||
case BS_Ping: break;
|
||||
case BS_Done: break;
|
||||
default:
|
||||
/* custom service */
|
||||
if(size>0)
|
||||
{
|
||||
/* this should be the name of the service */
|
||||
/* look up the symbol name in buffer and call as
|
||||
subroutine, passing it the BS */
|
||||
|
||||
len=BSreceiveData(bs,&buffer[1],size);
|
||||
switch(len)
|
||||
{
|
||||
case 0: /* timeout */ notdone=0; break;
|
||||
case -1: /* error */ notdone=0; break;
|
||||
default:
|
||||
buffer[0]='_';
|
||||
|
||||
if(strncmp(buffer,"_PVS",4)==0)
|
||||
{
|
||||
if(symFindByName(sysSymTbl,buffer,
|
||||
(char**)&func,&stype)==ERROR)
|
||||
func=(void (*)(BS*))NULL;
|
||||
|
||||
if(func)
|
||||
func(bs);
|
||||
else
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
else
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("PVSserver: unknown command received\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
struct dbnode
|
||||
{
|
||||
char* name;
|
||||
struct dbnode* next;
|
||||
};
|
||||
typedef struct dbnode DBNODE;
|
||||
|
||||
extern DBNODE* DbApplList;
|
||||
|
||||
void handle_applist(BS* bs)
|
||||
{
|
||||
DBNODE* n;
|
||||
int size,len;
|
||||
|
||||
len=0;
|
||||
for(n=DbApplList;n;n=n->next)
|
||||
{
|
||||
len=strlen(n->name)+1;
|
||||
|
||||
if(BSsendHeader(bs,PVS_Data,len)<0)
|
||||
printf("PVSserver: data cmd failed\n");
|
||||
else
|
||||
{
|
||||
if(BSsendData(bs,n->name,len)<0)
|
||||
printf("PVSserver: data send failed\n");
|
||||
}
|
||||
}
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
void handle_recdump(BS* bs)
|
||||
{
|
||||
printf("RecDump server invoked\n");
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
void PVS_test_server(BS* bs)
|
||||
{
|
||||
printf("PVS_test_server invoked\n");
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
void handle_spylist(BS* bs)
|
||||
{
|
||||
printf("PVS spy list server invoked\n");
|
||||
}
|
||||
|
||||
void handle_tasklist(BS* bs)
|
||||
{
|
||||
printf("PVS task list server invoked\n");
|
||||
}
|
||||
@@ -49,6 +49,17 @@ static char subst_buffer[VAR_MAX_SUB_SIZE];
|
||||
static int subst_used;
|
||||
static int line_num;
|
||||
|
||||
struct db_app_node
|
||||
{
|
||||
char* name;
|
||||
struct db_app_node* next;
|
||||
};
|
||||
typedef struct db_app_node DB_APP_NODE;
|
||||
|
||||
DB_APP_NODE* DbApplList=(DB_APP_NODE*)NULL;
|
||||
static DB_APP_NODE* DbCurrentListHead=(DB_APP_NODE*)NULL;
|
||||
static DB_APP_NODE* DbCurrentListTail=(DB_APP_NODE*)NULL;
|
||||
|
||||
static int yyerror();
|
||||
static void sub_pvname(char*,char*);
|
||||
|
||||
@@ -65,8 +76,9 @@ extern struct dbBase *pdbBase;
|
||||
%token <Str> WORD VALUE
|
||||
%token <Str> FIELD
|
||||
%left O_BRACE C_BRACE O_PAREN C_PAREN
|
||||
%left DATABASE CONTAINER RECORD
|
||||
%left NOWHERE
|
||||
%left DATABASE RECORD
|
||||
%left NOWHERE
|
||||
%token APPL
|
||||
|
||||
%union
|
||||
{
|
||||
@@ -105,18 +117,39 @@ n_body: O_BRACE records C_BRACE
|
||||
;
|
||||
|
||||
db_components: /* null */
|
||||
| db_components container
|
||||
| db_components applic
|
||||
| db_components record
|
||||
;
|
||||
|
||||
container: CONTAINER c_head c_body
|
||||
;
|
||||
applic: APPL O_PAREN VALUE C_PAREN
|
||||
{
|
||||
DB_APP_NODE* an=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE*));
|
||||
|
||||
c_head: O_PAREN WORD C_PAREN
|
||||
{ free($2); }
|
||||
;
|
||||
if(subst_used)
|
||||
{
|
||||
strcpy(subst_buffer,$<Str>3);
|
||||
if(dbDoSubst(subst_buffer,sizeof(subst_buffer),NULL)!=0)
|
||||
fprintf(stderr,"dbDoSubst failed\n");
|
||||
#ifdef vxWorks
|
||||
an->name=strdup(subst_buffer);
|
||||
free($3);
|
||||
#else
|
||||
printf("\napplication(\"%s\")\n",subst_buffer);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef vxWorks
|
||||
an->name=$<Str>3;
|
||||
#else
|
||||
printf("\napplication(\"%s\")\n",$<Str>3);
|
||||
#endif
|
||||
}
|
||||
if(DbCurrentListHead==(DB_APP_NODE*)NULL) DbCurrentListTail=an;
|
||||
|
||||
c_body: O_BRACE db_components C_BRACE
|
||||
an->next=DbCurrentListHead;
|
||||
DbCurrentListHead=an;
|
||||
}
|
||||
;
|
||||
|
||||
records: /* null */
|
||||
@@ -190,13 +223,24 @@ field: FIELD O_PAREN WORD COMMA VALUE C_PAREN
|
||||
static int yyerror(str)
|
||||
char *str;
|
||||
{ fprintf(stderr,"db file parse, Error line %d : %s\n",line_num, yytext); }
|
||||
|
||||
#ifdef vxWorks
|
||||
static char* strdup(char* x)
|
||||
{
|
||||
char* c;
|
||||
c=(char*)malloc(strlen(x)+1);
|
||||
strcpy(c,x);
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
int dbLoadRecords(char* pfilename, char* pattern)
|
||||
{
|
||||
FILE* fp;
|
||||
long status;
|
||||
DB_APP_NODE* an;
|
||||
|
||||
#ifdef vxWorks
|
||||
if(pdbBase==NULL)
|
||||
@@ -243,6 +287,21 @@ int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
if(subst_used) dbFreeSubst();
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(DbCurrentListHead==(DB_APP_NODE*)NULL)
|
||||
{
|
||||
/* set up a default list to put on the master application list */
|
||||
DbCurrentListHead=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE));
|
||||
DbCurrentListTail=DbCurrentListHead;
|
||||
DbCurrentListHead->name=strdup(pfilename);
|
||||
DbCurrentListHead->next=(DB_APP_NODE*)NULL;
|
||||
}
|
||||
|
||||
DbCurrentListTail->next=DbApplList;
|
||||
DbApplList=DbCurrentListHead;
|
||||
DbCurrentListHead=(DB_APP_NODE*)NULL;
|
||||
DbCurrentListTail=(DB_APP_NODE*)NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -276,3 +335,14 @@ static void sub_pvname(char* type, char* name)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef vxWorks
|
||||
int dbAppList()
|
||||
{
|
||||
DB_APP_NODE* an;
|
||||
|
||||
for(an=DbApplList;an;an=an->next)
|
||||
printf("%s\n",an->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
pvname [a-zA-Z0-9_\-:\.\[\]<>;]
|
||||
pvname [a-zA-Z0-9_~\-:\.\[\]<>;]
|
||||
value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
|
||||
%{
|
||||
@@ -12,9 +12,9 @@ value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
"field" { return(FIELD); }
|
||||
"grecord" { return(RECORD); }
|
||||
"record" { return(RECORD); }
|
||||
"container" { return(CONTAINER); }
|
||||
"database" { return(DATABASE); }
|
||||
"nowhere" { return(NOWHERE); }
|
||||
"application" { return(APPL); }
|
||||
|
||||
\"{value}*\" { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(VALUE); }
|
||||
|
||||
|
||||
@@ -276,9 +276,11 @@ sub_pat: WORD EQUALS WORD
|
||||
|
||||
#include "dbLoadTemplate_lex.c"
|
||||
|
||||
static int yyerror(str)
|
||||
char *str;
|
||||
{ fprintf(stderr,"templ file parse, Error line %d : %s\n",line_num, yytext); }
|
||||
static int yyerror(char* str)
|
||||
{
|
||||
fprintf(stderr,"Substitution file parse error\n");
|
||||
fprintf(stderr,"line %d:%s\n",line_num,yytext);
|
||||
}
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
value [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
|
||||
value [a-zA-Z0-9_~\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
|
||||
word [a-zA-Z0-9_\.\^~/\*#\[\]%:;!|\-&\$\(\)@\?\+<>]
|
||||
par [\"\']
|
||||
|
||||
|
||||
116
src/dbtools/rdbapplist.c
Normal file
116
src/dbtools/rdbapplist.c
Normal file
@@ -0,0 +1,116 @@
|
||||
|
||||
/* only runable on work station now */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname);
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
BSDATA info;
|
||||
int rc;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSsetAddress(&info,argv[1])<0)
|
||||
{
|
||||
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc=read_pvs(&info,PVS_AppList,(char*)NULL);
|
||||
|
||||
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname)
|
||||
{
|
||||
BS* bs;
|
||||
int verb,size,done,len,i,port,rsize;
|
||||
char* buffer;
|
||||
char ip_from[40];
|
||||
FILE* fd;
|
||||
|
||||
BSgetAddressPort(info,ip_from,&port);
|
||||
|
||||
/* verify ioc not already added */
|
||||
if(access(ip_from,F_OK)==0)
|
||||
{
|
||||
/* delete the existing file for this IOC */
|
||||
unlink(ip_from);
|
||||
}
|
||||
|
||||
done=0;
|
||||
BSsetPort(info,PVS_TCP_PORT);
|
||||
|
||||
if((bs=BSipOpenData(info))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of socket to IOC failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rsize=strlen(sname)+1;
|
||||
else
|
||||
rsize=0;
|
||||
|
||||
if(BSsendHeader(bs,serv,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"Command send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rsize>0)
|
||||
{
|
||||
if(BSsendData(bs,sname,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"send of command name failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fd=stdout;
|
||||
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
|
||||
|
||||
while(done==0)
|
||||
{
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"Receive header failed\n");
|
||||
done=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_Data: /* read a block of names */
|
||||
if((len=BSreceiveData(bs,buffer,size))<0)
|
||||
fprintf(stderr,"Receive data failed\n");
|
||||
else
|
||||
fputs(buffer,fd);
|
||||
fputc('\n',fd);
|
||||
break;
|
||||
case BS_Done: /* transfers complete */
|
||||
BSclose(bs);
|
||||
done=-1;
|
||||
break;
|
||||
default:
|
||||
if(size>0) done=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
128
src/dbtools/rdbls.c
Normal file
128
src/dbtools/rdbls.c
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
/* only runable on work station now */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname);
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
BSDATA info;
|
||||
int rc;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSsetAddress(&info,argv[1])<0)
|
||||
{
|
||||
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc=read_pvs(&info,PVS_RecList,(char*)NULL);
|
||||
|
||||
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname)
|
||||
{
|
||||
BS* bs;
|
||||
int verb,size,done,len,i,port,rsize;
|
||||
char* buffer;
|
||||
char ip_from[40];
|
||||
FILE* fd;
|
||||
|
||||
BSgetAddressPort(info,ip_from,&port);
|
||||
|
||||
/* printf("IOC %s starting\n",ip_from); */
|
||||
|
||||
/* verify ioc not already added */
|
||||
if(access(ip_from,F_OK)==0)
|
||||
{
|
||||
/* delete the existing file for this IOC */
|
||||
unlink(ip_from);
|
||||
}
|
||||
|
||||
done=0;
|
||||
BSsetPort(info,PVS_TCP_PORT);
|
||||
|
||||
if((bs=BSipOpenData(info))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of socket to IOC failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rsize=strlen(sname)+1;
|
||||
else
|
||||
rsize=0;
|
||||
|
||||
if(BSsendHeader(bs,serv,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"Command send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rsize>0)
|
||||
{
|
||||
if(BSsendData(bs,sname,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"send of command name failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fd=stdout;
|
||||
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
|
||||
|
||||
while(done==0)
|
||||
{
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"Receive header failed\n");
|
||||
done=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_Data: /* read a block of names */
|
||||
if((len=BSreceiveData(bs,buffer,size))<0)
|
||||
{
|
||||
fprintf(stderr,"Receive data failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
if(buffer[i]==' ') buffer[i]='\n';
|
||||
}
|
||||
buffer[len]='\n';
|
||||
buffer[len+1]='\0';
|
||||
|
||||
fputs(buffer,fd);
|
||||
}
|
||||
break;
|
||||
case BS_Done: /* transfers complete */
|
||||
BSclose(bs);
|
||||
done=-1;
|
||||
break;
|
||||
default:
|
||||
if(size>0) done=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
* This driver currently needs work on error message generation.
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1 1995/03/30 19:34:56 jba
|
||||
* Seperated drv files into ansi and old dirs. Added combine dir.
|
||||
*
|
||||
* Revision 1.37 1995/03/24 21:24:25 winans
|
||||
* Probable race condition in PEP TX task. Moved the final transmission
|
||||
* byte assignment into the point where the busy list is locked. This
|
||||
@@ -2532,6 +2535,11 @@ STATIC int pepTxTask(int link)
|
||||
if (bbDebug)
|
||||
printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link);
|
||||
|
||||
pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg;
|
||||
if (bbDebug>30)
|
||||
printf("pepTxTask(%d): outputting last byte %2.2X\n",
|
||||
link,*txMsg);
|
||||
|
||||
pnode->status = BB_OK;
|
||||
|
||||
if (pnode->finishProc != NULL) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
* for the DMA buffer that is appropriate.
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1 1995/03/30 19:35:14 jba
|
||||
* Seperated drv files into ansi and old dirs. Added combine dir.
|
||||
*
|
||||
* Revision 1.22 1995/01/06 17:03:43 winans
|
||||
* Added some ifdef'd out test code to see if the end of the sequence program
|
||||
* could be updated to NOT cause an extra sample from port zero to be taken
|
||||
@@ -181,7 +184,7 @@ static char *SccsId = "$Id$";
|
||||
#define ADVANCE_HOLD 0xC0
|
||||
#define RESTART 0x00
|
||||
|
||||
/* analogic 2502 memory structure */
|
||||
/* Analogic 2502 memory structure */
|
||||
struct dvx_2502
|
||||
{
|
||||
unsigned short dev_id; /* device id code (CFF5) */
|
||||
@@ -205,7 +208,7 @@ struct dvx_inbuf
|
||||
short *data; /* data buffer */
|
||||
};
|
||||
|
||||
/* analogic 2502 control structure */
|
||||
/* Analogic 2502 control structure */
|
||||
struct dvx_rec
|
||||
{
|
||||
struct dvx_2502 *pdvx2502; /* pointer to device registers */
|
||||
@@ -224,6 +227,8 @@ struct dvx_rec
|
||||
|
||||
int RearmMode; /* zero if auto-rearm, else manual */
|
||||
|
||||
unsigned short ScanRate; /* User settable scan rate */
|
||||
|
||||
IOSCANPVT *pioscanpvt;
|
||||
};
|
||||
|
||||
@@ -304,19 +309,19 @@ struct {
|
||||
static struct dvx_rec dvx[MAX_DVX_CARDS] = {
|
||||
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
|
||||
,{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
0 , NULL
|
||||
0 , DVX_DRATE, NULL
|
||||
},
|
||||
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
|
||||
,{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
0, NULL
|
||||
0, DVX_DRATE, NULL
|
||||
},
|
||||
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
|
||||
,{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
0, NULL
|
||||
0, DVX_DRATE, NULL
|
||||
},
|
||||
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
|
||||
,{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
0, NULL
|
||||
0, DVX_DRATE, NULL
|
||||
}
|
||||
};
|
||||
|
||||
@@ -425,6 +430,16 @@ dvx_int(struct dvx_rec *dvxptr)
|
||||
cptr->csr = dvxptr->csr_shadow;
|
||||
}
|
||||
|
||||
int dvx_SetScanRate(int Card, unsigned int Rate)
|
||||
{
|
||||
/* make sure hardware exists */
|
||||
if ((Card >= ai_num_cards[DVX2502]) || (Card < 0))
|
||||
return(-1);
|
||||
|
||||
dvx[Card].ScanRate = Rate & 0x0000FFFF;
|
||||
dvx[Card].pdvx2502->samp_rate = dvx[Card].ScanRate;
|
||||
return(0);
|
||||
}
|
||||
int dvx_RearmModeSet(int card, int mode)
|
||||
{
|
||||
/* make sure hardware exists */
|
||||
@@ -672,7 +687,11 @@ LOCAL long dvx_driver_init(void)
|
||||
/*
|
||||
* set scan rate and enable external start
|
||||
*/
|
||||
#if 0
|
||||
pDvxA16->samp_rate = DVX_DRATE; /* scan rate of 184 KHz */
|
||||
#else
|
||||
pDvxA16->samp_rate = dvx[i].ScanRate; /* Set scan rate */
|
||||
#endif
|
||||
dvx[i].csr_shadow |= CSR_M_ESTART; /* enable ext start (shadow csr) */
|
||||
pDvxA16->csr = dvx[i].csr_shadow; /* enable external start */
|
||||
dvx[i].mode = RUN_MODE; /* ready to aquire data */
|
||||
@@ -904,12 +923,17 @@ int sramld(int card)
|
||||
#endif
|
||||
|
||||
/* set scan rate and run it once */
|
||||
#if 0
|
||||
dvx[card].pdvx2502->samp_rate = DVX_DRATE;
|
||||
#else
|
||||
dvx[card].pdvx2502->samp_rate = dvx[card].ScanRate; /* Set scan rate */
|
||||
#endif
|
||||
dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_START;
|
||||
taskDelay(sysClkRateGet()); /* let scan run */
|
||||
dvx[card].pdvx2502->csr = dvx[card].csr_shadow; /* restore csr */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dvx_driver
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
108
src/libCom/bldEnvData
Executable file
108
src/libCom/bldEnvData
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# base/tools $Id$
|
||||
# Author: Andrew Johnson (RGO)
|
||||
# Date: 14-Mar-95
|
||||
#
|
||||
# Experimental Physics and Industrial Control System (EPICS)
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.1 1995/08/17 20:22:09 jba
|
||||
# Moved bldEnvData,blderrSymTbl, makeStatTbl to libCom dir
|
||||
#
|
||||
# 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[EPICS_ENV_VARIABLE_COUNT+1] = {
|
||||
!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 | Linux)
|
||||
# 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
18
src/libCom/env/envSubr.c
vendored
18
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,11 +68,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# include <winsock.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
@@ -81,9 +83,9 @@
|
||||
#endif
|
||||
|
||||
#include <envDefs.h>
|
||||
#include "envData.h"
|
||||
#include <errMdef.h>
|
||||
|
||||
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME envGetConfigParam - get value of a configuration parameter
|
||||
@@ -243,7 +245,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 +424,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 +448,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,11 +68,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef WIN32
|
||||
# include <winsock.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
@@ -81,9 +83,9 @@
|
||||
#endif
|
||||
|
||||
#include <envDefs.h>
|
||||
#include "envData.h"
|
||||
#include <errMdef.h>
|
||||
|
||||
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
* NAME envGetConfigParam - get value of a configuration parameter
|
||||
@@ -243,7 +245,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 +424,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 +448,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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user