Compare commits
60 Commits
R3.13.0-be
...
R3.13.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8a8f4c0e1 | ||
|
|
7a809e2e1e | ||
|
|
fdbfab2da2 | ||
|
|
50e53c3b60 | ||
|
|
6c974f9cf5 | ||
|
|
a48efbd861 | ||
|
|
2752749f5e | ||
|
|
d3bce294c3 | ||
|
|
6a51de27e5 | ||
|
|
779eea486e | ||
|
|
2b67d03514 | ||
|
|
830d2ff061 | ||
|
|
84b35b89ef | ||
|
|
6d0f7e878a | ||
|
|
951d97e7ff | ||
|
|
ccb8a554ab | ||
|
|
2cc65e1912 | ||
|
|
84544919cf | ||
|
|
f29a18fb06 | ||
|
|
373963601e | ||
|
|
03225a337e | ||
|
|
009ec62aab | ||
|
|
5f79145db6 | ||
|
|
592eb7a0d5 | ||
|
|
8d33c7127c | ||
|
|
19a8c56a69 | ||
|
|
daeb1247d8 | ||
|
|
fce5bb7398 | ||
|
|
e0122a1f18 | ||
|
|
fe782e3e4e | ||
|
|
5824a6096c | ||
|
|
4908e28d31 | ||
|
|
423e24fe8b | ||
|
|
db49a2babb | ||
|
|
e11c120f6b | ||
|
|
9155de5b30 | ||
|
|
599b22b70b | ||
|
|
6509cf77bf | ||
|
|
3c6ac06cff | ||
|
|
eba09bd6af | ||
|
|
b95644e9d7 | ||
|
|
6b415ddb49 | ||
|
|
88f27261f0 | ||
|
|
de29d6868d | ||
|
|
6e143c1b3c | ||
|
|
ffe28c21d6 | ||
|
|
4abdee5635 | ||
|
|
ae42cd5dfd | ||
|
|
dbd9309810 | ||
|
|
5d78536ad5 | ||
|
|
c41f2e9514 | ||
|
|
757be61d57 | ||
|
|
df10654f77 | ||
|
|
e7773db7a7 | ||
|
|
9f6dc20fd8 | ||
|
|
f654800370 | ||
|
|
f810436bb1 | ||
|
|
5593db0caf | ||
|
|
e9a04e688f | ||
|
|
b8fe2ed007 |
4
Makefile
4
Makefile
@@ -28,7 +28,3 @@ built_release:
|
||||
@echo TOP: Creating Fully Built Release...
|
||||
@./MakeRelease -b $(INSTALL_LOCATION)
|
||||
|
||||
uninstall::
|
||||
@DIR1=`pwd`;cd $(INSTALL_LOCATION);DIR2=`pwd`;cd $$DIR1;\
|
||||
if [ "$$DIR1" != "$$DIR2" ]; then $(RMDIR) $(INSTALL_LOCATION)/config; fi
|
||||
|
||||
|
||||
82
README.WIN32
82
README.WIN32
@@ -1,17 +1,19 @@
|
||||
Compiling EPICS on WIN32 (Windows95/NT)
|
||||
---------------------------------------
|
||||
|
||||
-kuk- 11/18/96 questions & comments please
|
||||
mailto:kasemir@atdiv.lanl.gov
|
||||
Original port of EPICS base to WIN32 (Windows95/NT)
|
||||
was done by Kay-Uwe Kasemir 11/96
|
||||
|
||||
questions & comments please mail to johill@lanl.gov
|
||||
|
||||
0) what you will get
|
||||
--------------------
|
||||
|
||||
Right now this port of EPICS to WIN32 should allow you to
|
||||
|
||||
* compile almost all EPICS base using Tornado, MS Visual C
|
||||
and some additional tools: gnumake, a UNIX-like shell, awk, sed, ...
|
||||
(See below where to get these.)
|
||||
* compile almost all of EPICS base using {Tornado, MS Visual C, perl,
|
||||
GNU make} (only {MS Visual C, perl, GNU make} if you prefer
|
||||
to compile only the host portions of EPICS base).
|
||||
* load EPICS on a PC IOC (486, pentium),
|
||||
load simple databases
|
||||
(no drivers/devices for real I/O available, yet.
|
||||
@@ -30,73 +32,41 @@ Right now this port of EPICS to WIN32 should allow you to
|
||||
To compiler EPICS on WIN32, we need
|
||||
|
||||
WindRiver Systems Tornado (used: 1.0)
|
||||
Microsoft Visual C (used: 4.0)
|
||||
Microsoft Visual C (used: 4.0)
|
||||
|
||||
and some tools:
|
||||
|
||||
a Unix-like shell
|
||||
gnumake
|
||||
basename
|
||||
date
|
||||
mv
|
||||
touch
|
||||
sort
|
||||
gnu make
|
||||
perl
|
||||
|
||||
All the above except. the shell are available 'on the net'
|
||||
The perl interpreter and gnu make are available 'on the net'
|
||||
as sources which compile with MS Visual C++.
|
||||
If you cannot/don't want to find them, contact me, please!
|
||||
|
||||
I could not find a shell that's fully operational.
|
||||
The best one seems to be the Cygnus bash for WIN32, though it
|
||||
still has errors and doesn't come with sources that compile
|
||||
under MS VC++.
|
||||
I use a small self-written shell called knts,
|
||||
again: Contact me if you need it.
|
||||
|
||||
* The final solution to make the shell, basename, date, ...
|
||||
* obsolete:
|
||||
* Use
|
||||
* 1) no shell scripts
|
||||
* 2) Perl which is available for Unix and WIN32
|
||||
|
||||
In addition we need some binaries that I have no sources
|
||||
for, yet, but that come with Tornado if and only if you
|
||||
INSTALL THE FULL PACKAGE (!)
|
||||
Including the 'WTX Test Suite i386/i486'
|
||||
(under "Select Sub-components" when installing Tornado)
|
||||
|
||||
You should find in your <Tornado>/host/x86-win32/bin dir:
|
||||
|
||||
awk, cat, cp, rm, mkdir
|
||||
|
||||
(There is also a bash and a GNU-make which are really poor,
|
||||
and WindRiver told me that they do not consider to support
|
||||
those in the future, so I no longer use them.)
|
||||
|
||||
2) set environment variables
|
||||
----------------------------
|
||||
|
||||
Your path should include:
|
||||
- The EPICS-binaries that we are about to build in base/bin/WIN32
|
||||
- The NTtools that you've built in step 1
|
||||
- The EPICS-binaries that we are about to build in <EPICS>base/bin/WIN32
|
||||
- The System (for me it's in NT40...)
|
||||
- The MS Visual C compiler binaries
|
||||
- The Tornado binaries
|
||||
|
||||
Check with e.g.:
|
||||
|
||||
/users/kay/Src/epics/nttools >echo $Path
|
||||
c:\users\kay\src\epics\base\bin\WIN32;c:\users\kay\src\epics\NTtools\bin;C:\NT40
|
||||
\system32;C:\NT40;c:\msdev\bin;C:\users\Tornado\host\x86-win32\bin
|
||||
>echo %Path%
|
||||
C:\WINNT35.0\system32;
|
||||
C:\WINNT35.0;
|
||||
c:\msdev\bin;
|
||||
c:\perl5\bin;
|
||||
c:\make-3.75\WinRel;
|
||||
c:\epics\base\bin\win32
|
||||
|
||||
On NT, $Path is defined by the operatin system, on Win95, it's $PATH instead.
|
||||
knts tries to use PATH and falls back on Path,
|
||||
what should wok on both systems.
|
||||
On NT, "Path" is defined by the operatin system, on Win95, it's "PATH" instead.
|
||||
|
||||
MS Visual C and Tornado should be installed properly with
|
||||
these env. variables set:
|
||||
|
||||
WIND_BASE=c:\usersTornado
|
||||
WIND_BASE=c:\Tornado
|
||||
WIND_HOST_TYPE=x86-win32
|
||||
|
||||
This way the EPICS makesystem can locate Tornado
|
||||
@@ -116,6 +86,7 @@ For EPICS, set:
|
||||
|
||||
# select host arch to build:
|
||||
HOST_ARCH=WIN32
|
||||
HOME=??? # if you use $(HOME)/EPICS_CONFIG
|
||||
|
||||
EPICS_CA_ADDR_LIST 128.165.32.255 (addr of WIN32 host)
|
||||
EPICS_CA_AUTO_CA_ADDR_LIST NO
|
||||
@@ -126,20 +97,13 @@ EPICS_CA_SERVER_PORT 5064
|
||||
EPICS_TS_MIN_WEST 420 (Germany: -120)
|
||||
|
||||
|
||||
To debug knts, set KNTS to 5:
|
||||
KNTS=5
|
||||
export KNTS
|
||||
|
||||
You should do this, however, only if you really want the debugging info.
|
||||
|
||||
|
||||
3) building EPICS
|
||||
-----------------
|
||||
|
||||
Prepare apx. 2 ltr. Tee and type:
|
||||
|
||||
cd <epics>/base
|
||||
gnumake
|
||||
make
|
||||
|
||||
Watch for errors and send them to me.
|
||||
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
#
|
||||
# supplement README for HP700 and Alpha OSF/1 builds
|
||||
# supplement README for HP700
|
||||
#
|
||||
# Johnny Tang 5-29-97
|
||||
#
|
||||
# M. Anderson and J. Tang
|
||||
|
||||
1. VxWorks 5.2 for HP-UX
|
||||
|
||||
- Directory permissions may not be correct across multiple machines, so a
|
||||
- Make sure that you have set VX_DIR and VX_GNU to your
|
||||
VxWorks root directory.
|
||||
|
||||
% chmod -R ugo+rw base extensions
|
||||
- Under $(VX_DIR), create a soft link:
|
||||
hp700.68k -> hp9700.68k
|
||||
|
||||
might be necessary.
|
||||
2. Modify base/config/CONFIG_SITE file
|
||||
|
||||
- ANSI=HPACC
|
||||
- STANDARD=HPCC
|
||||
- CPLUSPLUS=G++
|
||||
|
||||
3. HP native c++ compiler has problem to handle the head files
|
||||
in which a inline function is used in conjuction with template
|
||||
|
||||
base/src/cas, the portable CA server can't be compiled successfully
|
||||
because of the above limitation.
|
||||
|
||||
This problem can be resolved by spliting the function declarations
|
||||
from the inline code in the files in base/src/cxxTemplates.
|
||||
|
||||
@@ -12,6 +12,7 @@ RM =$(PERL) $(EPICS_BASE)/src/tools/rm.pl -f
|
||||
MKDIR=$(PERL) $(EPICS_BASE)/src/tools/mkdir.pl
|
||||
RMDIR=$(PERL) $(EPICS_BASE)/src/tools/rm.pl -rf
|
||||
CHMOD=echo
|
||||
WHAT=echo
|
||||
|
||||
# overrides defines in CONFIG_SITE that don't fit Tornado
|
||||
#
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
# Jeff eliminated many shell-lines in Makefile.*.
|
||||
#
|
||||
|
||||
# Set this to the UNIX-like shell that you have:
|
||||
#
|
||||
# it is now possible to just use the DOS shell
|
||||
#
|
||||
#SHELL=knts
|
||||
|
||||
# Use std path variables from ms
|
||||
HOME = $(HOMEDRIVE)$(HOMEPATH)
|
||||
@@ -24,10 +29,12 @@ BUILD_TYPE=Host
|
||||
#
|
||||
# optimize/debug flags
|
||||
#
|
||||
HOST_OPT = YES
|
||||
CXX_OPT_FLAGS_YES = -Ox
|
||||
# -Zi : included debugging info
|
||||
CXX_OPT_FLAGS_NO = -Zi
|
||||
HOST_OPT = YES
|
||||
# -Ox : maximum optimizations
|
||||
# -Wn ; use this warning level (all warnings at level 4)
|
||||
CXX_OPT_FLAGS_YES = -Ox -W1
|
||||
# -Zi : include debugging info in object files
|
||||
CXX_OPT_FLAGS_NO = -Zi -W1
|
||||
CXX_OPT_FLAGS = $(CXX_OPT_FLAGS_$(HOST_OPT))
|
||||
LINK_OPT_FLAGS_YES =
|
||||
LINK_OPT_FLAGS_NO = -debug
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# CONFIG.Unix.alpha
|
||||
# CONFIG.alpha
|
||||
#
|
||||
# This file is maintained by the EPICS community.
|
||||
|
||||
@@ -24,7 +24,7 @@ RANLIB = ranlib
|
||||
YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = cc
|
||||
CCC = cxx
|
||||
|
||||
CP=cp
|
||||
MV = mv
|
||||
@@ -136,7 +136,7 @@ COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c
|
||||
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c
|
||||
# Unlike the 'Unix' makesystem, output flags -o .. are now part of LINK.c[c]
|
||||
LINK.c = $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
LINK.cc = $(CXX) -o $@ $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
LINK.cc = $(CCC) -o $@ $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
|
||||
DEPEND_RULE.c = @echo no DEPENDS_RULE.c defined in CONFIG.alpha
|
||||
DEPEND_RULE.cc = @echo no DEPENDS_RULE.cc defined in CONFIG.alpha
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# BUILD_TYPE
|
||||
# Currently either Vx or Unix
|
||||
BUILD_TYPE = Unix
|
||||
BUILD_TYPE = Host
|
||||
|
||||
ARCH_CLASS = hp700
|
||||
|
||||
@@ -25,7 +25,7 @@ LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = CC
|
||||
|
||||
CP=cp
|
||||
CP = cp
|
||||
MV = mv
|
||||
RM=rm -f
|
||||
RMDIR = rm -rf
|
||||
@@ -137,8 +137,8 @@ LDLIBS = $(TARGET_LDLIBS) $(USR_LDLIBS) $(ARCH_DEP_LDLIBS) $(UNIX_LDLIBS)
|
||||
# Override defaults
|
||||
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) -c
|
||||
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c
|
||||
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
LINK.c = $(CC) -o $@ $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
LINK.cc = $(CXX) -o $@ $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
DEPENDS_RULE.c = @echo no DEPENDS_RULE.c defined in CONFIG.hp700
|
||||
DEPENDS_RULE.cc = @echo no DEPENDS_RULE.cc defined in CONFIG.hp700
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<<<<<<< CONFIG.pc486
|
||||
#
|
||||
# no longer required
|
||||
#
|
||||
#SHELL=knts
|
||||
=======
|
||||
>>>>>>> 1.3
|
||||
|
||||
# BUILD_TYPE
|
||||
# Currently either Vx or Unix
|
||||
|
||||
@@ -11,7 +11,7 @@ EPICS_VERSION=3
|
||||
EPICS_REVISION=13
|
||||
EPICS_MODIFICATION=0
|
||||
EPICS_UPDATE_NAME=beta
|
||||
EPICS_UPDATE_LEVEL=9
|
||||
EPICS_UPDATE_LEVEL=10
|
||||
|
||||
EPICS_VERSION_STRING="EPICS Version ${EPICS_VERSION}.${EPICS_REVISION}.${EPICS_MODIFICATION}.${EPICS_UPDATE_NAME}${EPICS_UPDATE_LEVEL}"
|
||||
|
||||
|
||||
@@ -63,10 +63,11 @@ EPICS_CAS_SERVER_PORT=
|
||||
|
||||
|
||||
# Log Server:
|
||||
# EPICS_IOC_LOG_PORT Log server port number.
|
||||
|
||||
# EPICS_IOC_LOG_PORT Log server port number etc.
|
||||
EPICS_IOC_LOG_PORT=7004
|
||||
|
||||
#EPICS_IOC_LOG_INET=""
|
||||
#EPICS_IOC_LOG_FILE_LIMIT=100000
|
||||
#EPICS_IOC_LOG_FILE_NAME=/a/b/c/d/iocs.log
|
||||
|
||||
# Other services:
|
||||
|
||||
|
||||
@@ -47,16 +47,17 @@ CROSS_COMPILER_TARGET_ARCHS=mv167
|
||||
#CROSS_COMPILER_HOST_ARCHS=sun4
|
||||
|
||||
# VxWorks directory
|
||||
#VX_DIR=/usr/csite/vw/5.1.1/vw
|
||||
#VX_DIR=$(VW)
|
||||
#VX_DIR=/usr/local/vw/vxV51.mm
|
||||
#VX_DIR=/usr/local/vw/vxV52/vw
|
||||
VX_DIR=/usr/local/vw/vxV52p1/vw
|
||||
|
||||
# Gnu directory for gcc
|
||||
#VX_GNU = $(VX_DIR)
|
||||
#VX_GNU = $(VX_GNU)
|
||||
VX_GNU = $(VX_DIR)/../vxgccV2.2.3.1
|
||||
|
||||
# Gnu directory for g++
|
||||
#GNU_DIR = $(LOCAL_GNU)
|
||||
GNU_DIR = /usr/local/hideos/gnu_install-2.7.2
|
||||
GNU_BIN = $(GNU_DIR)/bin
|
||||
GNU_LIB = $(GNU_DIR)/lib
|
||||
@@ -80,6 +81,7 @@ STANDARD=ACC
|
||||
# G++ (g++) GNU C++
|
||||
# CCC (CC) OS VENDOR C++
|
||||
#CPLUSPLUS=G++
|
||||
#Note: if CPLUSPLUS is empty then C++ src codes are not built
|
||||
#CPLUSPLUS= # use this if site does not have C++ compiler
|
||||
CPLUSPLUS=CCC
|
||||
|
||||
|
||||
@@ -11,40 +11,14 @@ CONFIGS += CONFIG_BASE_VERSION
|
||||
CONFIGS += CONFIG_COMMON
|
||||
CONFIGS += CONFIG_ENV
|
||||
|
||||
CONFIGS += CONFIG.WIN32
|
||||
CONFIGS += CONFIG.pc486
|
||||
CONFIGS += CONFIG.Linux
|
||||
CONFIGS += CONFIG.alpha
|
||||
CONFIGS += CONFIG.hp700
|
||||
CONFIGS += CONFIG.sgi
|
||||
CONFIGS += CONFIG.solaris
|
||||
CONFIGS += CONFIG.sun4
|
||||
CONFIGS += CONFIG.hkv2f
|
||||
CONFIGS += CONFIG.mv147
|
||||
CONFIGS += CONFIG.mv162
|
||||
CONFIGS += CONFIG.mv162lc
|
||||
CONFIGS += CONFIG.mv167
|
||||
CONFIGS += CONFIG.niCpu030
|
||||
CONFIGS += $(BUILD_ARCHS:%=CONFIG.%)
|
||||
|
||||
CONFIGS += CONFIG.Vx.68k
|
||||
|
||||
CONFIGS += CONFIG_SITE
|
||||
CONFIGS += CONFIG_SITE_ENV
|
||||
|
||||
CONFIGS += CONFIG_SITE.WIN32
|
||||
CONFIGS += CONFIG_SITE.pc486
|
||||
CONFIGS += CONFIG_SITE.Linux
|
||||
CONFIGS += CONFIG_SITE.alpha
|
||||
CONFIGS += CONFIG_SITE.hp700
|
||||
CONFIGS += CONFIG_SITE.sgi
|
||||
CONFIGS += CONFIG_SITE.solaris
|
||||
CONFIGS += CONFIG_SITE.sun4
|
||||
CONFIGS += CONFIG_SITE.hkv2f
|
||||
CONFIGS += CONFIG_SITE.mv147
|
||||
CONFIGS += CONFIG_SITE.mv162lc
|
||||
CONFIGS += CONFIG_SITE.mv162
|
||||
CONFIGS += CONFIG_SITE.mv167
|
||||
CONFIGS += CONFIG_SITE.niCpu030
|
||||
CONFIGS += $(BUILD_ARCHS:%=CONFIG_SITE.%)
|
||||
|
||||
CONFIGS += RULES.Host
|
||||
CONFIGS += RULES.Vx
|
||||
|
||||
@@ -407,21 +407,20 @@ endif
|
||||
@$(RM) $@
|
||||
$(COMPILE.cc) $<
|
||||
|
||||
%.c %.h: ../%.y
|
||||
@$(RM) y.tab.c y.tab.h
|
||||
#
|
||||
# rename the y.tab.h file only if we
|
||||
# are creating it
|
||||
#
|
||||
%.h %.c: ../%.y
|
||||
$(RM) $*.c y.tab.c
|
||||
ifeq ($(findstring -d, $(YACCOPT)),-d)
|
||||
$(RM) $*.h y.tab.h
|
||||
endif
|
||||
$(YACC) $(YACCOPT) $<
|
||||
@if [ -f y.tab.c ]; \
|
||||
then \
|
||||
echo "$(MV) y.tab.c $*.c"; \
|
||||
$(RM) $*.c; \
|
||||
$(MV) y.tab.c $*.c; \
|
||||
fi
|
||||
@if [ -f y.tab.h ]; \
|
||||
then \
|
||||
echo "$(MV) y.tab.h $*.h"; \
|
||||
$(RM) $*.h; \
|
||||
$(MV) y.tab.h $*.h; \
|
||||
fi
|
||||
$(MV) y.tab.c $*.c
|
||||
ifeq ($(findstring -d, $(YACCOPT)),-d)
|
||||
$(MV) y.tab.h $*.h
|
||||
endif
|
||||
|
||||
%.c: ../%.l
|
||||
@$(RM) lex.yy.c
|
||||
|
||||
@@ -104,19 +104,20 @@ $(DIRECTORY_TARGETS) :
|
||||
$(RM) $@
|
||||
$(COMPILE.cc) $<
|
||||
|
||||
%.c: ../%.y
|
||||
$(RM) y.tab.c y.tab.h
|
||||
#
|
||||
# rename the y.tab.h file only if we
|
||||
# are creating it
|
||||
#
|
||||
%.h %.c: ../%.y
|
||||
$(RM) $*.c y.tab.c
|
||||
ifeq ($(findstring -d, $(YACCOPT)),-d)
|
||||
$(RM) $*.h y.tab.h
|
||||
endif
|
||||
$(YACC) $(YACCOPT) $<
|
||||
@if [ -f y.tab.c ]; \
|
||||
then \
|
||||
echo "$(MV) y.tab.c $*.c"; \
|
||||
$(MV) y.tab.c $*.c; \
|
||||
fi
|
||||
@if [ -f y.tab.h ]; \
|
||||
then \
|
||||
echo "$(MV) y.tab.h $*.h"; \
|
||||
$(MV) y.tab.h $*.h; \
|
||||
fi
|
||||
$(MV) y.tab.c $*.c
|
||||
ifeq ($(findstring -d, $(YACCOPT)),-d)
|
||||
$(MV) y.tab.h $*.h
|
||||
endif
|
||||
|
||||
%.c: ../%.l
|
||||
$(RM) lex.yy.c
|
||||
|
||||
@@ -26,7 +26,9 @@ ifndef WIN32
|
||||
ln -s $(TARGETBIN)/vxWorks vxWorks
|
||||
ln -s $(TARGETBIN)/vxWorks.sym vxWorks.sym
|
||||
ln -s $(TOP)/dbd dbd
|
||||
ifdef SHARE
|
||||
ln -s $(SHARE) share
|
||||
endif
|
||||
@for dir in $(APPDIR) scum ; do \
|
||||
if [ $$dir = scum ]; then \
|
||||
: ; \
|
||||
|
||||
@@ -51,12 +51,17 @@ $(crossActionArchTargets) :
|
||||
$(crossArchs) :
|
||||
endif
|
||||
|
||||
$(hostDirs) :
|
||||
$(hostDirs) : $(EPICS_BASE)/config/makeMakefile.pl
|
||||
$(PERL) $(EPICS_BASE)/config/makeMakefile.pl $@ $(BUILD_TYPE)
|
||||
|
||||
$(crossDirs) :
|
||||
$(crossDirs) : $(EPICS_BASE)/config/makeMakefile.pl
|
||||
$(PERL) $(EPICS_BASE)/config/makeMakefile.pl $@ Vx
|
||||
|
||||
ifneq ($(EPICS_BASE),$(TOP))
|
||||
$(EPICS_BASE)/config/makeMakefile.pl : $(TOP)/config/makeMakefile.pl
|
||||
$(CP) $(TOP)/config/makeMakefile.pl $(EPICS_BASE)/config/makeMakefile.pl
|
||||
endif
|
||||
|
||||
#
|
||||
# host/cross action targets
|
||||
#
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
/************************************************************************/
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.94 1997/05/05 04:40:29 jhill
|
||||
* send_needed replaced by pushPending flag
|
||||
*
|
||||
* Revision 1.93 1997/04/29 06:05:57 jhill
|
||||
* use free list
|
||||
*
|
||||
@@ -636,10 +639,10 @@ LOCAL void cac_add_msg (IIU *piiu)
|
||||
int epicsShareAPI ca_task_initialize(void)
|
||||
{
|
||||
int status;
|
||||
struct ca_static *ca_temp;
|
||||
struct CA_STATIC *ca_temp;
|
||||
|
||||
if (!ca_static) {
|
||||
ca_temp = (struct ca_static *)
|
||||
ca_temp = (struct CA_STATIC *)
|
||||
calloc(1, sizeof(*ca_temp));
|
||||
if (!ca_temp) {
|
||||
return ECA_ALLOCMEM;
|
||||
@@ -691,7 +694,13 @@ int ca_os_independent_init (void)
|
||||
* init broadcasted search counters
|
||||
* (current time must be initialized before calling this)
|
||||
*/
|
||||
cacClrSearchCounters();
|
||||
ca_static->ca_search_responses = 0u;
|
||||
ca_static->ca_search_tries = 0u;
|
||||
ca_static->ca_search_retry_seq_no = 0u;
|
||||
ca_static->ca_seq_no_at_list_begin = 0u;
|
||||
ca_static->ca_frames_per_try = TRIESPERFRAME;
|
||||
ca_static->ca_conn_next_retry = ca_static->currentTime;
|
||||
cacSetRetryInterval (0u);
|
||||
|
||||
ellInit(&ca_static->ca_iiuList);
|
||||
ellInit(&ca_static->ca_ioeventlist);
|
||||
@@ -759,7 +768,6 @@ 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;
|
||||
@@ -1154,8 +1162,8 @@ int epicsShareAPI ca_search_and_connect
|
||||
/*
|
||||
* reset broadcasted search counters
|
||||
*/
|
||||
cacClrSearchCounters();
|
||||
|
||||
ca_static->ca_conn_next_retry = ca_static->currentTime;
|
||||
cacSetRetryInterval (0u);
|
||||
UNLOCK;
|
||||
|
||||
/*
|
||||
@@ -1726,7 +1734,7 @@ LOCAL void ca_put_notify_action(PUTNOTIFY *ppn)
|
||||
{
|
||||
CACLIENTPUTNOTIFY *pcapn;
|
||||
struct ioc_in_use *piiu;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
chid chix;
|
||||
|
||||
/*
|
||||
@@ -3589,7 +3597,7 @@ int ca_channel_status(int tid)
|
||||
{
|
||||
chid chix;
|
||||
IIU *piiu;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
|
||||
pcas = (struct ca_static *)
|
||||
taskVarGet(tid, (int *)&ca_static);
|
||||
|
||||
@@ -7,6 +7,9 @@ static char *sccsId = "@(#) $Id$";
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.45 1997/04/29 06:07:16 jhill
|
||||
* local host connect compatible
|
||||
*
|
||||
* Revision 1.44 1997/04/10 19:26:05 jhill
|
||||
* asynch connect, faster connect, ...
|
||||
*
|
||||
@@ -100,6 +103,7 @@ void write_event(struct event_handler_args args);
|
||||
void conn(struct connection_handler_args args);
|
||||
void get_cb(struct event_handler_args args);
|
||||
void accessSecurity_cb(struct access_rights_handler_args args);
|
||||
void pend_event_delay_test(dbr_double_t request);
|
||||
|
||||
void doubleTest(
|
||||
chid chan,
|
||||
@@ -179,26 +183,12 @@ int doacctst(char *pname)
|
||||
|
||||
/*
|
||||
* CA pend event delay accuracy test
|
||||
* (CA asssumes that search requests can be sent
|
||||
* at least every 25 mS on all supported os)
|
||||
*/
|
||||
{
|
||||
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 (fabs(accuracy) < 10.0);
|
||||
}
|
||||
pend_event_delay_test(1.0);
|
||||
pend_event_delay_test(0.1);
|
||||
pend_event_delay_test(0.25);
|
||||
|
||||
size = dbr_size_n(DBR_GR_FLOAT, NUM);
|
||||
ptr = (struct dbr_gr_float *) malloc(size);
|
||||
@@ -974,6 +964,30 @@ int doacctst(char *pname)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* pend_event_delay_test()
|
||||
*/
|
||||
void pend_event_delay_test(dbr_double_t request)
|
||||
{
|
||||
int status;
|
||||
TS_STAMP end_time;
|
||||
TS_STAMP start_time;
|
||||
dbr_double_t delay;
|
||||
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 = %f sec results in accuracy = %f %%\n",
|
||||
request, accuracy);
|
||||
assert (fabs(accuracy) < 10.0);
|
||||
}
|
||||
|
||||
void floatTest(
|
||||
chid chan,
|
||||
dbr_float_t beginValue,
|
||||
|
||||
@@ -127,17 +127,16 @@ int cac_select_io(struct timeval *ptimeout, int flags)
|
||||
piiu->recvPending = FALSE;
|
||||
}
|
||||
|
||||
if (flags&CA_DO_SENDS || piiu->pushPending) {
|
||||
if (piiu->state==iiu_connecting) {
|
||||
if (piiu->state==iiu_connecting) {
|
||||
FD_SET (piiu->sock_chan, &pfdi->writeMask);
|
||||
ioPending = TRUE;
|
||||
}
|
||||
else if (flags&CA_DO_SENDS || piiu->pushPending) {
|
||||
if (cacRingBufferReadSize(&piiu->send, FALSE)>0) {
|
||||
maxfd = max (maxfd,piiu->sock_chan);
|
||||
FD_SET (piiu->sock_chan, &pfdi->writeMask);
|
||||
ioPending = TRUE;
|
||||
}
|
||||
else {
|
||||
if (cacRingBufferReadSize(&piiu->send, FALSE)>0) {
|
||||
maxfd = max (maxfd,piiu->sock_chan);
|
||||
FD_SET (piiu->sock_chan, &pfdi->writeMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UNLOCK;
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1997/01/22 21:08:17 jhill
|
||||
* removed use of ## for VAXC port
|
||||
*
|
||||
* Revision 1.2 1996/09/16 16:32:49 jhill
|
||||
* added CA version string
|
||||
*
|
||||
@@ -68,6 +71,9 @@
|
||||
*
|
||||
* .10 050594 joh New command added for CA V4.3 - wakeup the server
|
||||
* $Log$
|
||||
* Revision 1.3 1997/01/22 21:08:17 jhill
|
||||
* removed use of ## for VAXC port
|
||||
*
|
||||
* Revision 1.2 1996/09/16 16:32:49 jhill
|
||||
* added CA version string
|
||||
*
|
||||
@@ -87,8 +93,8 @@
|
||||
* TCP/UDP port number (bumped each major protocol change)
|
||||
*/
|
||||
#define CA_PROTOCOL_VERSION 4u
|
||||
#define CA_MINOR_VERSION 7u
|
||||
#define CA_VERSION_STRING "4.7"
|
||||
#define CA_MINOR_VERSION 8u
|
||||
#define CA_VERSION_STRING "4.8"
|
||||
#define CA_UKN_MINOR_VERSION 0u /* unknown minor version */
|
||||
#if CA_PROTOCOL_VERSION == 4u
|
||||
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1u)
|
||||
@@ -98,6 +104,7 @@
|
||||
#define CA_V45(MAJOR,MINOR) ((MINOR)>=5u)
|
||||
#define CA_V46(MAJOR,MINOR) ((MINOR)>=6u)
|
||||
#define CA_V47(MAJOR,MINOR) ((MINOR)>=7u)
|
||||
#define CA_V48(MAJOR,MINOR) ((MINOR)>=8u)
|
||||
#elif CA_PROTOCOL_VERSION > 4u
|
||||
#define CA_V41(MAJOR,MINOR) ( 1u )
|
||||
#define CA_V42(MAJOR,MINOR) ( 1u )
|
||||
@@ -106,6 +113,7 @@
|
||||
#define CA_V45(MAJOR,MINOR) ( 1u )
|
||||
#define CA_V46(MAJOR,MINOR) ( 1u )
|
||||
#define CA_V47(MAJOR,MINOR) ( 1u )
|
||||
#define CA_V48(MAJOR,MINOR) ( 1u )
|
||||
#else
|
||||
#define CA_V41(MAJOR,MINOR) ( 0u )
|
||||
#define CA_V42(MAJOR,MINOR) ( 0u )
|
||||
@@ -114,6 +122,7 @@
|
||||
#define CA_V45(MAJOR,MINOR) ( 0u )
|
||||
#define CA_V46(MAJOR,MINOR) ( 0u )
|
||||
#define CA_V47(MAJOR,MINOR) ( 0u )
|
||||
#define CA_V48(MAJOR,MINOR) ( 0u )
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -190,22 +190,25 @@ typedef void caArh(struct access_rights_handler_args args);
|
||||
typedef void caArh();
|
||||
#endif /*CAC_ANSI_FUNC_PROTO*/
|
||||
|
||||
/*
|
||||
* The fields in this structure may change or even vanish in the future.
|
||||
* Please use the macros above to access the information in this structure.
|
||||
*/
|
||||
struct channel_in_use{
|
||||
ELLNODE node; /* list ptrs */
|
||||
short type; /* database field type */
|
||||
#define TYPENOTCONN (-1) /* the type when disconnected */
|
||||
unsigned short count; /* array element count */
|
||||
ELLNODE node; /* list ptrs */
|
||||
short type; /* database field type */
|
||||
#define TYPENOTCONN (-1) /* the type when disconnected */
|
||||
unsigned short count; /* array element count */
|
||||
union{
|
||||
unsigned sid; /* server id */
|
||||
struct dbAddr *paddr; /* database address */
|
||||
unsigned sid; /* server id */
|
||||
struct dbAddr *paddr; /* database address */
|
||||
} id;
|
||||
const void *puser; /* user available area */
|
||||
enum channel_state state; /* connected/ disconnected etc */
|
||||
caar ar; /* access rights */
|
||||
const void *puser; /* user available area */
|
||||
short state; /* connected/ disconnected etc */
|
||||
unsigned short retrySeqNo; /* search retry seq number */
|
||||
caar ar; /* access rights */
|
||||
|
||||
|
||||
/*
|
||||
* The following fields may change or even vanish in the future
|
||||
*/
|
||||
caCh *pConnFunc;
|
||||
caArh *pAccessRightsFunc;
|
||||
ELLLIST eventq;
|
||||
|
||||
@@ -142,7 +142,7 @@ int catime (char *channelName, enum appendNumberFlag appNF)
|
||||
itemList[i].name[strsize]= '\0';
|
||||
itemList[i].count = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf ("sync search test\n");
|
||||
assert (100u<=NELEMENTS(itemList));
|
||||
timeIt (test_sync_search, itemList, 100u);
|
||||
@@ -155,7 +155,7 @@ int catime (char *channelName, enum appendNumberFlag appNF)
|
||||
fflush (stdout);
|
||||
ca_pend_event(1.0);
|
||||
printf ("hopefully done\n");
|
||||
|
||||
#endif
|
||||
printf ("search test\n");
|
||||
timeIt (test_search, itemList, NELEMENTS(itemList));
|
||||
printSearchStat(NELEMENTS(itemList));
|
||||
|
||||
149
src/ca/conn.c
149
src/ca/conn.c
@@ -30,6 +30,9 @@
|
||||
/* (dont send all chans in a block) */
|
||||
/* */
|
||||
/* $Log$
|
||||
* Revision 1.38 1997/04/10 19:26:09 jhill
|
||||
* asynch connect, faster connect, ...
|
||||
*
|
||||
* Revision 1.37 1996/11/02 00:50:46 jhill
|
||||
* many pc port, const in API, and other changes
|
||||
*
|
||||
@@ -67,6 +70,7 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno);
|
||||
#endif
|
||||
|
||||
LOCAL void retrySearchRequest();
|
||||
LOCAL unsigned bhtHashIP(const struct sockaddr_in *pina);
|
||||
|
||||
|
||||
/*
|
||||
@@ -232,6 +236,11 @@ LOCAL void retrySearchRequest ()
|
||||
}
|
||||
|
||||
LOCK;
|
||||
|
||||
/*
|
||||
* increment the retry sequence number
|
||||
*/
|
||||
ca_static->ca_search_retry_seq_no++; /* allowed to roll over */
|
||||
|
||||
/*
|
||||
* dynamically adjust the number of UDP frames per
|
||||
@@ -265,7 +274,7 @@ LOCAL void retrySearchRequest ()
|
||||
/*
|
||||
* double UDP frames per try if we have a good score
|
||||
*/
|
||||
if (ca_static->ca_frames_per_try < (UINT_MAX/2u) ) {
|
||||
if (ca_static->ca_frames_per_try < (UINT_MAX/4u) ) {
|
||||
ca_static->ca_frames_per_try += ca_static->ca_frames_per_try;
|
||||
#ifdef DEBUG
|
||||
printf ("Increasing frame count to %u t=%u r=%u\n",
|
||||
@@ -309,11 +318,31 @@ LOCAL void retrySearchRequest ()
|
||||
if (ca_static->ca_search_responses==0u) {
|
||||
cacSetRetryInterval(ca_static->ca_min_retry+1u);
|
||||
}
|
||||
else {
|
||||
ca_static->ca_search_responses=0u;
|
||||
}
|
||||
ca_static->ca_search_tries = 0u;
|
||||
|
||||
ca_static->ca_min_retry = UINT_MAX;
|
||||
|
||||
/*
|
||||
* increment the retry sequence number
|
||||
* (this prevents the time of the next search
|
||||
* try from being set to the current time if
|
||||
* we are handling a response from an old
|
||||
* search message)
|
||||
*/
|
||||
ca_static->ca_search_retry_seq_no++; /* allowed to roll over */
|
||||
|
||||
/*
|
||||
* so that old search tries will not update the counters
|
||||
*/
|
||||
ca_static->ca_seq_no_at_list_begin = ca_static->ca_search_retry_seq_no;
|
||||
/*
|
||||
* keeps the search try/response counters in bounds
|
||||
* (but keep some of the info from the previous iteration)
|
||||
*/
|
||||
ca_static->ca_search_responses = ca_static->ca_search_responses/16u;
|
||||
ca_static->ca_search_tries = ca_static->ca_search_tries/16u;
|
||||
#ifdef DEBUG
|
||||
printf ("saw end of list\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -324,6 +353,10 @@ LOCAL void retrySearchRequest ()
|
||||
if (status != ECA_NORMAL) {
|
||||
nSent++;
|
||||
|
||||
if (nSent>=ca_static->ca_frames_per_try) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* flush out the search request buffer
|
||||
*/
|
||||
@@ -337,11 +370,7 @@ LOCAL void retrySearchRequest ()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nSent>=ca_static->ca_frames_per_try) {
|
||||
break;
|
||||
}
|
||||
|
||||
chan->retrySeqNo = ca_static->ca_search_retry_seq_no;
|
||||
chan = (ciu) ellFirst (&piiuCast->chidlist);
|
||||
|
||||
/*
|
||||
@@ -374,19 +403,13 @@ LOCAL void retrySearchRequest ()
|
||||
&ca_static->currentTime,
|
||||
&ca_static->ca_conn_retry_delay);
|
||||
LOGRETRYINTERVAL
|
||||
}
|
||||
|
||||
/*
|
||||
* cacClrSearchCounters()
|
||||
* (reset broadcasted search counters)
|
||||
*/
|
||||
void cacClrSearchCounters()
|
||||
{
|
||||
ca_static->ca_search_responses = 0u;
|
||||
ca_static->ca_search_tries = 0;
|
||||
ca_static->ca_frames_per_try = TRIESPERFRAME;
|
||||
ca_static->ca_conn_next_retry = ca_static->currentTime;
|
||||
cacSetRetryInterval(0u);
|
||||
#ifdef DEBUG
|
||||
printf("sent %u at cur sec=%u cur usec=%u delay sec=%u delay usec = %u\n",
|
||||
nSent, ca_static->currentTime.tv_sec,
|
||||
ca_static->currentTime.tv_usec,
|
||||
ca_static->ca_conn_retry_delay.tv_sec,
|
||||
ca_static->ca_conn_retry_delay.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -398,18 +421,11 @@ void cacSetRetryInterval(unsigned retryNo)
|
||||
long idelay;
|
||||
ca_real delay;
|
||||
|
||||
/*
|
||||
* NOOP if no change
|
||||
*/
|
||||
if (ca_static->ca_search_retry == retryNo) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the retry interval
|
||||
*/
|
||||
retryNo = min(retryNo, CHAR_BIT*sizeof(idelay)-1);
|
||||
ca_static->ca_search_retry = retryNo;
|
||||
assert(ca_static->ca_search_retry < CHAR_BIT*sizeof(idelay));
|
||||
idelay = 1;
|
||||
idelay = idelay << ca_static->ca_search_retry;
|
||||
delay = idelay * CA_RECAST_DELAY; /* sec */
|
||||
@@ -418,6 +434,11 @@ void cacSetRetryInterval(unsigned retryNo)
|
||||
ca_static->ca_conn_retry_delay.tv_sec = idelay;
|
||||
ca_static->ca_conn_retry_delay.tv_usec =
|
||||
(long) ((delay-idelay)*USEC_PER_SEC);
|
||||
#if 0
|
||||
printf ("new search period is %u sec %u usec\n",
|
||||
ca_static->ca_conn_retry_delay.tv_sec,
|
||||
ca_static->ca_conn_retry_delay.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -454,7 +475,7 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno)
|
||||
/*
|
||||
* MARK_SERVER_AVAILABLE
|
||||
*/
|
||||
void mark_server_available(const struct in_addr *pnet_addr)
|
||||
void mark_server_available(const struct sockaddr_in *pnet_addr)
|
||||
{
|
||||
ciu chan;
|
||||
ca_real currentPeriod;
|
||||
@@ -527,7 +548,7 @@ void mark_server_available(const struct in_addr *pnet_addr)
|
||||
#ifdef DEBUG
|
||||
ca_printf(
|
||||
"new server at %x cur=%f avg=%f\n",
|
||||
pnet_addr->s_addr,
|
||||
pnet_addr->sin_addr.s_addr,
|
||||
currentPeriod,
|
||||
pBHE->averagePeriod);
|
||||
#endif
|
||||
@@ -549,7 +570,7 @@ void mark_server_available(const struct in_addr *pnet_addr)
|
||||
#ifdef DEBUG
|
||||
ca_printf(
|
||||
"net resume seen %x cur=%f avg=%f\n",
|
||||
pnet_addr->s_addr,
|
||||
pnet_addr->sin_addr.s_addr,
|
||||
currentPeriod,
|
||||
pBHE->averagePeriod);
|
||||
#endif
|
||||
@@ -563,7 +584,7 @@ void mark_server_available(const struct in_addr *pnet_addr)
|
||||
#ifdef DEBUG
|
||||
ca_printf(
|
||||
"reboot seen %x cur=%f avg=%f\n",
|
||||
pnet_addr->s_addr,
|
||||
pnet_addr->sin_addr.s_addr,
|
||||
currentPeriod,
|
||||
pBHE->averagePeriod);
|
||||
#endif
|
||||
@@ -658,20 +679,17 @@ void mark_server_available(const struct in_addr *pnet_addr)
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr, unsigned sawBeacon)
|
||||
bhe *createBeaconHashEntry(const struct sockaddr_in *pina, unsigned sawBeacon)
|
||||
{
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
|
||||
pBHE = lookupBeaconInetAddr(pnet_addr);
|
||||
pBHE = lookupBeaconInetAddr(pina);
|
||||
if(pBHE){
|
||||
return pBHE;
|
||||
}
|
||||
|
||||
index = ntohl(pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
|
||||
assert(index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
index = bhtHashIP(pina);
|
||||
|
||||
pBHE = (bhe *)calloc(1,sizeof(*pBHE));
|
||||
if(!pBHE){
|
||||
@@ -679,13 +697,13 @@ bhe *createBeaconHashEntry(const struct in_addr *pnet_addr, unsigned sawBeacon)
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
ca_printf("new beacon at %x\n", pnet_addr->s_addr);
|
||||
ca_printf("new beacon at %x %u\n", pina->sin_addr.s_addr, pina->sin_port);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* store the inet address
|
||||
*/
|
||||
pBHE->inetAddr = *pnet_addr;
|
||||
pBHE->inetAddr = *pina;
|
||||
|
||||
/*
|
||||
* set average to -1.0 so that when the next beacon
|
||||
@@ -727,19 +745,17 @@ bhe *createBeaconHashEntry(const struct in_addr *pnet_addr, unsigned sawBeacon)
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
bhe *lookupBeaconInetAddr (const struct in_addr *pnet_addr)
|
||||
bhe *lookupBeaconInetAddr (const struct sockaddr_in *pina)
|
||||
{
|
||||
bhe *pBHE;
|
||||
unsigned index;
|
||||
|
||||
index = ntohl(pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
|
||||
assert(index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
index = bhtHashIP(pina);
|
||||
|
||||
pBHE = ca_static->ca_beaconHash[index];
|
||||
while(pBHE){
|
||||
if(pBHE->inetAddr.s_addr == pnet_addr->s_addr){
|
||||
while (pBHE) {
|
||||
if ( pBHE->inetAddr.sin_addr.s_addr == pina->sin_addr.s_addr &&
|
||||
pBHE->inetAddr.sin_port == pina->sin_port) {
|
||||
break;
|
||||
}
|
||||
pBHE = pBHE->pNext;
|
||||
@@ -754,21 +770,19 @@ bhe *lookupBeaconInetAddr (const struct in_addr *pnet_addr)
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
void removeBeaconInetAddr (const struct in_addr *pnet_addr)
|
||||
void removeBeaconInetAddr (const struct sockaddr_in *pina)
|
||||
{
|
||||
bhe *pBHE;
|
||||
bhe **ppBHE;
|
||||
unsigned index;
|
||||
|
||||
index = ntohl (pnet_addr->s_addr);
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
|
||||
assert (index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
index = bhtHashIP(pina);
|
||||
|
||||
ppBHE = &ca_static->ca_beaconHash[index];
|
||||
pBHE = *ppBHE;
|
||||
while (pBHE) {
|
||||
if (pBHE->inetAddr.s_addr == pnet_addr->s_addr) {
|
||||
if ( pBHE->inetAddr.sin_addr.s_addr == pina->sin_addr.s_addr &&
|
||||
pBHE->inetAddr.sin_port == pina->sin_port) {
|
||||
*ppBHE = pBHE->pNext;
|
||||
free (pBHE);
|
||||
return;
|
||||
@@ -779,13 +793,34 @@ void removeBeaconInetAddr (const struct in_addr *pnet_addr)
|
||||
assert (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* bhtHashIP()
|
||||
*/
|
||||
LOCAL unsigned bhtHashIP(const struct sockaddr_in *pina)
|
||||
{
|
||||
unsigned index;
|
||||
|
||||
#if BHT_INET_ADDR_MASK != 0xff
|
||||
# error BHT_INET_ADDR_MASK changed - recode this routine !
|
||||
#endif
|
||||
|
||||
index = pina->sin_addr.s_addr;
|
||||
index ^= pina->sin_port;
|
||||
index = (index>>16u) ^ index;
|
||||
index = (index>>8u) ^ index;
|
||||
index &= BHT_INET_ADDR_MASK;
|
||||
assert(index<NELEMENTS(ca_static->ca_beaconHash));
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* freeBeaconHash()
|
||||
*
|
||||
* LOCK must be applied
|
||||
*/
|
||||
void freeBeaconHash(struct ca_static *ca_temp)
|
||||
void freeBeaconHash(struct CA_STATIC *ca_temp)
|
||||
{
|
||||
bhe *pBHE;
|
||||
bhe **ppBHE;
|
||||
|
||||
@@ -95,7 +95,7 @@ LOCAL CACVRTFUNC cvrt_put_ackt;
|
||||
LOCAL CACVRTFUNC cvrt_stsack_string;
|
||||
|
||||
/* cvrt is (array of) (pointer to) (function returning) int */
|
||||
CACVRTFUNC *cac_dbr_cvrt[]
|
||||
epicsShareDef CACVRTFUNC *cac_dbr_cvrt[]
|
||||
=
|
||||
{
|
||||
cvrt_string,
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
/* address in use so that test works on UNIX */
|
||||
/* kernels that support multicast */
|
||||
/* $Log$
|
||||
* Revision 1.70 1997/05/05 04:44:39 jhill
|
||||
* socket buf matches CA buf size, and pushPending flag added
|
||||
*
|
||||
* Revision 1.69 1997/04/23 17:05:05 jhill
|
||||
* pc port changes
|
||||
*
|
||||
@@ -133,9 +136,8 @@ LOCAL void close_ioc (IIU *piiu);
|
||||
*
|
||||
*/
|
||||
int alloc_ioc(
|
||||
const struct in_addr *pnet_addr,
|
||||
unsigned short port,
|
||||
struct ioc_in_use **ppiiu
|
||||
const struct sockaddr_in *pina,
|
||||
struct ioc_in_use **ppiiu
|
||||
)
|
||||
{
|
||||
int status;
|
||||
@@ -145,9 +147,9 @@ struct ioc_in_use **ppiiu
|
||||
* look for an existing connection
|
||||
*/
|
||||
LOCK;
|
||||
pBHE = lookupBeaconInetAddr(pnet_addr);
|
||||
pBHE = lookupBeaconInetAddr(pina);
|
||||
if(!pBHE){
|
||||
pBHE = createBeaconHashEntry(pnet_addr, FALSE);
|
||||
pBHE = createBeaconHashEntry(pina, FALSE);
|
||||
if(!pBHE){
|
||||
UNLOCK;
|
||||
return ECA_ALLOCMEM;
|
||||
@@ -166,8 +168,7 @@ struct ioc_in_use **ppiiu
|
||||
else{
|
||||
status = create_net_chan(
|
||||
ppiiu,
|
||||
pnet_addr,
|
||||
port,
|
||||
pina,
|
||||
IPPROTO_TCP);
|
||||
if(status == ECA_NORMAL){
|
||||
pBHE->piiu = *ppiiu;
|
||||
@@ -181,14 +182,13 @@ struct ioc_in_use **ppiiu
|
||||
|
||||
|
||||
/*
|
||||
* CREATE_NET_CHANNEL()
|
||||
* CREATE_NET_CHAN()
|
||||
*
|
||||
*/
|
||||
int create_net_chan(
|
||||
struct ioc_in_use **ppiiu,
|
||||
const struct in_addr *pnet_addr, /* only used by TCP connections */
|
||||
unsigned short port,
|
||||
int net_proto
|
||||
struct ioc_in_use **ppiiu,
|
||||
const struct sockaddr_in *pina, /* only used by TCP connections */
|
||||
int net_proto
|
||||
)
|
||||
{
|
||||
struct ioc_in_use *piiu;
|
||||
@@ -228,7 +228,6 @@ int net_proto
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
|
||||
assert(pnet_addr);
|
||||
pNode = (caAddrNode *)calloc(1,sizeof(*pNode));
|
||||
if(!pNode){
|
||||
free(piiu);
|
||||
@@ -236,9 +235,8 @@ int net_proto
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
memset((char *)&pNode->destAddr,0,sizeof(pNode->destAddr));
|
||||
pNode->destAddr.in.sin_family = AF_INET;
|
||||
pNode->destAddr.in.sin_addr = *pnet_addr;
|
||||
pNode->destAddr.in.sin_port = htons (port);
|
||||
|
||||
pNode->destAddr.in = *pina;
|
||||
ellAdd(&piiu->destAddr, &pNode->node);
|
||||
piiu->recvBytes = tcp_recv_msg;
|
||||
piiu->sendBytes = cac_connect_iiu;
|
||||
@@ -321,7 +319,6 @@ int net_proto
|
||||
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
|
||||
/* set TCP buffer sizes */
|
||||
i = MAX_MSG_SIZE;
|
||||
@@ -352,25 +349,9 @@ int net_proto
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
|
||||
/* fetch the TCP send buffer size */
|
||||
i = sizeof(size);
|
||||
status = getsockopt(
|
||||
sock,
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
(char *)&size,
|
||||
&i);
|
||||
if(status < 0 || i != sizeof(size)){
|
||||
free(pNode);
|
||||
free(piiu);
|
||||
socket_close(sock);
|
||||
UNLOCK;
|
||||
return ECA_SOCK;
|
||||
}
|
||||
}
|
||||
|
||||
cacRingBufferInit(&piiu->recv, sizeof(piiu->send.buf));
|
||||
cacRingBufferInit(&piiu->recv, sizeof(piiu->recv.buf));
|
||||
cacRingBufferInit(&piiu->send, sizeof(piiu->send.buf));
|
||||
|
||||
cac_gettimeval (&piiu->timeAtLastRecv);
|
||||
@@ -401,7 +382,6 @@ int net_proto
|
||||
|
||||
case IPPROTO_UDP:
|
||||
|
||||
assert(!pnet_addr);
|
||||
piiu->recvBytes = udp_recv_msg;
|
||||
piiu->sendBytes = cac_udp_send_msg_piiu;
|
||||
piiu->procInput = ca_process_udp;
|
||||
@@ -492,7 +472,7 @@ int net_proto
|
||||
ca_static->ca_server_port);
|
||||
|
||||
|
||||
cacRingBufferInit(&piiu->recv, sizeof(piiu->send.buf));
|
||||
cacRingBufferInit(&piiu->recv, sizeof(piiu->recv.buf));
|
||||
cacRingBufferInit(&piiu->send, min(MAX_UDP,
|
||||
sizeof(piiu->send.buf)));
|
||||
|
||||
@@ -513,7 +493,7 @@ int net_proto
|
||||
|
||||
default:
|
||||
free(piiu);
|
||||
genLocalExcep (ECA_INTERNAL,"alloc_ioc: ukn protocol");
|
||||
genLocalExcep (ECA_INTERNAL,"create_net_chan: ukn protocol");
|
||||
/*
|
||||
* turn off gcc warnings
|
||||
*/
|
||||
@@ -622,9 +602,6 @@ LOCAL void cac_connect_iiu (struct ioc_in_use *piiu)
|
||||
errnoCpy==EALREADY ||
|
||||
errnoCpy==EINVAL /* for early WINSOCK */
|
||||
) {
|
||||
ca_printf(
|
||||
"CAC: duplicate connect err %d=\"%s\"\n",
|
||||
errnoCpy, strerror(errnoCpy));
|
||||
return;
|
||||
}
|
||||
else if(errnoCpy==EINTR) {
|
||||
@@ -971,7 +948,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
|
||||
localError = SOCKERRNO;
|
||||
|
||||
if( localError == EWOULDBLOCK ||
|
||||
localError == ENOBUFS ||
|
||||
/* localError == ENOBUFS || */
|
||||
localError == EINTR){
|
||||
UNLOCK;
|
||||
return;
|
||||
@@ -1388,7 +1365,7 @@ LOCAL void close_ioc (IIU *piiu)
|
||||
*/
|
||||
pNode = (caAddrNode *) piiu->destAddr.node.next;
|
||||
assert (pNode);
|
||||
removeBeaconInetAddr (&pNode->destAddr.in.sin_addr);
|
||||
removeBeaconInetAddr (&pNode->destAddr.in);
|
||||
|
||||
/*
|
||||
* Mark all of their channels disconnected
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
/************************************************************************/
|
||||
|
||||
/* $Log$
|
||||
* Revision 1.63 1997/05/05 04:45:25 jhill
|
||||
* send_needed => pushPending, and added ca_number_iiu_in_fc
|
||||
*
|
||||
* Revision 1.62 1997/04/29 06:11:08 jhill
|
||||
* use free lists
|
||||
*
|
||||
@@ -315,7 +318,7 @@ typedef struct caclient_put_notify{
|
||||
unsigned long valueSize; /* size of block pointed to by dbPutNotify */
|
||||
void (*caUserCallback)(struct event_handler_args);
|
||||
void *caUserArg;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
int busy;
|
||||
}CACLIENTPUTNOTIFY;
|
||||
#endif /*vxWorks*/
|
||||
@@ -434,7 +437,7 @@ typedef struct ioc_in_use{
|
||||
struct ca_buffer send;
|
||||
struct ca_buffer recv;
|
||||
caHdr curMsg;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
void *pCurData;
|
||||
void (*sendBytes)(struct ioc_in_use *);
|
||||
void (*recvBytes)(struct ioc_in_use *);
|
||||
@@ -464,11 +467,11 @@ typedef struct ioc_in_use{
|
||||
/*
|
||||
* for the beacon's recvd hash table
|
||||
*/
|
||||
#define BHT_INET_ADDR_MASK 0x7f
|
||||
#define BHT_INET_ADDR_MASK 0xff
|
||||
typedef struct beaconHashEntry{
|
||||
struct beaconHashEntry *pNext;
|
||||
IIU *piiu;
|
||||
struct in_addr inetAddr;
|
||||
struct sockaddr_in inetAddr;
|
||||
ca_time timeStamp;
|
||||
ca_real averagePeriod;
|
||||
}bhe;
|
||||
@@ -483,7 +486,7 @@ typedef struct {
|
||||
fd_set writeMask;
|
||||
}caFDInfo;
|
||||
|
||||
struct ca_static{
|
||||
struct CA_STATIC {
|
||||
ELLLIST ca_iiuList;
|
||||
ELLLIST ca_ioeventlist;
|
||||
ELLLIST ca_pend_read_list;
|
||||
@@ -516,8 +519,8 @@ struct ca_static{
|
||||
void *ca_sgFreeListPVT;
|
||||
void *ca_sgopFreeListPVT;
|
||||
ciu ca_pEndOfBCastList;
|
||||
unsigned long ca_search_responses; /* num valid search resp within seq # */
|
||||
unsigned long ca_search_tries; /* num search tries within seq # */
|
||||
unsigned ca_search_responses; /* num valid search resp within seq # */
|
||||
unsigned ca_search_tries; /* num search tries within seq # */
|
||||
unsigned ca_search_retry; /* search retry seq number */
|
||||
unsigned ca_min_retry; /* min retry no so far */
|
||||
unsigned ca_frames_per_try; /* # of UDP frames per search try */
|
||||
@@ -528,6 +531,8 @@ struct ca_static{
|
||||
unsigned ca_number_iiu_in_fc;
|
||||
unsigned short ca_server_port;
|
||||
unsigned short ca_repeater_port;
|
||||
unsigned short ca_search_retry_seq_no; /* search retry seq number */
|
||||
unsigned short ca_seq_no_at_list_begin; /* search retry seq number at beg of list*/
|
||||
char ca_sprintf_buf[256];
|
||||
char ca_new_err_code_msg_buf[128u];
|
||||
unsigned ca_post_msg_active:1;
|
||||
@@ -592,7 +597,7 @@ typedef struct{
|
||||
*/
|
||||
|
||||
GLBLTYPE
|
||||
struct ca_static *ca_static;
|
||||
struct CA_STATIC *ca_static;
|
||||
|
||||
/*
|
||||
* CA internal functions
|
||||
@@ -614,14 +619,14 @@ void issue_client_host_name(struct ioc_in_use *piiu);
|
||||
int ca_defunct(void);
|
||||
int ca_printf(char *pformat, ...);
|
||||
void manage_conn();
|
||||
void mark_server_available(const struct in_addr *pnet_addr);
|
||||
void mark_server_available(const struct sockaddr_in *pnet_addr);
|
||||
void flow_control_on(struct ioc_in_use *piiu);
|
||||
void flow_control_off(struct ioc_in_use *piiu);
|
||||
int broadcast_addr(struct in_addr *pcastaddr);
|
||||
void ca_repeater(void);
|
||||
void cac_recv_task(int tid);
|
||||
void ca_sg_init(void);
|
||||
void ca_sg_shutdown(struct ca_static *ca_temp);
|
||||
void ca_sg_shutdown(struct CA_STATIC *ca_temp);
|
||||
int cac_select_io(struct timeval *ptimeout, int flags);
|
||||
void caHostFromInetAddr(
|
||||
const struct in_addr *pnet_addr,
|
||||
@@ -635,9 +640,8 @@ int post_msg(
|
||||
unsigned long blockSize
|
||||
);
|
||||
int alloc_ioc(
|
||||
const struct in_addr *pnet_addr,
|
||||
unsigned short port,
|
||||
struct ioc_in_use **ppiiu
|
||||
const struct sockaddr_in *pina,
|
||||
struct ioc_in_use **ppiiu
|
||||
);
|
||||
unsigned long cacRingBufferWrite(
|
||||
struct ca_buffer *pRing,
|
||||
@@ -668,20 +672,19 @@ char *localUserName(void);
|
||||
char *localHostName(void);
|
||||
|
||||
int create_net_chan(
|
||||
struct ioc_in_use **ppiiu,
|
||||
const struct in_addr *pnet_addr, /* only used by TCP connections */
|
||||
unsigned short port,
|
||||
int net_proto
|
||||
struct ioc_in_use **ppiiu,
|
||||
const struct sockaddr_in *pina, /* only used by TCP connections */
|
||||
int net_proto
|
||||
);
|
||||
|
||||
void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port);
|
||||
|
||||
int ca_os_independent_init (void);
|
||||
|
||||
void freeBeaconHash(struct ca_static *ca_temp);
|
||||
void removeBeaconInetAddr(const struct in_addr *pnet_addr);
|
||||
bhe *lookupBeaconInetAddr(const struct in_addr *pnet_addr);
|
||||
bhe *createBeaconHashEntry(const struct in_addr *pnet_addr, unsigned sawBeacon);
|
||||
void freeBeaconHash(struct CA_STATIC *ca_temp);
|
||||
void removeBeaconInetAddr(const struct sockaddr_in *pnet_addr);
|
||||
bhe *lookupBeaconInetAddr(const struct sockaddr_in *pnet_addr);
|
||||
bhe *createBeaconHashEntry(const struct sockaddr_in *pnet_addr, unsigned sawBeacon);
|
||||
void notify_ca_repeater(void);
|
||||
void cac_clean_iiu_list(void);
|
||||
|
||||
@@ -691,8 +694,8 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV);
|
||||
void os_specific_sg_create(CASG *pcasg);
|
||||
void os_specific_sg_delete(CASG *pcasg);
|
||||
void os_specific_sg_io_complete(CASG *pcasg);
|
||||
int cac_os_depen_init(struct ca_static *pcas);
|
||||
void cac_os_depen_exit (struct ca_static *pcas);
|
||||
int cac_os_depen_init(struct CA_STATIC *pcas);
|
||||
void cac_os_depen_exit (struct CA_STATIC *pcas);
|
||||
void ca_process_exit();
|
||||
void ca_spawn_repeater(void);
|
||||
void cac_gettimeval(struct timeval *pt);
|
||||
@@ -711,7 +714,6 @@ void genLocalExcepWFL(long stat, char *ctx,
|
||||
genLocalExcepWFL (STAT, PCTX, __FILE__, __LINE__)
|
||||
void cac_reconnect_channel(ciu chan);
|
||||
void retryPendingClaims(IIU *piiu);
|
||||
void cacClrSearchCounters();
|
||||
void cacSetRetryInterval(unsigned retryNo);
|
||||
void addToChanList(ciu chan, IIU *piiu);
|
||||
void removeFromChanList(ciu chan);
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
#define _NET_CONVERT_H
|
||||
|
||||
#include "db_access.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here are the definitions for architecture dependent byte ordering
|
||||
@@ -85,7 +90,7 @@ typedef void CACVRTFUNC(void *pSrc, void *pDest, int hton, unsigned long count);
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
/* cvrt is (array of) (pointer to) (function returning) int */
|
||||
extern CACVRTFUNC *cac_dbr_cvrt[LAST_BUFFER_TYPE+1];
|
||||
epicsShareExtern CACVRTFUNC *cac_dbr_cvrt[LAST_BUFFER_TYPE+1];
|
||||
#endif
|
||||
|
||||
|
||||
@@ -123,20 +128,20 @@ extern CACVRTFUNC *cac_dbr_cvrt[LAST_BUFFER_TYPE+1];
|
||||
#ifdef CA_LITTLE_ENDIAN
|
||||
# ifndef ntohl
|
||||
# define ntohl(LONG)\
|
||||
(\
|
||||
((LONG) & (dbr_long_t) 0xff000000) >> 24 |\
|
||||
((LONG) & (dbr_long_t) 0x000000ff) << 24 |\
|
||||
((LONG) & (dbr_long_t) 0x0000ff00) << 8 |\
|
||||
((LONG) & (dbr_long_t) 0x00ff0000) >> 8\
|
||||
( (dbr_long_t) (\
|
||||
( ((dbr_ulong_t)LONG) & 0xff000000 ) >> 24u |\
|
||||
( ((dbr_ulong_t)LONG) & 0x000000ff ) << 24u |\
|
||||
( ((dbr_ulong_t)LONG) & 0x0000ff00 ) << 8u |\
|
||||
( ((dbr_ulong_t)LONG) & 0x00ff0000 ) >> 8u )\
|
||||
)
|
||||
# endif
|
||||
# ifndef htonl
|
||||
# define htonl(LONG)\
|
||||
( (dbr_long_t) \
|
||||
(((LONG) & (dbr_long_t) 0x000000ff) << 24 |\
|
||||
((LONG) & (dbr_long_t) 0xff000000) >> 24 |\
|
||||
((LONG) & (dbr_long_t) 0x00ff0000) >> 8 |\
|
||||
((LONG) & (dbr_long_t) 0x0000ff00) << 8 )\
|
||||
( (dbr_long_t) (\
|
||||
( ((dbr_ulong_t)(LONG)) & 0x000000ff ) << 24u |\
|
||||
( ((dbr_ulong_t)(LONG)) & 0xff000000 ) >> 24u |\
|
||||
( ((dbr_ulong_t)(LONG)) & 0x00ff0000 ) >> 8u |\
|
||||
( ((dbr_ulong_t)(LONG)) & 0x0000ff00 ) << 8u )\
|
||||
)
|
||||
# endif
|
||||
# else
|
||||
@@ -183,4 +188,8 @@ extern CACVRTFUNC *cac_dbr_cvrt[LAST_BUFFER_TYPE+1];
|
||||
void dbr_ntohf(dbr_float_t *pNet, dbr_float_t *pHost);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* define _NET_CONVERT_H */
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.21 1997/04/10 19:26:17 jhill
|
||||
* asynch connect, faster connect, ...
|
||||
*
|
||||
* Revision 1.20 1996/11/02 00:51:02 jhill
|
||||
* many pc port, const in API, and other changes
|
||||
*
|
||||
@@ -110,7 +113,7 @@ void os_specific_sg_delete(CASG *pcasg)
|
||||
/*
|
||||
* CAC_ADD_TASK_VARIABLE()
|
||||
*/
|
||||
int cac_add_task_variable(struct ca_static *ca_temp)
|
||||
int cac_add_task_variable(struct CA_STATIC *ca_temp)
|
||||
{
|
||||
ca_static = ca_temp;
|
||||
return ECA_NORMAL;
|
||||
@@ -120,7 +123,7 @@ int cac_add_task_variable(struct ca_static *ca_temp)
|
||||
/*
|
||||
* cac_os_depen_init()
|
||||
*/
|
||||
int cac_os_depen_init(struct ca_static *pcas)
|
||||
int cac_os_depen_init(struct CA_STATIC *pcas)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -135,7 +138,7 @@ int cac_os_depen_init(struct ca_static *pcas)
|
||||
/*
|
||||
* cac_os_depen_exit ()
|
||||
*/
|
||||
void cac_os_depen_exit (struct ca_static *pcas)
|
||||
void cac_os_depen_exit (struct CA_STATIC *pcas)
|
||||
{
|
||||
ca_static = pcas;
|
||||
ca_process_exit();
|
||||
|
||||
126
src/ca/service.c
126
src/ca/service.c
@@ -533,21 +533,33 @@ const struct in_addr *pnet_addr
|
||||
case CA_PROTO_RSRV_IS_UP:
|
||||
LOCK;
|
||||
{
|
||||
struct in_addr ina;
|
||||
struct sockaddr_in ina;
|
||||
|
||||
/*
|
||||
* this allows a fan-out server to potentially
|
||||
* insert the true address of a server
|
||||
* (servers prior to 3.13 always set this
|
||||
*
|
||||
* (servers always set this
|
||||
* field to one of the ip addresses of the host)
|
||||
* (clients prior to 3.13 always expect that this
|
||||
* (clients always expect that this
|
||||
* field is set to the server's IP address).
|
||||
*/
|
||||
ina.sin_family = AF_INET;
|
||||
if (piiu->curMsg.m_available != INADDR_ANY) {
|
||||
ina.s_addr = piiu->curMsg.m_available;
|
||||
ina.sin_addr.s_addr = piiu->curMsg.m_available;
|
||||
}
|
||||
else {
|
||||
ina = *pnet_addr;
|
||||
ina.sin_addr = *pnet_addr;
|
||||
}
|
||||
if (piiu->curMsg.m_count != 0) {
|
||||
ina.sin_port = htons (piiu->curMsg.m_count);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* old servers dont supply this and the
|
||||
* default port must be assumed
|
||||
*/
|
||||
ina.sin_port = htons (ca_static->ca_server_port);
|
||||
}
|
||||
mark_server_available(&ina);
|
||||
}
|
||||
@@ -788,13 +800,13 @@ IIU *piiu,
|
||||
const struct in_addr *pnet_addr
|
||||
)
|
||||
{
|
||||
unsigned short port;
|
||||
char rej[64];
|
||||
ciu chan;
|
||||
int status;
|
||||
IIU *allocpiiu;
|
||||
unsigned short *pMinorVersion;
|
||||
unsigned minorVersion;
|
||||
struct sockaddr_in ina;
|
||||
char rej[64];
|
||||
ciu chan;
|
||||
int status;
|
||||
IIU *allocpiiu;
|
||||
unsigned short *pMinorVersion;
|
||||
unsigned minorVersion;
|
||||
|
||||
if (piiu!=piiuCast) {
|
||||
return;
|
||||
@@ -828,29 +840,6 @@ const struct in_addr *pnet_addr
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore duplicate search replies
|
||||
*/
|
||||
if (piiuCast != (IIU *) chan->piiu) {
|
||||
caAddrNode *pNode;
|
||||
IIU *tcpPIIU = (IIU *) chan->piiu;
|
||||
|
||||
pNode = (caAddrNode *) ellFirst(&tcpPIIU->destAddr);
|
||||
assert(pNode);
|
||||
if (pNode->destAddr.in.sin_addr.s_addr != pnet_addr->s_addr) {
|
||||
caHostFromInetAddr(pnet_addr,rej,sizeof(rej));
|
||||
sprintf(
|
||||
sprintf_buf,
|
||||
"Channel: %s Accepted: %s Rejected: %s ",
|
||||
(char *)(chan + 1),
|
||||
tcpPIIU->host_name_str,
|
||||
rej);
|
||||
genLocalExcep (ECA_DBLCHNL, sprintf_buf);
|
||||
}
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Starting with CA V4.1 the minor version number
|
||||
* is appended to the end of each search reply.
|
||||
@@ -868,13 +857,50 @@ const struct in_addr *pnet_addr
|
||||
* 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;
|
||||
ina.sin_family = AF_INET;
|
||||
if (CA_V48 (CA_PROTOCOL_VERSION,minorVersion)) {
|
||||
if (piiu->curMsg.m_cid != ~0ul) {
|
||||
ina.sin_addr.s_addr = htonl(piiu->curMsg.m_cid);
|
||||
}
|
||||
else {
|
||||
ina.sin_addr = *pnet_addr;
|
||||
}
|
||||
ina.sin_port = htons(piiu->curMsg.m_type);
|
||||
}
|
||||
else if (CA_V45 (CA_PROTOCOL_VERSION,minorVersion)) {
|
||||
ina.sin_port = htons(piiu->curMsg.m_type);
|
||||
ina.sin_addr = *pnet_addr;
|
||||
}
|
||||
else {
|
||||
port = ca_static->ca_server_port;
|
||||
ina.sin_port = htons(ca_static->ca_server_port);
|
||||
ina.sin_addr = *pnet_addr;
|
||||
}
|
||||
status = alloc_ioc (pnet_addr, port, &allocpiiu);
|
||||
|
||||
/*
|
||||
* Ignore duplicate search replies
|
||||
*/
|
||||
if (piiuCast != (IIU *) chan->piiu) {
|
||||
caAddrNode *pNode;
|
||||
IIU *tcpPIIU = (IIU *) chan->piiu;
|
||||
|
||||
pNode = (caAddrNode *) ellFirst(&tcpPIIU->destAddr);
|
||||
assert(pNode);
|
||||
if (pNode->destAddr.in.sin_addr.s_addr != ina.sin_addr.s_addr ||
|
||||
pNode->destAddr.in.sin_port != ina.sin_port) {
|
||||
caHostFromInetAddr(pnet_addr,rej,sizeof(rej));
|
||||
sprintf(
|
||||
sprintf_buf,
|
||||
"Channel: %s Accepted: %s Rejected: %s ",
|
||||
(char *)(chan + 1),
|
||||
tcpPIIU->host_name_str,
|
||||
rej);
|
||||
genLocalExcep (ECA_DBLCHNL, sprintf_buf);
|
||||
}
|
||||
UNLOCK;
|
||||
return;
|
||||
}
|
||||
|
||||
status = alloc_ioc (&ina, &allocpiiu);
|
||||
switch (status) {
|
||||
|
||||
case ECA_NORMAL:
|
||||
@@ -913,8 +939,15 @@ const struct in_addr *pnet_addr
|
||||
issue_client_host_name(allocpiiu);
|
||||
}
|
||||
|
||||
if (ca_static->ca_search_responses<ULONG_MAX) {
|
||||
ca_static->ca_search_responses++;
|
||||
/*
|
||||
* increase the valid search response count only if this
|
||||
* response matches up with a request since the beginning
|
||||
* of the search list
|
||||
*/
|
||||
if (ca_static->ca_seq_no_at_list_begin <= chan->retrySeqNo) {
|
||||
if (ca_static->ca_search_responses<ULONG_MAX) {
|
||||
ca_static->ca_search_responses++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -948,13 +981,12 @@ const struct in_addr *pnet_addr
|
||||
|
||||
/*
|
||||
* Reset the delay to the next search request if we get
|
||||
* at least one response. This may result in an over
|
||||
* run of the UDP input queue of the server in some
|
||||
* cases (and therefore in redundant search requests)
|
||||
* but it does significantly reduce the connect delays
|
||||
* when 1000's of channels must be connected.
|
||||
* at least one response. However, dont reset this delay if we
|
||||
* get a delayed response to an old search request.
|
||||
*/
|
||||
ca_static->ca_conn_next_retry = ca_static->currentTime;
|
||||
if (chan->retrySeqNo == ca_static->ca_search_retry_seq_no) {
|
||||
ca_static->ca_conn_next_retry = ca_static->currentTime;
|
||||
}
|
||||
|
||||
/*
|
||||
* claim the resource in the IOC
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.23 1997/04/29 06:12:42 jhill
|
||||
* use free lists
|
||||
*
|
||||
* Revision 1.22 1996/11/22 19:08:02 jhill
|
||||
* added const to API
|
||||
*
|
||||
@@ -81,7 +84,7 @@ void ca_sg_init(void)
|
||||
/*
|
||||
* ca_sg_shutdown()
|
||||
*/
|
||||
void ca_sg_shutdown(struct ca_static *ca_temp)
|
||||
void ca_sg_shutdown(struct CA_STATIC *ca_temp)
|
||||
{
|
||||
CASG *pcasg;
|
||||
CASG *pnextcasg;
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
* cjm 20-Nov-95 Add code for gettimeofday
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.21 1997/01/22 21:11:49 jhill
|
||||
* moved vms includes here
|
||||
*
|
||||
* Revision 1.20 1996/07/02 23:04:07 jhill
|
||||
* took &tz out of gettimeofday()
|
||||
*
|
||||
@@ -164,7 +167,7 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
/*
|
||||
* cac_os_depen_init()
|
||||
*/
|
||||
int cac_os_depen_init(struct ca_static *pcas)
|
||||
int cac_os_depen_init(struct CA_STATIC *pcas)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -179,7 +182,7 @@ int cac_os_depen_init(struct ca_static *pcas)
|
||||
/*
|
||||
* cac_os_depen_exit ()
|
||||
*/
|
||||
void cac_os_depen_exit (struct ca_static *pcas)
|
||||
void cac_os_depen_exit (struct CA_STATIC *pcas)
|
||||
{
|
||||
ca_static = pcas;
|
||||
ca_process_exit();
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.30 1997/04/29 06:13:49 jhill
|
||||
* use free lists
|
||||
*
|
||||
* Revision 1.29 1997/04/23 17:05:10 jhill
|
||||
* pc port changes
|
||||
*
|
||||
@@ -71,8 +74,8 @@
|
||||
LOCAL void ca_repeater_task();
|
||||
LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb);
|
||||
LOCAL void ca_extra_event_labor(void *pArg);
|
||||
LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid);
|
||||
LOCAL int cac_add_task_variable (struct ca_static *ca_temp);
|
||||
LOCAL int cac_os_depen_exit_tid (struct CA_STATIC *pcas, int tid);
|
||||
LOCAL int cac_add_task_variable (struct CA_STATIC *ca_temp);
|
||||
LOCAL void deleteCallBack(CALLBACK *pcb);
|
||||
LOCAL void ca_check_for_fp();
|
||||
LOCAL int event_import(int tid);
|
||||
@@ -238,7 +241,7 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
/*
|
||||
* CAC_ADD_TASK_VARIABLE()
|
||||
*/
|
||||
LOCAL int cac_add_task_variable (struct ca_static *ca_temp)
|
||||
LOCAL int cac_add_task_variable (struct CA_STATIC *ca_temp)
|
||||
{
|
||||
static char ca_installed;
|
||||
TVIU *ptviu;
|
||||
@@ -314,7 +317,7 @@ LOCAL int cac_add_task_variable (struct ca_static *ca_temp)
|
||||
LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb)
|
||||
{
|
||||
int status;
|
||||
struct ca_static *ca_temp;
|
||||
struct CA_STATIC *ca_temp;
|
||||
|
||||
# ifdef DEBUG
|
||||
ca_printf("CAC: entering the exit handler %x\n", ptcb);
|
||||
@@ -327,9 +330,9 @@ LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb)
|
||||
* the task id - somthing which may not be true
|
||||
* on future releases of vxWorks
|
||||
*/
|
||||
ca_temp = (struct ca_static *)
|
||||
ca_temp = (struct CA_STATIC *)
|
||||
taskVarGet((int)ptcb, (int *) &ca_static);
|
||||
if (ca_temp == (struct ca_static *) ERROR){
|
||||
if (ca_temp == (struct CA_STATIC *) ERROR){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,7 +365,7 @@ LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb)
|
||||
/*
|
||||
* cac_os_depen_init()
|
||||
*/
|
||||
int cac_os_depen_init(struct ca_static *pcas)
|
||||
int cac_os_depen_init(struct CA_STATIC *pcas)
|
||||
{
|
||||
char name[15];
|
||||
int status;
|
||||
@@ -426,7 +429,7 @@ int cac_os_depen_init(struct ca_static *pcas)
|
||||
/*
|
||||
* cac_os_depen_exit ()
|
||||
*/
|
||||
void cac_os_depen_exit (struct ca_static *pcas)
|
||||
void cac_os_depen_exit (struct CA_STATIC *pcas)
|
||||
{
|
||||
cac_os_depen_exit_tid (pcas, 0);
|
||||
}
|
||||
@@ -435,7 +438,7 @@ void cac_os_depen_exit (struct ca_static *pcas)
|
||||
/*
|
||||
* cac_os_depen_exit_tid ()
|
||||
*/
|
||||
LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid)
|
||||
LOCAL int cac_os_depen_exit_tid (struct CA_STATIC *pcas, int tid)
|
||||
{
|
||||
int status;
|
||||
ciu chix;
|
||||
@@ -665,7 +668,7 @@ LOCAL int event_import(int tid)
|
||||
int ca_import(int tid)
|
||||
{
|
||||
int status;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
TVIU *ptviu;
|
||||
|
||||
ca_check_for_fp();
|
||||
@@ -674,9 +677,9 @@ int ca_import(int tid)
|
||||
* just return success if they have already done
|
||||
* a ca import for this task
|
||||
*/
|
||||
pcas = (struct ca_static *)
|
||||
pcas = (struct CA_STATIC *)
|
||||
taskVarGet(taskIdSelf(), (int *)&ca_static);
|
||||
if (pcas != (struct ca_static *) ERROR){
|
||||
if (pcas != (struct CA_STATIC *) ERROR){
|
||||
return ECA_NORMAL;
|
||||
}
|
||||
|
||||
@@ -685,9 +688,9 @@ int ca_import(int tid)
|
||||
return ECA_ALLOCMEM;
|
||||
}
|
||||
|
||||
pcas = (struct ca_static *)
|
||||
pcas = (struct CA_STATIC *)
|
||||
taskVarGet(tid, (int *)&ca_static);
|
||||
if (pcas == (struct ca_static *) ERROR){
|
||||
if (pcas == (struct CA_STATIC *) ERROR){
|
||||
free(ptviu);
|
||||
return ECA_NOCACTX;
|
||||
}
|
||||
@@ -718,7 +721,7 @@ int ca_import_cancel(int tid)
|
||||
{
|
||||
int status;
|
||||
TVIU *ptviu;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
|
||||
if (tid == taskIdSelf()) {
|
||||
pcas = NULL;
|
||||
@@ -730,9 +733,9 @@ int ca_import_cancel(int tid)
|
||||
/*
|
||||
* Attempt to attach to the specified context
|
||||
*/
|
||||
ca_static = (struct ca_static *)
|
||||
ca_static = (struct CA_STATIC *)
|
||||
taskVarGet(tid, (int *)&ca_static);
|
||||
if (ca_static == (struct ca_static *) ERROR){
|
||||
if (ca_static == (struct CA_STATIC *) ERROR){
|
||||
ca_static = pcas;
|
||||
return ECA_NOCACTX;
|
||||
}
|
||||
@@ -829,7 +832,7 @@ LOCAL void ca_extra_event_labor(void *pArg)
|
||||
{
|
||||
int status;
|
||||
CACLIENTPUTNOTIFY *ppnb;
|
||||
struct ca_static *pcas;
|
||||
struct CA_STATIC *pcas;
|
||||
struct event_handler_args args;
|
||||
|
||||
pcas = pArg;
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.27 1997/05/01 19:46:32 jhill
|
||||
* fixed unintialized variable bug
|
||||
*
|
||||
* Revision 1.26 1997/04/11 20:36:00 jhill
|
||||
* kay's perl branch
|
||||
*
|
||||
@@ -147,7 +150,7 @@ void cac_block_for_sg_completion(CASG *pcasg, struct timeval *pTV)
|
||||
/*
|
||||
* cac_os_depen_init()
|
||||
*/
|
||||
int cac_os_depen_init(struct ca_static *pcas)
|
||||
int cac_os_depen_init(struct CA_STATIC *pcas)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -164,7 +167,7 @@ int cac_os_depen_init(struct ca_static *pcas)
|
||||
/*
|
||||
* cac_os_depen_exit ()
|
||||
*/
|
||||
void cac_os_depen_exit (struct ca_static *pcas)
|
||||
void cac_os_depen_exit (struct CA_STATIC *pcas)
|
||||
{
|
||||
ca_static = pcas;
|
||||
ca_process_exit();
|
||||
|
||||
@@ -11,7 +11,7 @@ include $(TOP)/config/CONFIG_BASE
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
# sometimes it's good to have different C/C++ flags, not now:
|
||||
USR_CFLAGS = -I$(SRC) -I$(IOSRC) -I$(STSRC) -I$(CA)
|
||||
USR_CFLAGS = -I$(SRC) -I$(IOSRC) -I$(STSRC) -I$(CA) -DcaNetAddrSock
|
||||
USR_CXXFLAGS = $(USR_CFLAGS)
|
||||
|
||||
LIBSRCS += caServer.cc
|
||||
@@ -38,7 +38,6 @@ LIBSRCS += casAsyncPVCIOI.cc
|
||||
LIBSRCS += casEventSys.cc
|
||||
LIBSRCS += casMonitor.cc
|
||||
LIBSRCS += casMonEvent.cc
|
||||
LIBSRCS += casOpaqueAddr.cc
|
||||
LIBSRCS += inBuf.o
|
||||
LIBSRCS += outBuf.cc
|
||||
LIBSRCS += dgInBuf.o
|
||||
|
||||
@@ -3,7 +3,7 @@ TOP=../../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
DIRS = simple
|
||||
DIRS = simple directoryService
|
||||
|
||||
include $(TOP)/config/RULES_DIRS
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
|
||||
This directory contains several server tool examples (which
|
||||
use the ca server library). The original ca server example
|
||||
is in the "simple" subdirectory.
|
||||
use the ca server library).
|
||||
|
||||
simple - complete CA server example (includes asynchronous
|
||||
io and arrays)
|
||||
|
||||
testdb - very simple ca server (does not provide some of the
|
||||
pv attributes (ie precision and others))
|
||||
|
||||
directoryService - fully functional pv name resolution server
|
||||
|
||||
|
||||
|
||||
7
src/cas/example/directoryService/Makefile
Normal file
7
src/cas/example/directoryService/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
include $(TOP)/config/RULES_ARCHS
|
||||
|
||||
27
src/cas/example/directoryService/Makefile.Host
Normal file
27
src/cas/example/directoryService/Makefile.Host
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
CAS = ../../..
|
||||
TOP = $(CAS)/../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
PROD_LIBS := cas ca gdd Com
|
||||
|
||||
SRCS += main.cc
|
||||
SRCS += directoryServer.cc
|
||||
SRCS += templInst.cc
|
||||
|
||||
PROD := caDirServ
|
||||
|
||||
include $(TOP)/config/RULES.Host
|
||||
|
||||
pcaDirServ: $(PROD_OBJS) $(PRODDEPLIBS)
|
||||
$(PURIFY) $(PROD_LINKER) $(PROD_OBJS) $(LDLIBS)
|
||||
|
||||
clean::
|
||||
@$(RM) caDirServ
|
||||
@$(RM) pcaDirServ
|
||||
@$(RM) -rf Templates.DB
|
||||
@$(RM) core
|
||||
|
||||
38
src/cas/example/directoryService/Makefile.Vx.WorkInProgress
Normal file
38
src/cas/example/directoryService/Makefile.Vx.WorkInProgress
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
CAS = ../../..
|
||||
TOP = $(CAS)/../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
USR_INCLUDES =
|
||||
USR_LDFLAGS =
|
||||
|
||||
DEPLIBS_BASE = $(EPICS_BASE_LIB)
|
||||
DEPLIBS = $(DEPLIBS_BASE)/libcas.a $(DEPLIBSWOCAS)
|
||||
|
||||
SRCS.cc += ../vxEntry.cc
|
||||
SRCS.cc += ../exServer.cc
|
||||
SRCS.cc += ../exPV.cc
|
||||
SRCS.cc += ../exSyncPV.cc
|
||||
SRCS.cc += ../exAsyncPV.cc
|
||||
SRCS.cc += ../exChannel.cc
|
||||
|
||||
LIBOBJS += vxEntry.o
|
||||
LIBOBJS += exServer.o
|
||||
LIBOBJS += exPV.o
|
||||
LIBOBJS += exSyncPV.o
|
||||
LIBOBJS += exAsyncPV.o
|
||||
LIBOBJS += exChannel.o
|
||||
|
||||
LIBNAME = libexserver.o
|
||||
include $(TOP)/config/RULES.Vx
|
||||
|
||||
excas: $(OBJS) $(DEPLIBS)
|
||||
$(LINK.cc) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
clean::
|
||||
@$(RM) -rf Templates.DB
|
||||
@$(RM) core
|
||||
|
||||
13
src/cas/example/directoryService/README
Normal file
13
src/cas/example/directoryService/README
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
This directory contains an example ca directory (name resolution) server.
|
||||
|
||||
The directory server reads in a file with records as follows:
|
||||
<PV name> <host name or dotted ip address> [<optional IP port number>]
|
||||
|
||||
The server responds to search requests with the true server address of
|
||||
the PV (not the address of this directory server).
|
||||
|
||||
This server can be used to cause EPICS to locate any PV listed in
|
||||
the file anywhere on the internet. You must of course set EPICS_CA_ADDR_LIST
|
||||
for the client so that it points at a running instance of this directory
|
||||
(name resolution) server.
|
||||
155
src/cas/example/directoryService/directoryServer.cc
Normal file
155
src/cas/example/directoryService/directoryServer.cc
Normal file
@@ -0,0 +1,155 @@
|
||||
|
||||
//
|
||||
// Example EPICS CA directory server
|
||||
//
|
||||
|
||||
#include "directoryServer.h"
|
||||
#include "tsMinMax.h"
|
||||
|
||||
const pvInfo *pvInfo::pFirst;
|
||||
|
||||
//
|
||||
// directoryServer::directoryServer()
|
||||
//
|
||||
directoryServer::directoryServer(const char * const pvPrefix, unsigned pvCount, unsigned aliasCount) :
|
||||
caServer(pvCount*(aliasCount+1u))
|
||||
{
|
||||
unsigned i;
|
||||
const pvInfo *pPVI;
|
||||
int resLibStatus;
|
||||
char pvAlias[256];
|
||||
const char * const pNameFmtStr = "%.100s%.20s";
|
||||
const char * const pAliasFmtStr = "%.100s%.20s%u";
|
||||
|
||||
//
|
||||
// hash table size may need adjustment here?
|
||||
//
|
||||
resLibStatus = this->stringResTbl.init(pvCount*(aliasCount+1u));
|
||||
if (resLibStatus) {
|
||||
fprintf(stderr, "CAS: string resource id table init failed\n");
|
||||
//
|
||||
// should throw an exception once this is portable
|
||||
//
|
||||
assert(resLibStatus==0);
|
||||
}
|
||||
|
||||
//
|
||||
// pre-create all of the simple PVs that this server will export
|
||||
//
|
||||
for (pPVI = pvInfo::getFirst(); pPVI; pPVI=pPVI->getNext()) {
|
||||
|
||||
//
|
||||
// Install canonical (root) name
|
||||
//
|
||||
sprintf(pvAlias, pNameFmtStr, pvPrefix, pPVI->getName());
|
||||
this->installAliasName(*pPVI, pvAlias);
|
||||
|
||||
//
|
||||
// Install numbered alias names
|
||||
//
|
||||
for (i=0u; i<aliasCount; i++) {
|
||||
sprintf(pvAlias, pAliasFmtStr, pvPrefix,
|
||||
pPVI->getName(), i);
|
||||
this->installAliasName(*pPVI, pvAlias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// directoryServer::installAliasName()
|
||||
//
|
||||
void directoryServer::installAliasName(const pvInfo &info, const char *pAliasName)
|
||||
{
|
||||
pvEntry *pEntry;
|
||||
|
||||
pEntry = new pvEntry(info, *this, pAliasName);
|
||||
if (pEntry) {
|
||||
int resLibStatus;
|
||||
resLibStatus = this->stringResTbl.add(*pEntry);
|
||||
if (resLibStatus==0) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
delete pEntry;
|
||||
}
|
||||
}
|
||||
fprintf(stderr,
|
||||
"Unable to enter PV=\"%s\" Alias=\"%s\" in PV name alias hash table\n",
|
||||
info.getName(), pAliasName);
|
||||
}
|
||||
|
||||
//
|
||||
// directoryServer::pvExistTest()
|
||||
//
|
||||
pvExistReturn directoryServer::pvExistTest
|
||||
(const casCtx&, const char *pPVName)
|
||||
{
|
||||
//
|
||||
// lifetime of id is shorter than lifetime of pName
|
||||
//
|
||||
char pvNameBuf[512];
|
||||
stringId id(pPVName, stringId::refString);
|
||||
stringId idBuf(pvNameBuf, stringId::refString);
|
||||
pvEntry *pPVE;
|
||||
const char *pStr, *pLastStr;
|
||||
|
||||
//
|
||||
// strip trailing occurrence of ".field"
|
||||
// (for compatibility with EPICS
|
||||
// function block database).
|
||||
//
|
||||
pStr = pPVName;
|
||||
do {
|
||||
pLastStr = pStr;
|
||||
pStr = strstr (pStr, ".");
|
||||
}
|
||||
while (pStr);
|
||||
|
||||
if (pLastStr==pPVName) {
|
||||
pPVE = this->stringResTbl.lookup(id);
|
||||
if (!pPVE) {
|
||||
return pverDoesNotExistHere;
|
||||
}
|
||||
}
|
||||
else {
|
||||
size_t diff = pLastStr-pPVName;
|
||||
diff = tsMin (diff, sizeof(pvNameBuf)-1);
|
||||
memcpy (pvNameBuf, pPVName, diff);
|
||||
pvNameBuf[diff] = '\0';
|
||||
pLastStr = pvNameBuf;
|
||||
pPVE = this->stringResTbl.lookup(idBuf);
|
||||
if (!pPVE) {
|
||||
//
|
||||
// look for entire PV name (in case this PV isnt
|
||||
// associated a function block database)
|
||||
//
|
||||
// lifetime of id2 is shorter than lifetime of pName
|
||||
//
|
||||
pPVE = this->stringResTbl.lookup(id);
|
||||
if (!pPVE) {
|
||||
return pverDoesNotExistHere;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pvExistReturn (caNetAddr(pPVE->getInfo().getAddr()));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// directoryServer::show()
|
||||
//
|
||||
void directoryServer::show (unsigned level) const
|
||||
{
|
||||
//
|
||||
// server tool specific show code goes here
|
||||
//
|
||||
this->stringResTbl.show(level);
|
||||
|
||||
//
|
||||
// print information about ca server libarary
|
||||
// internals
|
||||
//
|
||||
this->caServer::show(level);
|
||||
}
|
||||
|
||||
135
src/cas/example/directoryService/directoryServer.h
Normal file
135
src/cas/example/directoryService/directoryServer.h
Normal file
@@ -0,0 +1,135 @@
|
||||
//
|
||||
// Example EPICS CA directory server
|
||||
//
|
||||
//
|
||||
// caServer
|
||||
// |
|
||||
// directoryServer
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// ANSI C
|
||||
//
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//
|
||||
// EPICS
|
||||
//
|
||||
#include "epicsAssert.h"
|
||||
#define caNetAddrSock
|
||||
#include "casdef.h"
|
||||
#include "resourceLib.h"
|
||||
|
||||
|
||||
#ifndef NELEMENTS
|
||||
# define NELEMENTS(A) (sizeof(A)/sizeof(A[0]))
|
||||
#endif
|
||||
|
||||
class directoryServer;
|
||||
|
||||
//
|
||||
// pvInfo
|
||||
//
|
||||
class pvInfo {
|
||||
public:
|
||||
pvInfo (const char *pNameIn, sockaddr_in addrIn) :
|
||||
addr(addrIn), pNext(pvInfo::pFirst)
|
||||
{
|
||||
pvInfo::pFirst = this;
|
||||
this->pName = new char [strlen(pNameIn)+1u];
|
||||
assert(this->pName);
|
||||
strcpy(this->pName, pNameIn);
|
||||
}
|
||||
|
||||
const struct sockaddr_in getAddr() const { return this->addr; }
|
||||
const char *getName () const { return this->pName; }
|
||||
const pvInfo *getNext () const { return this->pNext; }
|
||||
static const pvInfo *getFirst () { return pvInfo::pFirst; }
|
||||
private:
|
||||
struct sockaddr_in addr;
|
||||
char *pName;
|
||||
const pvInfo *pNext;
|
||||
static const pvInfo *pFirst;
|
||||
};
|
||||
|
||||
//
|
||||
// pvEntry
|
||||
//
|
||||
// o entry in the string hash table for the pvInfo
|
||||
// o Since there may be aliases then we may end up
|
||||
// with several of this class all referencing
|
||||
// the same pv info class (justification
|
||||
// for this breaking out into a seperate class
|
||||
// from pvInfo)
|
||||
//
|
||||
class pvEntry : public stringId, public tsSLNode<pvEntry> {
|
||||
public:
|
||||
pvEntry (const pvInfo &infoIn, directoryServer &casIn,
|
||||
const char *pAliasName) :
|
||||
stringId(pAliasName), info(infoIn), cas(casIn)
|
||||
{
|
||||
assert(this->stringId::resourceName()!=NULL);
|
||||
}
|
||||
|
||||
inline ~pvEntry();
|
||||
|
||||
const pvInfo &getInfo() const { return this->info; }
|
||||
|
||||
inline void destroy ();
|
||||
|
||||
private:
|
||||
const pvInfo &info;
|
||||
directoryServer &cas;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// directoryServer
|
||||
//
|
||||
class directoryServer : public caServer {
|
||||
public:
|
||||
directoryServer (const char * const pvPrefix, unsigned pvCount, unsigned aliasCount);
|
||||
void show (unsigned level) const;
|
||||
pvExistReturn pvExistTest (const casCtx&, const char *pPVName);
|
||||
|
||||
void installAliasName (const pvInfo &info, const char *pAliasName);
|
||||
inline void removeAliasName(pvEntry &entry);
|
||||
|
||||
private:
|
||||
resTable<pvEntry,stringId> stringResTbl;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// directoryServer::removeAliasName()
|
||||
//
|
||||
inline void directoryServer::removeAliasName(pvEntry &entry)
|
||||
{
|
||||
pvEntry *pE;
|
||||
pE = this->stringResTbl.remove(entry);
|
||||
assert(pE = &entry);
|
||||
}
|
||||
|
||||
//
|
||||
// pvEntry::~pvEntry()
|
||||
//
|
||||
inline pvEntry::~pvEntry()
|
||||
{
|
||||
this->cas.removeAliasName(*this);
|
||||
}
|
||||
|
||||
//
|
||||
// pvEntry::destroy()
|
||||
//
|
||||
inline void pvEntry::destroy ()
|
||||
{
|
||||
//
|
||||
// always created with new
|
||||
//
|
||||
delete this;
|
||||
}
|
||||
|
||||
215
src/cas/example/directoryService/main.cc
Normal file
215
src/cas/example/directoryService/main.cc
Normal file
@@ -0,0 +1,215 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "directoryServer.h"
|
||||
#include "fdManager.h"
|
||||
|
||||
#define LOCAL static
|
||||
|
||||
LOCAL int parseDirectoryFile (const char *pFileName);
|
||||
LOCAL int parseDirectoryFP (FILE *pf, const char *pFileName);
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (~0ul)
|
||||
#endif
|
||||
|
||||
//
|
||||
// main()
|
||||
// (example single threaded ca server tool main loop)
|
||||
//
|
||||
extern int main (int argc, const char **argv)
|
||||
{
|
||||
osiTime begin(osiTime::getCurrent());
|
||||
directoryServer *pCAS;
|
||||
unsigned debugLevel = 0u;
|
||||
float executionTime;
|
||||
char pvPrefix[128] = "";
|
||||
char fileName[128] = "pvDirectory.txt";
|
||||
unsigned aliasCount = 0u;
|
||||
aitBool forever = aitTrue;
|
||||
int nPV;
|
||||
int i;
|
||||
|
||||
for (i=1; i<argc; i++) {
|
||||
if (sscanf(argv[i], "-d %u", &debugLevel)==1) {
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i],"-t %f", &executionTime)==1) {
|
||||
forever = aitFalse;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i],"-p %127s", pvPrefix)==1) {
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i],"-c %u", &aliasCount)==1) {
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i], "-f %127s", fileName)==1) {
|
||||
continue;
|
||||
}
|
||||
fprintf (stderr,
|
||||
"usage: %s [-d<debug level> -t<execution time> -p<PV name prefix> -c<numbered alias count> -f<PV directory file>]\n",
|
||||
argv[0]);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
nPV = parseDirectoryFile (fileName);
|
||||
if (nPV<=0) {
|
||||
fprintf(stderr,
|
||||
"No PVs in directory file=%s. Exiting because there is no useful work to do.\n",
|
||||
fileName);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pCAS = new directoryServer(pvPrefix, (unsigned) nPV, aliasCount);
|
||||
if (!pCAS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pCAS->setDebugLevel(debugLevel);
|
||||
|
||||
if (forever) {
|
||||
osiTime delay(1000u,0u);
|
||||
//
|
||||
// loop here forever
|
||||
//
|
||||
while (aitTrue) {
|
||||
fileDescriptorManager.process(delay);
|
||||
}
|
||||
}
|
||||
else {
|
||||
osiTime total(executionTime);
|
||||
osiTime delay(osiTime::getCurrent() - begin);
|
||||
//
|
||||
// loop here untime the specified execution time
|
||||
// expires
|
||||
//
|
||||
while (delay < total) {
|
||||
fileDescriptorManager.process(delay);
|
||||
delay = osiTime::getCurrent() - begin;
|
||||
}
|
||||
}
|
||||
pCAS->show(2u);
|
||||
delete pCAS;
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// parseDirectoryFile()
|
||||
//
|
||||
// PV directory file is expected to have entries of the form:
|
||||
// <PV name> <host name or dotted ip address> [<optional IP port number>]
|
||||
//
|
||||
//
|
||||
LOCAL int parseDirectoryFile (const char *pFileName)
|
||||
{
|
||||
|
||||
FILE *pf;
|
||||
int nPV;
|
||||
|
||||
//
|
||||
// open a file that contains the PV directory
|
||||
//
|
||||
pf = fopen(pFileName, "r");
|
||||
if (!pf) {
|
||||
fprintf(stderr, "Directory file access probems with file=\"%s\" because \"%s\"\n",
|
||||
pFileName, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
nPV = parseDirectoryFP (pf, pFileName);
|
||||
|
||||
fclose (pf);
|
||||
|
||||
return nPV;
|
||||
}
|
||||
|
||||
//
|
||||
// parseDirectoryFP()
|
||||
//
|
||||
// PV directory file is expected to have entries of the form:
|
||||
// <PV name> <host name or dotted ip address> [<optional IP port number>]
|
||||
//
|
||||
//
|
||||
LOCAL int parseDirectoryFP (FILE *pf, const char *pFileName)
|
||||
{
|
||||
pvInfo *pPVI;
|
||||
char pvNameStr[128];
|
||||
struct sockaddr_in ipa;
|
||||
char hostNameStr[128];
|
||||
int nPV=0;
|
||||
|
||||
ipa.sin_family = AF_INET;
|
||||
while (TRUE) {
|
||||
|
||||
//
|
||||
// parse the PV name entry from the file
|
||||
//
|
||||
if (fscanf(pf, " %127s ", pvNameStr) != 1) {
|
||||
return nPV; // success
|
||||
}
|
||||
|
||||
//
|
||||
// parse out server address
|
||||
//
|
||||
if (fscanf(pf, " %s ", hostNameStr) == 1) {
|
||||
|
||||
ipa.sin_addr.s_addr = inet_addr(hostNameStr);
|
||||
if (ipa.sin_addr.s_addr==INADDR_NONE) {
|
||||
struct hostent *pent;
|
||||
|
||||
pent = gethostbyname(hostNameStr);
|
||||
if (!pent) {
|
||||
fprintf (pf, "Unknown host name=\"%s\" (or bad dotted ip addr) in \"%s\" with PV=\"%s\"?\n",
|
||||
hostNameStr, pFileName, pvNameStr);
|
||||
return -1;
|
||||
}
|
||||
if (pent->h_addrtype != AF_INET) {
|
||||
fprintf (pf, "Unknown addr type for host=\"%s\" in \"%s\" with PV=\"%s\" addr type=%u?\n",
|
||||
hostNameStr, pFileName, pvNameStr, pent->h_addrtype);
|
||||
return -1;
|
||||
}
|
||||
assert (pent->h_addr_list[0]);
|
||||
assert (pent->h_length==sizeof(ipa.sin_addr));
|
||||
|
||||
memcpy ((char *)&ipa.sin_addr, pent->h_addr_list[0], pent->h_length);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf (stderr,"No host name (or dotted ip addr) after PV name in \"%s\" with PV=\"%s\"?\n",
|
||||
pFileName, pvNameStr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// parse out optional IP port number
|
||||
//
|
||||
unsigned portNumber;
|
||||
if (fscanf(pf, " %u ", &portNumber) == 1) {
|
||||
if (portNumber>0xffff) {
|
||||
fprintf (stderr,"Port number supplied is to large in \"%s\" with PV=\"%s\" host=\"%s\" port=%u?\n",
|
||||
pFileName, pvNameStr, hostNameStr, portNumber);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ipa.sin_port = (aitUint16) portNumber;
|
||||
}
|
||||
else {
|
||||
ipa.sin_port = 0u; // will default to this server's port
|
||||
}
|
||||
|
||||
pPVI = new pvInfo (pvNameStr, ipa);
|
||||
if (!pPVI) {
|
||||
fprintf (stderr, "Unable to allocate space for a new PV in \"%s\" with PV=\"%s\" host=\"%s\"\n",
|
||||
pFileName, pvNameStr, hostNameStr);
|
||||
return -1;
|
||||
}
|
||||
nPV++;
|
||||
}
|
||||
}
|
||||
5
src/cas/example/directoryService/pvDirectory.txt
Normal file
5
src/cas/example/directoryService/pvDirectory.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
ca:ai_2000 ioc3.atdiv.lanl.gov 22000
|
||||
ca:ai_2001 128.165.32.83 22000
|
||||
ca:ao_2000 ioc3
|
||||
ca:ao_2001 128.165.32.83
|
||||
27
src/cas/example/directoryService/templInst.cc
Normal file
27
src/cas/example/directoryService/templInst.cc
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Explcit instantiation of template instances used by the
|
||||
// example server
|
||||
//
|
||||
//
|
||||
|
||||
#include "directoryServer.h"
|
||||
#include "resourceLib.cc"
|
||||
|
||||
//
|
||||
// if the compiler supports explicit instantiation of
|
||||
// template member functions
|
||||
//
|
||||
#if defined(EXPL_TEMPL)
|
||||
//
|
||||
// From Stroustrups's "The C++ Programming Language"
|
||||
// Appendix A: r.14.9
|
||||
//
|
||||
// This explicitly instantiates the template class's
|
||||
// member functions into "templInst.o"
|
||||
//
|
||||
template class resTable <pvEntry,stringId>;
|
||||
#endif
|
||||
|
||||
844
src/cas/example/directoryService/test.adl
Normal file
844
src/cas/example/directoryService/test.adl
Normal file
@@ -0,0 +1,844 @@
|
||||
file {
|
||||
name="test.dl"
|
||||
}
|
||||
display {
|
||||
magic="305419896"
|
||||
majv="2"
|
||||
mnrv="4"
|
||||
ndyng="0"
|
||||
npc="5"
|
||||
nstr="8"
|
||||
ndynamic="12"
|
||||
nplot="0"
|
||||
nrd="0"
|
||||
nes="0"
|
||||
nkd="0"
|
||||
object {
|
||||
x="0"
|
||||
y="0"
|
||||
width="421"
|
||||
height="306"
|
||||
}
|
||||
clr="0"
|
||||
bclr="1"
|
||||
nwords_dspy="1106"
|
||||
nwords_sta="28"
|
||||
nwords_cmap="36"
|
||||
nwords_crules="106"
|
||||
odyng="306"
|
||||
osta="278"
|
||||
odynamic="306"
|
||||
oplot="1106"
|
||||
ord="1106"
|
||||
oes="1106"
|
||||
okd="1106"
|
||||
opc="58"
|
||||
ostr="88"
|
||||
ocmap="136"
|
||||
ocrules="172"
|
||||
style="solid"
|
||||
fill="outline"
|
||||
width="0"
|
||||
clrmod="static"
|
||||
vismod="static"
|
||||
clrrule="alarm"
|
||||
pv=""
|
||||
cmap=""
|
||||
}
|
||||
"<<color map>>" {
|
||||
ncolors="8"
|
||||
dl_color {
|
||||
r="255"
|
||||
g="255"
|
||||
b="255"
|
||||
inten="255"
|
||||
blink="off"
|
||||
RISCpad="128"
|
||||
}
|
||||
dl_color {
|
||||
r="0"
|
||||
g="0"
|
||||
b="0"
|
||||
inten="0"
|
||||
blink="off"
|
||||
RISCpad="75"
|
||||
}
|
||||
dl_color {
|
||||
r="255"
|
||||
g="0"
|
||||
b="0"
|
||||
inten="255"
|
||||
blink="off"
|
||||
RISCpad="-14684"
|
||||
}
|
||||
dl_color {
|
||||
r="255"
|
||||
g="0"
|
||||
b="0"
|
||||
inten="255"
|
||||
blink="on"
|
||||
RISCpad="14744"
|
||||
}
|
||||
dl_color {
|
||||
r="255"
|
||||
g="255"
|
||||
b="0"
|
||||
inten="255"
|
||||
blink="off"
|
||||
RISCpad="-16536"
|
||||
}
|
||||
dl_color {
|
||||
r="255"
|
||||
g="255"
|
||||
b="0"
|
||||
inten="255"
|
||||
blink="on"
|
||||
RISCpad="-15536"
|
||||
}
|
||||
dl_color {
|
||||
r="0"
|
||||
g="0"
|
||||
b="255"
|
||||
inten="255"
|
||||
blink="off"
|
||||
RISCpad="-28408"
|
||||
}
|
||||
dl_color {
|
||||
r="0"
|
||||
g="0"
|
||||
b="255"
|
||||
inten="255"
|
||||
blink="on"
|
||||
RISCpad="0"
|
||||
}
|
||||
}
|
||||
"<<color rules>>" {
|
||||
nrules="1"
|
||||
dl_color_rule {
|
||||
name="alarm"
|
||||
info[0] {
|
||||
chan="$(C).SEVR"
|
||||
value="MAJOR"
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="2"
|
||||
RISCpad="0"
|
||||
}
|
||||
info[1] {
|
||||
chan="$(C).SEVR"
|
||||
value="MINOR"
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="4"
|
||||
RISCpad="127"
|
||||
}
|
||||
info[2] {
|
||||
chan="$(C).SEVR"
|
||||
value="INFO"
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="6"
|
||||
RISCpad="44"
|
||||
}
|
||||
info[3] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="-128"
|
||||
}
|
||||
info[4] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="-1"
|
||||
}
|
||||
info[5] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="-104"
|
||||
}
|
||||
info[6] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="-1"
|
||||
}
|
||||
info[7] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="8"
|
||||
}
|
||||
info[8] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="120"
|
||||
}
|
||||
info[9] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="1"
|
||||
}
|
||||
info[10] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="7"
|
||||
}
|
||||
info[11] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="19"
|
||||
}
|
||||
info[12] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="48"
|
||||
}
|
||||
info[13] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="28"
|
||||
}
|
||||
info[14] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="-88"
|
||||
}
|
||||
info[15] {
|
||||
chan=""
|
||||
value=""
|
||||
connector="use"
|
||||
comparator="equals"
|
||||
clr="1"
|
||||
RISCpad="0"
|
||||
}
|
||||
fg_enable="on"
|
||||
bg_enable="on"
|
||||
default_fg="0"
|
||||
default_bg="1"
|
||||
}
|
||||
}
|
||||
"<<basic attribute>>" {
|
||||
attr {
|
||||
clr="0"
|
||||
style="solid"
|
||||
fill="outline"
|
||||
width="0"
|
||||
}
|
||||
}
|
||||
"text" {
|
||||
object {
|
||||
x="44"
|
||||
y="16"
|
||||
width="104"
|
||||
height="14"
|
||||
groupid="0"
|
||||
}
|
||||
textix="Sync"
|
||||
align="horiz. left"
|
||||
RISC_pad="0"
|
||||
}
|
||||
"text" {
|
||||
object {
|
||||
x="260"
|
||||
y="13"
|
||||
width="92"
|
||||
height="17"
|
||||
groupid="0"
|
||||
}
|
||||
textix="Async"
|
||||
align="horiz. left"
|
||||
RISC_pad="0"
|
||||
}
|
||||
"indicator" {
|
||||
object {
|
||||
x="15"
|
||||
y="88"
|
||||
width="170"
|
||||
height="22"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="fred"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
RISC_pad="0"
|
||||
}
|
||||
"text update" {
|
||||
object {
|
||||
x="16"
|
||||
y="133"
|
||||
width="169"
|
||||
height="17"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="fred"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="none"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="append"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
align="horiz. left"
|
||||
format="decimal"
|
||||
}
|
||||
"valuator" {
|
||||
object {
|
||||
x="15"
|
||||
y="43"
|
||||
width="168"
|
||||
height="26"
|
||||
groupid="0"
|
||||
}
|
||||
control {
|
||||
chan="fred"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
gain="coarse"
|
||||
sendMode="send on motion"
|
||||
increment="0"
|
||||
}
|
||||
"indicator" {
|
||||
object {
|
||||
x="215"
|
||||
y="81"
|
||||
width="170"
|
||||
height="30"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="freddy"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
RISC_pad="0"
|
||||
}
|
||||
"text update" {
|
||||
object {
|
||||
x="216"
|
||||
y="133"
|
||||
width="171"
|
||||
height="18"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="freddy"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="none"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="append"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
align="horiz. left"
|
||||
format="decimal"
|
||||
}
|
||||
"valuator" {
|
||||
object {
|
||||
x="215"
|
||||
y="43"
|
||||
width="168"
|
||||
height="28"
|
||||
groupid="0"
|
||||
}
|
||||
control {
|
||||
chan="freddy"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
gain="coarse"
|
||||
sendMode="send on motion"
|
||||
increment="0"
|
||||
}
|
||||
"indicator" {
|
||||
object {
|
||||
x="16"
|
||||
y="225"
|
||||
width="171"
|
||||
height="19"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="jane"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
RISC_pad="0"
|
||||
}
|
||||
"text update" {
|
||||
object {
|
||||
x="17"
|
||||
y="259"
|
||||
width="170"
|
||||
height="20"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="jane"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="none"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="append"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
align="horiz. left"
|
||||
format="decimal"
|
||||
}
|
||||
"valuator" {
|
||||
object {
|
||||
x="15"
|
||||
y="187"
|
||||
width="170"
|
||||
height="19"
|
||||
groupid="0"
|
||||
}
|
||||
control {
|
||||
chan="jane"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
gain="coarse"
|
||||
sendMode="send on motion"
|
||||
increment="0"
|
||||
}
|
||||
"indicator" {
|
||||
object {
|
||||
x="219"
|
||||
y="218"
|
||||
width="173"
|
||||
height="23"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="janet"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
RISC_pad="0"
|
||||
}
|
||||
"text update" {
|
||||
object {
|
||||
x="220"
|
||||
y="257"
|
||||
width="174"
|
||||
height="20"
|
||||
groupid="0"
|
||||
}
|
||||
monitor {
|
||||
chan="janet"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="none"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="append"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
align="horiz. left"
|
||||
format="decimal"
|
||||
}
|
||||
"valuator" {
|
||||
object {
|
||||
x="219"
|
||||
y="188"
|
||||
width="171"
|
||||
height="21"
|
||||
groupid="0"
|
||||
}
|
||||
control {
|
||||
chan="janet"
|
||||
clr="0"
|
||||
bclr="1"
|
||||
label="limits"
|
||||
clrmod="static"
|
||||
rulechan[0] = ""
|
||||
rulechan[1] = ""
|
||||
rulechan[2] = ""
|
||||
rulechan[3] = ""
|
||||
rulechan[4] = ""
|
||||
rulechan[5] = ""
|
||||
rulechan[6] = ""
|
||||
rulechan[7] = ""
|
||||
rulechan[8] = ""
|
||||
rulechan[9] = ""
|
||||
rulechan[10] = ""
|
||||
rulechan[11] = ""
|
||||
rulechan[12] = ""
|
||||
rulechan[13] = ""
|
||||
rulechan[14] = ""
|
||||
rulechan[15] = ""
|
||||
clrrule="alarm"
|
||||
clrargs=""
|
||||
rulecolorbg="0"
|
||||
rulecolorfg="0"
|
||||
hdl="0"
|
||||
ldl="0"
|
||||
prec="-1"
|
||||
newunits=""
|
||||
units="none"
|
||||
decorate="none"
|
||||
convertFunc=""
|
||||
convertParams=""
|
||||
}
|
||||
direction="down"
|
||||
gain="coarse"
|
||||
sendMode="send on motion"
|
||||
increment="0"
|
||||
}
|
||||
81
src/cas/example/directoryService/vxEntry.cc
Normal file
81
src/cas/example/directoryService/vxEntry.cc
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// $Id$
|
||||
// Author: Jeff HIll (LANL)
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1997/04/10 19:39:26 jhill
|
||||
// API changes
|
||||
//
|
||||
// Revision 1.1 1996/12/06 22:20:22 jhill
|
||||
// moved down one level
|
||||
//
|
||||
// Revision 1.2 1996/09/16 18:22:09 jhill
|
||||
// added cvs log entries
|
||||
//
|
||||
//
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
#include "exServer.h"
|
||||
|
||||
//
|
||||
// so we can call this from the vxWorks shell
|
||||
//
|
||||
extern "C" {
|
||||
|
||||
exServer *pExampleCAS;
|
||||
|
||||
//
|
||||
// excas ()
|
||||
// (vxWorks example server entry point)
|
||||
//
|
||||
int excas (unsigned debugLevel, unsigned delaySec)
|
||||
{
|
||||
osiTime begin(osiTime::getCurrent());
|
||||
exServer *pCAS;
|
||||
|
||||
pCAS = new exServer(32u,5u,500u);
|
||||
if (!pCAS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pCAS->setDebugLevel(debugLevel);
|
||||
pExampleCAS = pCAS;
|
||||
|
||||
if (delaySec==0u) {
|
||||
//
|
||||
// loop here forever
|
||||
//
|
||||
while (1) {
|
||||
taskDelay(10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
osiTime total( ((float)delaySec) );
|
||||
osiTime delay(osiTime::getCurrent() - begin);
|
||||
//
|
||||
// loop here untill the specified execution time
|
||||
// expires
|
||||
//
|
||||
while (delay < total) {
|
||||
taskDelay(10);
|
||||
delay = osiTime::getCurrent() - begin;
|
||||
}
|
||||
}
|
||||
pCAS->show(debugLevel);
|
||||
pExampleCAS = NULL;
|
||||
delete pCAS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int excasShow(unsigned level)
|
||||
{
|
||||
if (pExampleCAS!=NULL) {
|
||||
pExampleCAS->show(level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
9
src/cas/example/iocmonitor/Makefile
Normal file
9
src/cas/example/iocmonitor/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
# $Log$
|
||||
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
include $(TOP)/config/RULES_ARCHS
|
||||
|
||||
23
src/cas/example/iocmonitor/Makefile.Host
Normal file
23
src/cas/example/iocmonitor/Makefile.Host
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
# $Log$
|
||||
|
||||
CAS = ../../..
|
||||
TOP = $(CAS)/../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
PROD_LIBS := cas ca gdd Com
|
||||
|
||||
SRCS += mon.cc monAdl.cc monNode.cc monServer.cc
|
||||
|
||||
PROD := iocMonitor
|
||||
|
||||
include $(TOP)/config/RULES.Host
|
||||
|
||||
clean::
|
||||
@$(RM) iocMonitor
|
||||
@$(RM) -rf Templates.DB
|
||||
@$(RM) core
|
||||
|
||||
343
src/cas/example/iocmonitor/mon.cc
Normal file
343
src/cas/example/iocmonitor/mon.cc
Normal file
@@ -0,0 +1,343 @@
|
||||
|
||||
// Author: Jim Kowalkowski
|
||||
// Date: 1/97
|
||||
//
|
||||
// $Id$
|
||||
// $Log$
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "caProto.h"
|
||||
|
||||
// use lower 11 bits of address as index
|
||||
|
||||
#define ADDR_MASK 0x000007ff
|
||||
#define ADDR_CHECK 10
|
||||
#define ADDR_WARNING 20
|
||||
#define ADDR_DEATH 40
|
||||
#define REPEATER_PORT 5065
|
||||
|
||||
typedef enum { nodeAlive=0, nodeUnknown, nodeDead } nodeState;
|
||||
|
||||
// ----------------------------- host node ------------------------------
|
||||
|
||||
class netNode
|
||||
{
|
||||
public:
|
||||
netNode(unsigned long a,const char* pre);
|
||||
~netNode(void);
|
||||
|
||||
void report(void);
|
||||
void ping(void);
|
||||
nodeState state(void);
|
||||
nodeState state(time_t);
|
||||
|
||||
unsigned long addr;
|
||||
time_t last_ping;
|
||||
const char* name;
|
||||
struct netNode* next;
|
||||
};
|
||||
|
||||
netNode::netNode(unsigned long a,const char* pre)
|
||||
{
|
||||
struct in_addr& in = (struct in_addr&)a;
|
||||
struct hostent* entry;
|
||||
char *n,*x;
|
||||
|
||||
addr=a;
|
||||
time(&last_ping);
|
||||
|
||||
if((entry=gethostbyaddr((char*)&a,sizeof(a),AF_INET))==NULL)
|
||||
n=inet_ntoa(in);
|
||||
else
|
||||
n=entry->h_name;
|
||||
|
||||
x=new char[strlen(n)+1+strlen(pre)];
|
||||
strcpy(x,pre);
|
||||
strcat(x,n);
|
||||
name=x;
|
||||
next=NULL;
|
||||
}
|
||||
|
||||
netNode::~netNode(void)
|
||||
{
|
||||
char* n = (char*)name;
|
||||
delete [] n;
|
||||
}
|
||||
|
||||
void netNode::ping(void)
|
||||
{
|
||||
time(&last_ping);
|
||||
}
|
||||
|
||||
nodeState netNode::state(void)
|
||||
{
|
||||
time_t t;
|
||||
time(&t);
|
||||
return state(t);
|
||||
}
|
||||
|
||||
nodeState netNode::state(time_t t)
|
||||
{
|
||||
nodeState s;
|
||||
time_t x;
|
||||
x=t-last_ping;
|
||||
if(x<ADDR_WARNING)
|
||||
s=nodeAlive;
|
||||
else if(x<ADDR_DEATH)
|
||||
s=nodeUnknown;
|
||||
else
|
||||
s=nodeDead;
|
||||
return s;
|
||||
}
|
||||
|
||||
void netNode::report(void)
|
||||
{
|
||||
switch(state())
|
||||
{
|
||||
case nodeDead: printf(" IOC %s Dead\n",name); break;
|
||||
case nodeAlive: printf(" IOC %s Alive\n",name); break;
|
||||
case nodeUnknown: printf(" IOC %s Unknown\n",name); break;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------- database ---------------------------
|
||||
|
||||
class addrDb
|
||||
{
|
||||
public:
|
||||
addrDb(const char* p);
|
||||
~addrDb(void);
|
||||
|
||||
void report(void);
|
||||
netNode* findNode(unsigned long addr);
|
||||
netNode* addNode(unsigned long addr);
|
||||
private:
|
||||
const char* prefix;
|
||||
netNode** db;
|
||||
};
|
||||
|
||||
addrDb::addrDb(const char* p)
|
||||
{
|
||||
int i;
|
||||
const char* x = p?p:"_";
|
||||
char* y;
|
||||
y=new char[strlen(x)+1];
|
||||
strcpy(y,x);
|
||||
prefix=y;
|
||||
db=new netNode*[ADDR_MASK];
|
||||
for(i=0;i<ADDR_MASK;i++) db[i]=NULL;
|
||||
}
|
||||
|
||||
addrDb::~addrDb(void)
|
||||
{
|
||||
int i;
|
||||
netNode *c,*p;
|
||||
for(i=0;i<ADDR_MASK;i++)
|
||||
{
|
||||
for(c=db[i];c;)
|
||||
{
|
||||
p=c->next;
|
||||
delete c;
|
||||
c=p;
|
||||
}
|
||||
}
|
||||
delete [] db;
|
||||
}
|
||||
|
||||
void addrDb::report(void)
|
||||
{
|
||||
int i;
|
||||
netNode* n;
|
||||
for(i=0;i<ADDR_MASK;i++)
|
||||
{
|
||||
for(n=db[i];n;n=n->next)
|
||||
n->report();
|
||||
}
|
||||
}
|
||||
|
||||
netNode* addrDb::findNode(unsigned long addr)
|
||||
{
|
||||
netNode* t;
|
||||
for(t=db[addr&ADDR_MASK];t && t->addr!=addr;t=t->next);
|
||||
return t;
|
||||
}
|
||||
|
||||
netNode* addrDb::addNode(unsigned long addr)
|
||||
{
|
||||
unsigned long i;
|
||||
netNode* t;
|
||||
if((t=findNode(addr))==NULL)
|
||||
{
|
||||
i=addr&ADDR_MASK;
|
||||
t=new netNode(addr,prefix);
|
||||
t->next=db[i];
|
||||
db[i]=t;
|
||||
}
|
||||
else
|
||||
t->ping();
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
addrDb* db;
|
||||
|
||||
int main(int argc, char* argv[] )
|
||||
{
|
||||
caHdr msg;
|
||||
struct sockaddr_in tsin;
|
||||
struct sockaddr ssin;
|
||||
struct timeval tout;
|
||||
struct hostent* entry;
|
||||
fd_set fds;
|
||||
char* name;
|
||||
netNode* node;
|
||||
int soc,retry,done,rlen,len;
|
||||
unsigned short cmd;
|
||||
unsigned long* iaddr;
|
||||
time_t curr,last;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
fprintf(stderr,"Must enter a prefix for PVs on command line\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
db=new addrDb(argv[1]);
|
||||
|
||||
tsin.sin_port=htons(0);
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((soc=socket(AF_INET,SOCK_DGRAM,17))<0)
|
||||
{
|
||||
perror("open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(soc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("local bind failed to soc failed");
|
||||
close(soc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset((char*)&msg,0,sizeof(msg));
|
||||
msg.m_cmmd = htons(REPEATER_REGISTER);
|
||||
msg.m_available = tsin.sin_addr.s_addr;
|
||||
tsin.sin_port=htons(REPEATER_PORT);
|
||||
|
||||
for(done=0,retry=0;done==0 && retry<3;retry++)
|
||||
{
|
||||
if(sendto(soc,(char*)&msg,sizeof(msg),0,
|
||||
(struct sockaddr*)&tsin,sizeof(tsin))<0)
|
||||
{
|
||||
perror("sendto failed");
|
||||
close(soc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc,&fds);
|
||||
tout.tv_sec=0;
|
||||
tout.tv_usec=500000;
|
||||
|
||||
switch(select(FD_SETSIZE,&fds,NULL,NULL,&tout))
|
||||
{
|
||||
case -1: /* bad */
|
||||
perror("first select failed");
|
||||
return -1;
|
||||
case 0: /* timeout */
|
||||
break;
|
||||
default: /* data ready */
|
||||
done=1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done==1)
|
||||
{
|
||||
rlen=0;
|
||||
if((len=recvfrom(soc,(char*)&msg,sizeof(msg),0,&ssin,&rlen))<0)
|
||||
{
|
||||
perror("first recvfrom failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd=ntohs(msg.m_cmmd);
|
||||
|
||||
if(cmd==REPEATER_CONFIRM)
|
||||
printf("Connected to repeater\n");
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to repeater (%d)\n",(int)cmd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to repeater\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------- ready ---------------- */
|
||||
last=0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc,&fds);
|
||||
tout.tv_sec=ADDR_CHECK;
|
||||
tout.tv_usec=0;
|
||||
|
||||
switch(select(FD_SETSIZE,&fds,NULL,NULL,&tout))
|
||||
{
|
||||
case -1: /* bad */
|
||||
perror("main select failed");
|
||||
case 0: /* timeout */
|
||||
// db->report();
|
||||
break;
|
||||
default: /* data ready */
|
||||
{
|
||||
if((len=recvfrom(soc,(char*)&msg,sizeof(msg),0,&ssin,&rlen))<0)
|
||||
{
|
||||
perror("first recvfrom failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
iaddr=(unsigned long*)&msg.m_available;
|
||||
node=db->addNode(*iaddr);
|
||||
|
||||
// cmd=ntohs(msg.m_cmmd);
|
||||
// if(cmd==CA_PROTO_RSRV_IS_UP)
|
||||
// {
|
||||
// printf("Alive\n");
|
||||
// }
|
||||
// else
|
||||
// printf("Unidentified Command from 0x%8.8x\n",*iaddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
time(&curr);
|
||||
if((curr-last)>=ADDR_CHECK)
|
||||
{
|
||||
db->report();
|
||||
last=curr;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
95
src/cas/example/iocmonitor/monAdl.cc
Normal file
95
src/cas/example/iocmonitor/monAdl.cc
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
// Author: Jim Kowalkowski
|
||||
// Date: 1/97
|
||||
//
|
||||
// $Id$
|
||||
// $Log$
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "monNode.h"
|
||||
#include "monServer.h"
|
||||
|
||||
#define WIDTH 180
|
||||
#define HEIGHT 10
|
||||
#define MAX_WIDTH 1000
|
||||
#define MAX_HEIGHT 700
|
||||
#define TOTAL_X (MAX_WIDTH/WIDTH)
|
||||
#define TOTAL_Y (MAX_HEIGHT/HEIGHT)
|
||||
|
||||
int monAdl(monNode** head, char* fname,const char* prefix)
|
||||
{
|
||||
FILE *fdout;
|
||||
int dh;
|
||||
int i,j,k;
|
||||
monNode* node;
|
||||
|
||||
if((fdout=fopen(fname,"w"))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot open the ADL file %s\n",fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dh=monNode::total/TOTAL_X;
|
||||
if((dh*TOTAL_X)!=monNode::total) ++dh;
|
||||
|
||||
fprintf(fdout,"\nfile { name=\"ioc_status.adl\" version=020209 }\n");
|
||||
fprintf(fdout,"display {\n");
|
||||
fprintf(fdout," object { x=0 y=0 width=%d height=%d }\n",
|
||||
MAX_WIDTH,dh*HEIGHT+40);
|
||||
fprintf(fdout," clr=37 bclr=14 cmap=\"\"\n}\n");
|
||||
|
||||
fprintf(fdout,"\"color map\" { ncolors=65 colors {\n");
|
||||
fprintf(fdout,"ffffff, ececec, dadada, c8c8c8, bbbbbb, aeaeae, 9e9e9e,\n");
|
||||
fprintf(fdout,"919191, 858585, 787878, 696969, 5a5a5a, 464646, 2d2d2d,\n");
|
||||
fprintf(fdout,"000000, 00d800, 1ebb00, 339900, 2d7f00, 216c00, fd0000,\n");
|
||||
fprintf(fdout,"de1309, be190b, a01207, 820400, 5893ff, 597ee1, 4b6ec7,\n");
|
||||
fprintf(fdout,"3a5eab, 27548d, fbf34a, f9da3c, eeb62b, e19015, cd6100,\n");
|
||||
fprintf(fdout,"ffb0ff, d67fe2, ae4ebc, 8b1a96, 610a75, a4aaff, 8793e2,\n");
|
||||
fprintf(fdout,"6a73c1, 4d52a4, 343386, c7bb6d, b79d5c, a47e3c, 7d5627,\n");
|
||||
fprintf(fdout,"58340f, 99ffff, 73dfff, 4ea5f9, 2a63e4, 0a00b8, ebf1b5,\n");
|
||||
fprintf(fdout,"d4db9d, bbc187, a6a462, 8b8239, 73ff6b, 52da3b, 3cb420,\n");
|
||||
fprintf(fdout,"289315, 1a7309,\n");
|
||||
fprintf(fdout,"} }\n");
|
||||
|
||||
// ----------------------- heading ----------------------------------
|
||||
i=(MAX_WIDTH/2)-(300/2);
|
||||
fprintf(fdout," text { object { x=%d y=2 width=300 height=25 }\n",i);
|
||||
fprintf(fdout," \"basic attribute\" { clr=37 }\n");
|
||||
fprintf(fdout," textix=\"%d IOC STATUS MONITOR\"\n",monNode::total);
|
||||
fprintf(fdout," align=\"horiz. centered\"\n}\n");
|
||||
|
||||
// ---------------------- generate new file button -------------------
|
||||
fprintf(fdout,"\"message button\" { object\n");
|
||||
fprintf(fdout," { x=%d y=2 width=180 height=22 }\n",MAX_WIDTH-180);
|
||||
fprintf(fdout," control { chan=\"%smakeScreen\" clr=31 bclr=47 }\n",prefix);
|
||||
fprintf(fdout," label=\"Make New Screen\" press_msg=\"1\"\n}\n");
|
||||
|
||||
fprintf(fdout,"\"text update\" { object { x=1 y=2 width=180 height=22 }\n");
|
||||
fprintf(fdout," monitor { chan=\"%siocCount\" clr=31 bclr=14 }\n",prefix);
|
||||
fprintf(fdout,"}\n");
|
||||
|
||||
// -------------- make all the buttons
|
||||
i=0;j=0;
|
||||
for(k=0;k<ADDR_TOTAL;k++)
|
||||
{
|
||||
for(node=head[k];node;node=node->next)
|
||||
{
|
||||
fprintf(fdout,"\"text update\" {\n");
|
||||
fprintf(fdout," object { x=%d y=%d width=%d height=%d }\n",
|
||||
i*WIDTH,j*HEIGHT+30,WIDTH,HEIGHT);
|
||||
|
||||
if(++i>=TOTAL_X) { i=0; ++j; }
|
||||
|
||||
fprintf(fdout," monitor { chan=\"%s\" clr=0 bclr=14 }\n",
|
||||
node->name);
|
||||
fprintf(fdout," clrmod=\"alarm\"\n}\n");
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
283
src/cas/example/iocmonitor/monNode.cc
Normal file
283
src/cas/example/iocmonitor/monNode.cc
Normal file
@@ -0,0 +1,283 @@
|
||||
|
||||
// Author: Jim Kowalkowski
|
||||
// Date: 1/97
|
||||
//
|
||||
// $Id$
|
||||
// $Log$
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "gddAppTable.h"
|
||||
#include "monServer.h"
|
||||
#include "monNode.h"
|
||||
|
||||
// --------------------------- monPv ----------------------------
|
||||
|
||||
monPv::monPv(const casCtx& c,monServer& s,monNode* n,const char* name):
|
||||
casPV(c,name),node(n),mrg(s)
|
||||
{
|
||||
monDebug1(5,"monPV: Creating PV for %s\n",name);
|
||||
data=NULL;
|
||||
markNotInterested();
|
||||
node->setPv(this);
|
||||
}
|
||||
|
||||
monPv::~monPv(void)
|
||||
{
|
||||
node->clearPv();
|
||||
if(data) data->unreference();
|
||||
monDebug1(5,"monPV: Deleting PV for %s\n",node->name);
|
||||
}
|
||||
|
||||
unsigned monPv::maxSimultAsyncOps(void) const { return 5000u; }
|
||||
void monPv::interestDelete(void) { markNotInterested(); }
|
||||
aitEnum monPv::bestExternalType(void) const { return aitEnumString; }
|
||||
unsigned monPv::maxDimension(void) const { return 0; }
|
||||
aitIndex monPv::maxBound(unsigned dim) const { return 0; }
|
||||
void monPv::destroy(void) { casPV::destroy(); }
|
||||
|
||||
caStatus monPv::interestRegister(void)
|
||||
{
|
||||
markInterested();
|
||||
return S_casApp_success;
|
||||
}
|
||||
|
||||
caStatus monPv::read(const casCtx& ctx, gdd& dd)
|
||||
{
|
||||
monDebug1(5,"monPV: Read PV data=0x%8.8x\n",(int)data);
|
||||
gddApplicationTypeTable& table=gddApplicationTypeTable::AppTable();
|
||||
if(data) table.smartCopy(&dd,data);
|
||||
return S_casApp_success;
|
||||
}
|
||||
|
||||
caStatus monPv::write(const casCtx& /*ctx*/, gdd& /*dd*/)
|
||||
{
|
||||
// cannot write to these PVs
|
||||
return S_casApp_success;
|
||||
}
|
||||
|
||||
void monPv::eventData(void)
|
||||
{
|
||||
struct tm* t;
|
||||
char val[40];
|
||||
char str[10];
|
||||
aitTimeStamp stamp(node->state_ping,0);
|
||||
|
||||
// prepare a new gdd used for posting and reads
|
||||
if(data) data->unreference();
|
||||
data=new gddScalar(mrg.appValue,aitEnumString);
|
||||
t=localtime(&node->state_ping);
|
||||
|
||||
switch(node->state())
|
||||
{
|
||||
case monAlive:
|
||||
strcpy(str,"Up");
|
||||
data->setStatSevr(0,NO_ALARM);
|
||||
break;
|
||||
case monUnknown:
|
||||
strcpy(str,"?");
|
||||
data->setStatSevr(TIMEOUT_ALARM,MINOR_ALARM);
|
||||
break;
|
||||
case monDead:
|
||||
strcpy(str,"Down");
|
||||
data->setStatSevr(COMM_ALARM,MAJOR_ALARM);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
sprintf(val,"(%s %s %2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d)",
|
||||
&node->name[mrg.prefix_length],str,
|
||||
t->tm_mon+1,t->tm_mday,t->tm_year,t->tm_hour,t->tm_min,t->tm_sec);
|
||||
*/
|
||||
sprintf(val,"(%2.2d/%2.2d %2.2d:%2.2d:%2.2d %s)",
|
||||
t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec,
|
||||
&node->name[mrg.prefix_length]);
|
||||
|
||||
data->reference();
|
||||
data->setTimeStamp(&stamp);
|
||||
data->put(val);
|
||||
|
||||
monDebug1(5,"monPV: eventData data=0x%8.8x\n",(int)data);
|
||||
if(debugLevel>6) data->dump();
|
||||
|
||||
if(isMonitored())
|
||||
{
|
||||
monDebug0(5,"monPV: PV monitored\n");
|
||||
casEventMask select(
|
||||
mrg.alarmEventMask|mrg.valueEventMask|mrg.logEventMask);
|
||||
postEvent(select,*data);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------- monNode ----------------------------
|
||||
|
||||
monNode::monNode(unsigned long a,const char* prefix)
|
||||
{
|
||||
struct in_addr& in = (struct in_addr&)a;
|
||||
struct hostent* entry;
|
||||
char *n,*x;
|
||||
|
||||
addr=a;
|
||||
time(&last_ping);
|
||||
state_ping=last_ping;
|
||||
|
||||
if((entry=gethostbyaddr((char*)&a,sizeof(a),AF_INET))==NULL)
|
||||
n=inet_ntoa(in);
|
||||
else
|
||||
n=entry->h_name;
|
||||
|
||||
x=new char[strlen(n)+1+strlen(prefix)];
|
||||
strcpy(x,prefix);
|
||||
strcat(x,n);
|
||||
name=x;
|
||||
next=NULL;
|
||||
pv=NULL;
|
||||
last_state=monAlive;
|
||||
++monNode::total;
|
||||
monDebug1(5,"monNode: Created node %s\n",name);
|
||||
}
|
||||
|
||||
monNode::~monNode(void)
|
||||
{
|
||||
monDebug1(5,"monNode: Deleted node %s\n",name);
|
||||
char* n = (char*)name;
|
||||
delete [] n;
|
||||
}
|
||||
|
||||
int monNode::total=0;
|
||||
|
||||
void monNode::ping(void)
|
||||
{
|
||||
time(&last_ping);
|
||||
}
|
||||
|
||||
monState monNode::state(void)
|
||||
{
|
||||
return last_state;
|
||||
}
|
||||
|
||||
monState monNode::state(time_t t)
|
||||
{
|
||||
monState s;
|
||||
time_t x;
|
||||
x=t-last_ping;
|
||||
if(x<ADDR_WARNING)
|
||||
s=monAlive;
|
||||
else if(x<ADDR_DEATH)
|
||||
s=monUnknown;
|
||||
else
|
||||
s=monDead;
|
||||
return s;
|
||||
}
|
||||
|
||||
void monNode::check(time_t t)
|
||||
{
|
||||
monState s = state(t);
|
||||
monDebug1(9,"monNode: Checking node %s\n",name);
|
||||
|
||||
if(s!=last_state)
|
||||
{
|
||||
last_state=s;
|
||||
// only change boot time if going from/to dead
|
||||
if(s==monDead || last_state==monDead) state_ping=t;
|
||||
if(pv) pv->eventData();
|
||||
}
|
||||
}
|
||||
|
||||
void monNode::setPv(monPv* p)
|
||||
{
|
||||
int need;
|
||||
monDebug1(9,"monNode: Setting PV for %s\n",name);
|
||||
|
||||
if(pv==NULL)
|
||||
need=1;
|
||||
else
|
||||
need=0;
|
||||
|
||||
pv=p;
|
||||
if(need) pv->eventData();
|
||||
}
|
||||
|
||||
void monNode::clearPv(void) { pv=NULL; }
|
||||
|
||||
void monNode::report(FILE* fd)
|
||||
{
|
||||
struct in_addr* ia = (struct in_addr*)&addr;
|
||||
switch(state())
|
||||
{
|
||||
case monDead:
|
||||
fprintf(fd,"%s %s Dead\n",name,inet_ntoa(*ia));
|
||||
break;
|
||||
case monAlive:
|
||||
fprintf(fd,"%s %s Alive\n",name,inet_ntoa(*ia));
|
||||
break;
|
||||
case monUnknown:
|
||||
fprintf(fd,"%s %s Unknown\n",name,inet_ntoa(*ia));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- status PVs -----------------------
|
||||
|
||||
makeScreenPV::~makeScreenPV(void) { }
|
||||
aitEnum makeScreenPV::bestExternalType(void) const { return aitEnumInt32; }
|
||||
|
||||
caStatus makeScreenPV::read(const casCtx& /*ctx*/, gdd& /*dd*/)
|
||||
{
|
||||
return S_casApp_success;
|
||||
}
|
||||
|
||||
caStatus makeScreenPV::write(const casCtx& /*ctx*/, gdd& /*dd*/)
|
||||
{
|
||||
mrg.makeADL();
|
||||
return S_casApp_success; // cannot write to these PVs
|
||||
}
|
||||
|
||||
// -------------
|
||||
|
||||
iocCountPV::~iocCountPV(void) { mrg.count_pv=NULL; }
|
||||
void iocCountPV::interestDelete(void) { monitored=0; }
|
||||
|
||||
aitEnum iocCountPV::bestExternalType(void) const { return aitEnumInt32; }
|
||||
|
||||
void iocCountPV::postValue(void)
|
||||
{
|
||||
gdd* value=new gddScalar(mrg.appValue,aitEnumInt32);
|
||||
value->put(monNode::total);
|
||||
|
||||
if(monitored)
|
||||
{
|
||||
casEventMask select(
|
||||
mrg.alarmEventMask|mrg.valueEventMask|mrg.logEventMask);
|
||||
postEvent(select,*value);
|
||||
}
|
||||
}
|
||||
|
||||
caStatus iocCountPV::interestRegister(void)
|
||||
{
|
||||
monitored=1;
|
||||
return S_casApp_success;
|
||||
}
|
||||
|
||||
|
||||
caStatus iocCountPV::read(const casCtx& ctx, gdd& dd)
|
||||
{
|
||||
// this is bad, should check for dd to be scalar, if it is not a scalar,
|
||||
// then find the value gdd within the container
|
||||
dd.put(monNode::total);
|
||||
return S_casApp_success;
|
||||
}
|
||||
|
||||
caStatus iocCountPV::write(const casCtx& /*ctx*/, gdd& /*dd*/)
|
||||
{
|
||||
return S_casApp_success; // cannot write to these PVs
|
||||
}
|
||||
|
||||
118
src/cas/example/iocmonitor/monNode.h
Normal file
118
src/cas/example/iocmonitor/monNode.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#ifndef MONNODE_H
|
||||
#define MONNODE_H
|
||||
|
||||
/*
|
||||
* Author: Jim Kowalkowski
|
||||
* Date: 1/97
|
||||
*
|
||||
* $Id$
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "aitTypes.h"
|
||||
#include "casdef.h"
|
||||
|
||||
typedef enum { monAlive=0, monUnknown, monDead } monState;
|
||||
|
||||
#define ADDR_CHECK 10
|
||||
#define ADDR_WARNING 20
|
||||
#define ADDR_DEATH 40
|
||||
|
||||
class monNode;
|
||||
class monServer;
|
||||
class gdd;
|
||||
|
||||
class monPv : public casPV
|
||||
{
|
||||
public:
|
||||
monPv(const casCtx&,monServer&,monNode*,const char* pv_name);
|
||||
virtual ~monPv(void);
|
||||
|
||||
// CA server interface functions
|
||||
virtual caStatus interestRegister(void);
|
||||
virtual void interestDelete(void);
|
||||
virtual aitEnum bestExternalType(void) const;
|
||||
virtual caStatus read(const casCtx &ctx, gdd &prototype);
|
||||
virtual caStatus write(const casCtx &ctx, gdd &value);
|
||||
virtual void destroy(void);
|
||||
virtual unsigned maxSimultAsyncOps(void) const;
|
||||
virtual unsigned maxDimension(void) const;
|
||||
virtual aitIndex maxBound(unsigned dim) const;
|
||||
|
||||
void eventData(void);
|
||||
|
||||
void markInterested(void) { monitor=1; }
|
||||
void markNotInterested(void) { monitor=0; }
|
||||
int isMonitored(void) { return monitor; }
|
||||
|
||||
monServer& mrg;
|
||||
monNode* node;
|
||||
int monitor;
|
||||
gdd* data;
|
||||
};
|
||||
|
||||
class monNode
|
||||
{
|
||||
public:
|
||||
monNode(unsigned long a, const char* prefix);
|
||||
~monNode(void);
|
||||
|
||||
void report(FILE*);
|
||||
void ping(void);
|
||||
void check(time_t);
|
||||
monState state(void);
|
||||
monState state(time_t);
|
||||
void setPv(monPv*);
|
||||
void clearPv(void);
|
||||
|
||||
unsigned long addr;
|
||||
time_t last_ping;
|
||||
time_t state_ping;
|
||||
const char* name;
|
||||
monPv* pv;
|
||||
monNode* next;
|
||||
monState last_state;
|
||||
static int total;
|
||||
};
|
||||
|
||||
// ---------------------------- status PVs --------------------------
|
||||
|
||||
class makeScreenPV : public casPV
|
||||
{
|
||||
public:
|
||||
makeScreenPV(const casCtx& c,const char* pv_name,monServer& s):
|
||||
casPV(c,pv_name),mrg(s){}
|
||||
virtual ~makeScreenPV(void);
|
||||
|
||||
// CA server interface functions
|
||||
virtual aitEnum bestExternalType(void) const;
|
||||
virtual caStatus read(const casCtx &ctx, gdd &prototype);
|
||||
virtual caStatus write(const casCtx &ctx, gdd &value);
|
||||
|
||||
monServer& mrg;
|
||||
};
|
||||
|
||||
class iocCountPV : public casPV
|
||||
{
|
||||
public:
|
||||
iocCountPV(const casCtx& c,const char* pv_name,monServer& s):
|
||||
casPV(c,pv_name),mrg(s),monitored(0) {}
|
||||
virtual ~iocCountPV(void);
|
||||
|
||||
// CA server interface functions
|
||||
virtual caStatus interestRegister(void);
|
||||
virtual void interestDelete(void);
|
||||
virtual aitEnum bestExternalType(void) const;
|
||||
virtual caStatus read(const casCtx &ctx, gdd &prototype);
|
||||
virtual caStatus write(const casCtx &ctx, gdd &value);
|
||||
|
||||
void postValue(void);
|
||||
|
||||
int monitored;
|
||||
monServer& mrg;
|
||||
};
|
||||
|
||||
#endif
|
||||
358
src/cas/example/iocmonitor/monServer.cc
Normal file
358
src/cas/example/iocmonitor/monServer.cc
Normal file
@@ -0,0 +1,358 @@
|
||||
|
||||
// Author: Jim Kowalkowski
|
||||
// Date: 1/97
|
||||
//
|
||||
// $Id$
|
||||
// $Log$
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "caProto.h"
|
||||
#include "gddAppTable.h"
|
||||
|
||||
#include "monServer.h"
|
||||
#include "monNode.h"
|
||||
|
||||
int debugLevel=0;
|
||||
int makeReport=0;
|
||||
int keepGoing=1;
|
||||
|
||||
typedef void (*SIG_FUNC)(int);
|
||||
|
||||
static SIG_FUNC save_hup = NULL;
|
||||
static SIG_FUNC save_int = NULL;
|
||||
static SIG_FUNC save_term = NULL;
|
||||
static SIG_FUNC save_usr1 = NULL;
|
||||
|
||||
static void sig_end(int)
|
||||
{
|
||||
signal(SIGHUP,sig_end);
|
||||
signal(SIGTERM,sig_end);
|
||||
signal(SIGINT,sig_end);
|
||||
keepGoing=0;
|
||||
}
|
||||
static void sig_usr1(int) { makeReport=1; signal(SIGUSR1,sig_usr1); }
|
||||
|
||||
extern int monAdl(monNode**,char*,const char*);
|
||||
|
||||
// ------------------------- file descriptor servicing ----------------------
|
||||
|
||||
monFd::~monFd(void) { }
|
||||
void monFd::callBack(void) { server.dataReady(); }
|
||||
|
||||
// -------------------------- server -----------------------------
|
||||
|
||||
monServer::monServer(unsigned namelen,unsigned pvcount,unsigned simio,
|
||||
const char* p):caServer(namelen,pvcount,simio)
|
||||
{
|
||||
int i;
|
||||
count_pv=NULL;
|
||||
const char* x = p?p:"_";
|
||||
prefix=new char[strlen(x)+1];
|
||||
strcpy(prefix,x);
|
||||
prefix_length=strlen(prefix);
|
||||
soc_fd=NULL;
|
||||
db=new monNode*[ADDR_TOTAL];
|
||||
for(i=0;i<ADDR_TOTAL;i++) db[i]=NULL;
|
||||
|
||||
gddApplicationTypeTable& tt = gddApplicationTypeTable::AppTable();
|
||||
appValue=tt.getApplicationType("value");
|
||||
|
||||
sprintf(ioc_count_name,"%siocCount",prefix);
|
||||
sprintf(make_screen_name,"%smakeScreen",prefix);
|
||||
}
|
||||
|
||||
monServer::~monServer(void)
|
||||
{
|
||||
int i;
|
||||
monNode *c,*p;
|
||||
for(i=0;i<ADDR_TOTAL;i++)
|
||||
{
|
||||
for(c=db[i];c;)
|
||||
{
|
||||
p=c->next;
|
||||
delete c;
|
||||
c=p;
|
||||
}
|
||||
}
|
||||
delete [] db;
|
||||
}
|
||||
|
||||
void monServer::report(FILE* fd)
|
||||
{
|
||||
int i;
|
||||
monNode* n;
|
||||
for(i=0;i<ADDR_TOTAL;i++)
|
||||
{
|
||||
for(n=db[i];n;n=n->next)
|
||||
n->report(fd);
|
||||
}
|
||||
}
|
||||
|
||||
monNode* monServer::findNode(unsigned long addr)
|
||||
{
|
||||
monNode* t;
|
||||
for(t=db[addr&ADDR_MASK];t && t->addr!=addr;t=t->next);
|
||||
return t;
|
||||
}
|
||||
|
||||
monNode* monServer::addNode(unsigned long addr)
|
||||
{
|
||||
unsigned long i;
|
||||
monNode* t;
|
||||
if((t=findNode(addr))==NULL)
|
||||
{
|
||||
i=addr&ADDR_MASK;
|
||||
t=new monNode(addr,prefix);
|
||||
t->next=db[i];
|
||||
db[i]=t;
|
||||
pv_list.add(t->name,*t);
|
||||
if(count_pv) count_pv->postValue();
|
||||
}
|
||||
else
|
||||
t->ping();
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void monServer::checkEvent(void)
|
||||
{
|
||||
// go through all the nodes and send out monitors on PV if required
|
||||
time_t t;
|
||||
int i;
|
||||
monNode* n;
|
||||
time(&t);
|
||||
|
||||
for(i=0;i<ADDR_TOTAL;i++)
|
||||
{
|
||||
for(n=db[i];n;n=n->next)
|
||||
n->check(t);
|
||||
}
|
||||
}
|
||||
|
||||
pvExistReturn monServer::pvExistTest(const casCtx& c,const char* pvname)
|
||||
{
|
||||
monNode* node;
|
||||
|
||||
if(strcmp(pvname,ioc_count_name)==0)
|
||||
return pvExistReturn(S_casApp_success,ioc_count_name);
|
||||
|
||||
if(strcmp(pvname,make_screen_name)==0)
|
||||
return pvExistReturn(S_casApp_success,make_screen_name);
|
||||
|
||||
if(pv_list.find(pvname,node)==0)
|
||||
return pvExistReturn(S_casApp_success,node->name);
|
||||
else
|
||||
return pvExistReturn(S_casApp_pvNotFound);
|
||||
}
|
||||
|
||||
casPV* monServer::createPV(const casCtx& c,const char* pvname)
|
||||
{
|
||||
monNode* node;
|
||||
|
||||
if(strcmp(pvname,ioc_count_name)==0)
|
||||
return count_pv=new iocCountPV(c,pvname,*this);
|
||||
|
||||
if(strcmp(pvname,make_screen_name)==0)
|
||||
return new makeScreenPV(c,pvname,*this);
|
||||
|
||||
if(pv_list.find(pvname,node)==0)
|
||||
return new monPv(c,*this,node,pvname);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int monServer::repeaterConnect(void)
|
||||
{
|
||||
caHdr msg;
|
||||
struct sockaddr_in tsin;
|
||||
struct sockaddr ssin;
|
||||
struct timeval tout;
|
||||
fd_set fds;
|
||||
int retry,done,rlen,len;
|
||||
|
||||
tsin.sin_port=htons(0);
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((soc=socket(AF_INET,SOCK_DGRAM,17))<0)
|
||||
{
|
||||
perror("open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(soc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("local bind failed to soc failed");
|
||||
close(soc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset((char*)&msg,0,sizeof(msg));
|
||||
msg.m_cmmd = htons(REPEATER_REGISTER);
|
||||
msg.m_available = tsin.sin_addr.s_addr;
|
||||
tsin.sin_port=htons(REPEATER_PORT);
|
||||
|
||||
for(done=0,retry=0;done==0 && retry<3;retry++)
|
||||
{
|
||||
if(sendto(soc,(char*)&msg,sizeof(msg),0,
|
||||
(struct sockaddr*)&tsin,sizeof(tsin))<0)
|
||||
{
|
||||
perror("sendto failed");
|
||||
close(soc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc,&fds);
|
||||
tout.tv_sec=0;
|
||||
tout.tv_usec=500000;
|
||||
|
||||
switch(select(FD_SETSIZE,&fds,NULL,NULL,&tout))
|
||||
{
|
||||
case -1: /* bad */
|
||||
perror("first select failed");
|
||||
return -1;
|
||||
case 0: /* timeout */
|
||||
break;
|
||||
default: /* data ready */
|
||||
done=1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done==1)
|
||||
{
|
||||
rlen=0;
|
||||
if((len=recvfrom(soc,(char*)&msg,sizeof(msg),0,&ssin,&rlen))<0)
|
||||
{
|
||||
perror("first recvfrom failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ntohs(msg.m_cmmd)==REPEATER_CONFIRM)
|
||||
printf("Connected to repeater\n");
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to repeater (%d)\n",(int)ntohs(msg.m_cmmd));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to repeater\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
soc_fd=new monFd(soc,fdrRead,*this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void monServer::dataReady(void)
|
||||
{
|
||||
caHdr msg;
|
||||
struct sockaddr ssin;
|
||||
monNode* node;
|
||||
int rlen,len;
|
||||
unsigned long* iaddr;
|
||||
|
||||
rlen=0;
|
||||
if((len=recvfrom(soc,(char*)&msg,sizeof(msg),0,&ssin,&rlen))<0)
|
||||
{
|
||||
perror("first recvfrom failed");
|
||||
}
|
||||
else if(ntohs(msg.m_cmmd)==CA_PROTO_RSRV_IS_UP)
|
||||
{
|
||||
iaddr=(unsigned long*)&msg.m_available;
|
||||
node=addNode(*iaddr);
|
||||
}
|
||||
}
|
||||
|
||||
void monServer::mainLoop(void)
|
||||
{
|
||||
osiTime delay(ADDR_CHECK,0u);
|
||||
time_t curr,prev;
|
||||
|
||||
if(repeaterConnect()<0) return;
|
||||
|
||||
prev=0;
|
||||
while(keepGoing)
|
||||
{
|
||||
fileDescriptorManager.process(delay);
|
||||
time(&curr);
|
||||
if((curr-prev)>=ADDR_CHECK)
|
||||
{
|
||||
checkEvent();
|
||||
prev=curr;
|
||||
}
|
||||
|
||||
if(makeReport)
|
||||
{
|
||||
FILE* fd;
|
||||
if((fd=fopen("PV_REPORT","w")))
|
||||
{
|
||||
report(fd);
|
||||
fclose(fd);
|
||||
}
|
||||
makeADL();
|
||||
makeReport=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void monServer::makeADL(void) { monAdl(db,"ioc_status.adl",prefix); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if(argc<2)
|
||||
{
|
||||
fprintf(stderr,"Must enter a prefix for PVs on command line\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(argc==3) sscanf(argv[2],"%d",&debugLevel);
|
||||
|
||||
// disassociate from parent
|
||||
switch(fork())
|
||||
{
|
||||
case -1: // error
|
||||
perror("Cannot create gateway processes");
|
||||
return -1;
|
||||
case 0: // child
|
||||
#if defined linux || defined SOLARIS
|
||||
setpgrp();
|
||||
#else
|
||||
setpgrp(0,0);
|
||||
#endif
|
||||
setsid();
|
||||
break;
|
||||
default: // parent
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
save_hup=signal(SIGHUP,sig_end);
|
||||
save_term=signal(SIGTERM,sig_end);
|
||||
save_int=signal(SIGINT,sig_end);
|
||||
save_usr1=signal(SIGUSR1,sig_usr1);
|
||||
|
||||
monServer* ms = new monServer(32u,5u,2000u,argv[1]);
|
||||
ms->mainLoop();
|
||||
delete ms;
|
||||
return 0;
|
||||
}
|
||||
|
||||
94
src/cas/example/iocmonitor/monServer.h
Normal file
94
src/cas/example/iocmonitor/monServer.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef MONSERVER_H
|
||||
#define MONSERVER_H
|
||||
|
||||
/*
|
||||
* Author: Jim Kowalkowski
|
||||
* Date: 1/97
|
||||
*
|
||||
* $Id$
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
#include "casdef.h"
|
||||
#include "tsHash.h"
|
||||
#include "fdManager.h"
|
||||
|
||||
#include "monNode.h"
|
||||
|
||||
class gdd;
|
||||
class monServer;
|
||||
|
||||
// use lower 11 bits of address as index
|
||||
#define ADDR_MASK 0x0000001f
|
||||
#define ADDR_TOTAL (ADDR_MASK+1)
|
||||
#define REPEATER_PORT 5065
|
||||
|
||||
// ---------------------- fd manager ------------------------
|
||||
|
||||
class monFd : public fdReg
|
||||
{
|
||||
public:
|
||||
monFd(const int fdIn,const fdRegType typ,monServer& s):
|
||||
fdReg(fdIn,typ),server(s) { }
|
||||
virtual ~monFd(void);
|
||||
private:
|
||||
virtual void callBack(void);
|
||||
monServer& server;
|
||||
};
|
||||
|
||||
// ---------------------------- server -------------------------------
|
||||
|
||||
class monServer : public caServer
|
||||
{
|
||||
public:
|
||||
monServer(unsigned max_name_len,unsigned pv_count_est,unsigned max_sim_io,
|
||||
const char* pre);
|
||||
virtual ~monServer(void);
|
||||
|
||||
// CAS virtual overloads
|
||||
virtual pvExistReturn pvExistTest(const casCtx& c,const char* pvname);
|
||||
virtual casPV* createPV(const casCtx& c,const char* pvname);
|
||||
|
||||
// CAS application management functions
|
||||
int repeaterConnect(void);
|
||||
void checkEvent(void);
|
||||
void dataReady(void);
|
||||
void mainLoop(void);
|
||||
void report(FILE*);
|
||||
void makeADL(void);
|
||||
|
||||
monNode* findNode(unsigned long addr);
|
||||
monNode* addNode(unsigned long addr);
|
||||
|
||||
int appValue;
|
||||
char* prefix;
|
||||
int prefix_length;
|
||||
iocCountPV* count_pv;
|
||||
private:
|
||||
tsHash<monNode> pv_list; // client pv list
|
||||
monNode** db;
|
||||
monFd* soc_fd;
|
||||
int soc;
|
||||
char ioc_count_name[40];
|
||||
char make_screen_name[40];
|
||||
};
|
||||
|
||||
extern int debugLevel;
|
||||
|
||||
/* debug macro creation */
|
||||
#ifdef NODEBUG
|
||||
#define monDebug(l,f,v) ;
|
||||
#else
|
||||
#define monDebug(l,f,v) { if(l<=debugLevel) \
|
||||
{ fprintf(stderr,f,v); fflush(stderr); }}
|
||||
#define monDebug0(l,f) { if(l<=debugLevel) \
|
||||
{ fprintf(stderr,f); fflush(stderr); } }
|
||||
#define monDebug1(l,f,v) { if(l<=debugLevel) \
|
||||
{ fprintf(stderr,f,v); fflush(stderr); }}
|
||||
#define monDebug2(l,f,v1,v2) { if(l<=debugLevel) \
|
||||
{ fprintf(stderr,f,v1,v2); fflush(stderr); }}
|
||||
#define monDebug3(l,f,v1,v2,v3) { if(l<=debugLevel) \
|
||||
{ fprintf(stderr,f,v1,v2,v3); fflush(stderr); }}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
115
src/cas/example/iocmonitor/tsDLHashList.h
Normal file
115
src/cas/example/iocmonitor/tsDLHashList.h
Normal file
@@ -0,0 +1,115 @@
|
||||
#ifndef tsDLHashList_H
|
||||
#define tsDLHashList_H
|
||||
|
||||
/*
|
||||
* Author: Jim Kowalkowski
|
||||
* Date: 1/97
|
||||
*
|
||||
* $Id$
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include "gpHash.h"
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class tsHash
|
||||
{
|
||||
private:
|
||||
void* hash_table;
|
||||
|
||||
public:
|
||||
gpHash(void)
|
||||
{
|
||||
hash_table=NULL;
|
||||
gphInitPvt(&hash_table);
|
||||
}
|
||||
|
||||
~gateHash(void) { gphFreeMem(hash_table); }
|
||||
|
||||
int add(const char* key, T& item);
|
||||
{
|
||||
GPHENTRY* entry;
|
||||
int rc;
|
||||
|
||||
entry=gphAdd(hash_table,(char*)key,hash_table);
|
||||
|
||||
if(entry==(GPHENTRY*)NULL)
|
||||
rc=-1;
|
||||
else
|
||||
{
|
||||
entry->userPvt=(void*)&item;
|
||||
rc=0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int remove(const char* key,T*& item);
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(find(key,item)<0)
|
||||
rc=-1;
|
||||
else
|
||||
{
|
||||
gphDelete(hash_table,(char*)key,hash_table);
|
||||
rc=0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int find(const char* key, T*& item);
|
||||
{
|
||||
GPHENTRY* entry;
|
||||
int rc;
|
||||
|
||||
entry=gphFind(hash_table,(char*)key,hash_table);
|
||||
|
||||
if(entry==(GPHENTRY*)NULL)
|
||||
rc=-1;
|
||||
else
|
||||
{
|
||||
item=(T*)entry->userPvt;
|
||||
rc=0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class tsDLHashList : public tsDLList<T>
|
||||
{
|
||||
private:
|
||||
tsHash<T> h;
|
||||
public:
|
||||
int add(const char* key, T& item)
|
||||
{
|
||||
int rc;
|
||||
rc=h.add(key,item);
|
||||
add(item);
|
||||
return rc;
|
||||
}
|
||||
int find(const char* key, T*& item);
|
||||
{
|
||||
int rc=0;
|
||||
if(h.find(key,item)!=0)
|
||||
rc=-1;
|
||||
return rc;
|
||||
}
|
||||
int remove(const char* key,T*& item);
|
||||
{
|
||||
int rc=0;
|
||||
if(h.find(key,item)==0)
|
||||
{
|
||||
h.remove(key,item);
|
||||
remove(*item);
|
||||
}
|
||||
else
|
||||
rc=-1;
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
136
src/cas/example/iocmonitor/tsHash.h
Normal file
136
src/cas/example/iocmonitor/tsHash.h
Normal file
@@ -0,0 +1,136 @@
|
||||
#ifndef tsDLHashList_H
|
||||
#define tsDLHashList_H
|
||||
|
||||
/*
|
||||
* Author: Jim Kowalkowski
|
||||
* Date: 7/96
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "gpHash.h"
|
||||
}
|
||||
|
||||
#include "tsDLList.h"
|
||||
|
||||
template <class T>
|
||||
class tsHash
|
||||
{
|
||||
private:
|
||||
void* hash_table;
|
||||
friend class tsDLHashIter<T>;
|
||||
|
||||
public:
|
||||
tsHash(void)
|
||||
{
|
||||
hash_table=0;
|
||||
gphInitPvt(&hash_table,2048); // 2048 is a guess
|
||||
}
|
||||
|
||||
~tsHash(void)
|
||||
{
|
||||
gphFreeMem(hash_table);
|
||||
}
|
||||
|
||||
int add(const char* key, T& item)
|
||||
{
|
||||
GPHENTRY* entry;
|
||||
int rc;
|
||||
|
||||
entry=gphAdd(hash_table,(char*)key,hash_table);
|
||||
|
||||
if(entry==0)
|
||||
rc=-1;
|
||||
else
|
||||
{
|
||||
entry->userPvt=(void*)&item;
|
||||
rc=0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int remove(const char* key,T*& item)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(find(key,item)<0)
|
||||
rc=-1;
|
||||
else
|
||||
{
|
||||
gphDelete(hash_table,(char*)key,hash_table);
|
||||
rc=0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int find(const char* key, T*& item)
|
||||
{
|
||||
GPHENTRY* entry;
|
||||
int rc;
|
||||
|
||||
entry=gphFind(hash_table,(char*)key,hash_table);
|
||||
|
||||
if(entry==0)
|
||||
rc=-1;
|
||||
else
|
||||
{
|
||||
item=(T*)entry->userPvt;
|
||||
rc=0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class tsDLHashList : public tsDLList<T>
|
||||
{
|
||||
private:
|
||||
tsHash<T> h;
|
||||
friend class tsDLHashIter<T>;
|
||||
|
||||
public:
|
||||
tsDLHashList(void) { }
|
||||
~tsDLHashList(void) { }
|
||||
|
||||
int add(const char* key, T& item)
|
||||
{
|
||||
int rc;
|
||||
rc=h.add(key,item);
|
||||
tsDLList<T>::add(item);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int find(const char* key, T*& item)
|
||||
{
|
||||
int rc=0;
|
||||
if(h.find(key,item)!=0)
|
||||
rc=-1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int remove(const char* key,T*& item)
|
||||
{
|
||||
int rc=0;
|
||||
if(h.find(key,item)==0)
|
||||
{
|
||||
h.remove(key,item);
|
||||
tsDLList<T>::remove(*item);
|
||||
}
|
||||
else
|
||||
rc=-1;
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class tsDLHashNode : public tsDLNode<T>
|
||||
{
|
||||
public:
|
||||
T* getNext(void) { return tsDLNode<T>::getNext(); }
|
||||
T* getPrev(void) { return tsDLNode<T>::getPrev(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -86,7 +86,8 @@ caStatus exPV::update(gdd &valueIn)
|
||||
return cas;
|
||||
}
|
||||
|
||||
cur.get (t.tv_sec, t.tv_nsec);
|
||||
t.tv_sec = (time_t) cur.getSecTruncToLong ();
|
||||
t.tv_nsec = cur.getNSecTruncToLong ();
|
||||
this->pValue->setTimeStamp(&t);
|
||||
this->pValue->setStat (epicsAlarmNone);
|
||||
this->pValue->setSevr (epicsSevNone);
|
||||
@@ -242,7 +243,8 @@ inline aitTimeStamp exPV::getTS()
|
||||
}
|
||||
else {
|
||||
osiTime cur(osiTime::getCurrent());
|
||||
cur.get(ts.tv_sec, ts.tv_nsec);
|
||||
ts.tv_sec = (time_t) cur.getSecTruncToLong ();
|
||||
ts.tv_nsec = cur.getNSecTruncToLong ();
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
@@ -140,7 +140,8 @@ void exServer::installAliasName(pvInfo &info, const char *pAliasName)
|
||||
//
|
||||
// exServer::pvExistTest()
|
||||
//
|
||||
pvExistReturn exServer::pvExistTest(const casCtx& ctxIn, const char *pPVName)
|
||||
pvExistReturn exServer::pvExistTest
|
||||
(const casCtx& ctxIn, const char *pPVName)
|
||||
{
|
||||
//
|
||||
// lifetime of id is shorter than lifetime of pName
|
||||
@@ -185,7 +186,8 @@ pvExistReturn exServer::pvExistTest(const casCtx& ctxIn, const char *pPVName)
|
||||
//
|
||||
// exServer::createPV()
|
||||
//
|
||||
pvCreateReturn exServer::createPV (const casCtx &ctx, const char *pName)
|
||||
pvCreateReturn exServer::createPV
|
||||
(const casCtx &ctx, const char *pName)
|
||||
{
|
||||
//
|
||||
// lifetime of id is shorter than lifetime of pName
|
||||
@@ -196,7 +198,7 @@ pvCreateReturn exServer::createPV (const casCtx &ctx, const char *pName)
|
||||
|
||||
pPVE = this->stringResTbl.lookup(id);
|
||||
if (!pPVE) {
|
||||
return pvCreateReturn(S_casApp_pvNotFound);
|
||||
return S_casApp_pvNotFound;
|
||||
}
|
||||
|
||||
pvInfo &pvi = pPVE->getInfo();
|
||||
@@ -206,17 +208,20 @@ pvCreateReturn exServer::createPV (const casCtx &ctx, const char *pName)
|
||||
//
|
||||
if (pvi.getIOType() == excasIoSync) {
|
||||
pPV = pvi.createPV(*this, aitFalse);
|
||||
if (!pPV) {
|
||||
pvCreateReturn(S_casApp_noMemory);
|
||||
if (pPV) {
|
||||
return *pPV;
|
||||
}
|
||||
return pvCreateReturn(*pPV);
|
||||
else {
|
||||
return S_casApp_noMemory;
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// Initiate async IO if this is an async PV
|
||||
//
|
||||
else {
|
||||
if (this->simultAsychIOCount>=maxSimultAsyncIO) {
|
||||
return pvCreateReturn(S_casApp_postponeAsyncIO);
|
||||
return S_casApp_postponeAsyncIO;
|
||||
}
|
||||
|
||||
this->simultAsychIOCount++;
|
||||
@@ -224,10 +229,10 @@ pvCreateReturn exServer::createPV (const casCtx &ctx, const char *pName)
|
||||
exAsyncCreateIO *pIO =
|
||||
new exAsyncCreateIO(pvi, *this, ctx);
|
||||
if (pIO) {
|
||||
return pvCreateReturn(S_casApp_asyncCompletion);
|
||||
return S_casApp_asyncCompletion;
|
||||
}
|
||||
else {
|
||||
return pvCreateReturn(S_casApp_noMemory);
|
||||
return S_casApp_noMemory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,10 @@ public:
|
||||
// for this class
|
||||
//
|
||||
pvInfo (const pvInfo ©In) :
|
||||
scanPeriod(copyIn.scanPeriod), pName(copyIn.pName),
|
||||
hopr(copyIn.hopr), lopr(copyIn.lopr),
|
||||
ioType(copyIn.ioType), elementCount(copyIn.elementCount),
|
||||
pPV(copyIn.pPV)
|
||||
scanPeriod(copyIn.scanPeriod), pName(copyIn.pName),
|
||||
hopr(copyIn.hopr), lopr(copyIn.lopr),
|
||||
ioType(copyIn.ioType), elementCount(copyIn.elementCount),
|
||||
pPV(copyIn.pPV)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ public:
|
||||
const double getHopr () const { return this->hopr; }
|
||||
const double getLopr () const { return this->lopr; }
|
||||
const excasIoType getIOType () const { return this->ioType; }
|
||||
const unsigned getElementCount() const { return this->elementCount; }
|
||||
const unsigned getElementCount() const
|
||||
{ return this->elementCount; }
|
||||
void destroyPV() { this->pPV=NULL; }
|
||||
exPV *createPV (exServer &exCAS, aitBool preCreateFlag);
|
||||
private:
|
||||
@@ -103,7 +104,8 @@ private:
|
||||
//
|
||||
class pvEntry : public stringId, public tsSLNode<pvEntry> {
|
||||
public:
|
||||
pvEntry (pvInfo &infoIn, exServer &casIn, const char *pAliasName) :
|
||||
pvEntry (pvInfo &infoIn, exServer &casIn,
|
||||
const char *pAliasName) :
|
||||
stringId(pAliasName), info(infoIn), cas(casIn)
|
||||
{
|
||||
assert(this->stringId::resourceName()!=NULL);
|
||||
@@ -113,13 +115,8 @@ public:
|
||||
|
||||
pvInfo &getInfo() const { return this->info; }
|
||||
|
||||
void destroy ()
|
||||
{
|
||||
//
|
||||
// always created with new
|
||||
//
|
||||
delete this;
|
||||
}
|
||||
inline void destroy ();
|
||||
|
||||
private:
|
||||
pvInfo &info;
|
||||
exServer &cas;
|
||||
@@ -252,7 +249,8 @@ protected:
|
||||
//
|
||||
class exScalarPV : public exPV {
|
||||
public:
|
||||
exScalarPV (caServer &cas, pvInfo &setup, aitBool preCreateFlag) :
|
||||
exScalarPV (caServer &cas,
|
||||
pvInfo &setup, aitBool preCreateFlag) :
|
||||
exPV (cas, setup, preCreateFlag) {}
|
||||
void scan();
|
||||
private:
|
||||
@@ -264,7 +262,8 @@ private:
|
||||
//
|
||||
class exVectorPV : public exPV {
|
||||
public:
|
||||
exVectorPV (caServer &cas, pvInfo &setup, aitBool preCreateFlag) :
|
||||
exVectorPV (caServer &cas, pvInfo &setup,
|
||||
aitBool preCreateFlag) :
|
||||
exPV (cas, setup, preCreateFlag) {}
|
||||
void scan();
|
||||
|
||||
@@ -302,7 +301,8 @@ public:
|
||||
this->simultAsychIOCount--;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "inconsistent simultAsychIOCount?\n");
|
||||
fprintf(stderr,
|
||||
"simultAsychIOCount underflow?\n");
|
||||
}
|
||||
}
|
||||
private:
|
||||
@@ -561,4 +561,15 @@ inline pvEntry::~pvEntry()
|
||||
{
|
||||
this->cas.removeAliasName(*this);
|
||||
}
|
||||
|
||||
//
|
||||
// pvEntry:: destroy()
|
||||
//
|
||||
inline void pvEntry::destroy ()
|
||||
{
|
||||
//
|
||||
// always created with new
|
||||
//
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
// $Id$
|
||||
// $Log$
|
||||
// Revision 1.2 1997/03/05 21:16:22 jbk
|
||||
// Fixes cvs log id at top
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pvServ.h"
|
||||
@@ -80,7 +83,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
Debug3("total=%d,rate=%lf,prefix=%s\n",total_pv,rate,name);
|
||||
|
||||
server = new serv(total_pv,rate,name,40u,total_pv,total_pv);
|
||||
server = new serv(total_pv,rate,name,total_pv);
|
||||
rc=server->Main();
|
||||
delete server;
|
||||
return rc;
|
||||
@@ -100,38 +103,19 @@ int serv::InitDB(void)
|
||||
|
||||
int serv::Main(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
int not_done=1;
|
||||
|
||||
double inv=(1.0/event_rate);
|
||||
double num=(unsigned long)inv;
|
||||
double fract=inv-num;
|
||||
unsigned long lfract=fract?(unsigned long)(1.0/fract):0;
|
||||
unsigned long nsec = lfract?1000000000u/lfract:0;
|
||||
unsigned long sec = (unsigned long)num;
|
||||
struct timeval tv_curr,tv_prev;
|
||||
|
||||
osiTime delay(sec,nsec);
|
||||
|
||||
tv_prev.tv_sec=0;
|
||||
tv_prev.tv_usec=0;
|
||||
|
||||
Debug2("Update every sec=%lu nsec=%lu\n",sec,nsec);
|
||||
|
||||
if (event_rate>0) {
|
||||
Debug1("Update every %f sec\n", inv);
|
||||
double inv=(1.0/event_rate);
|
||||
pScanTimer = new scanTimer (inv, *this);
|
||||
}
|
||||
|
||||
while(not_done)
|
||||
{
|
||||
osiTime delay(10.0);
|
||||
fileDescriptorManager.process(delay);
|
||||
|
||||
gettimeofday(&tv_curr,NULL);
|
||||
|
||||
if(tv_curr.tv_sec-tv_prev.tv_sec >= sec &&
|
||||
tv_curr.tv_usec-tv_prev.tv_usec >= (nsec/1000))
|
||||
{
|
||||
for(i=0;i<pv_total;i++)
|
||||
db_sync[i].eventReady();
|
||||
}
|
||||
|
||||
tv_prev=tv_curr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -139,10 +123,10 @@ int serv::Main(void)
|
||||
|
||||
// ------------------------- server stuff ----------------------------
|
||||
|
||||
serv::serv(int tot,double rate,char* name,
|
||||
unsigned max_name_len,unsigned pv_count_est,unsigned max_sim_io):
|
||||
caServer(max_name_len, pv_count_est, max_sim_io),
|
||||
db_sync(NULL),pv_total(tot),event_rate(rate),prefix(name)
|
||||
serv::serv(int tot,double rate,char* name,unsigned pv_count_est):
|
||||
caServer(pv_count_est),
|
||||
db_sync(NULL),pv_total(tot),event_rate(rate),prefix(name),
|
||||
pScanTimer(NULL)
|
||||
{
|
||||
event_mask|=(alarmEventMask|valueEventMask|logEventMask);
|
||||
|
||||
@@ -159,6 +143,7 @@ serv::serv(int tot,double rate,char* name,
|
||||
serv::~serv(void)
|
||||
{
|
||||
delete [] db_sync;
|
||||
if (pScanTimer) delete pScanTimer;
|
||||
}
|
||||
|
||||
pvExistReturn serv::pvExistTest(const casCtx&,const char* pvname)
|
||||
@@ -185,9 +170,9 @@ pvExistReturn serv::pvExistTest(const casCtx&,const char* pvname)
|
||||
pvExistReturn(rc);
|
||||
}
|
||||
|
||||
casPV* serv::createPV(const casCtx& in,const char* pvname)
|
||||
pvCreateReturn serv::createPV(const casCtx& in,const char* pvname)
|
||||
{
|
||||
casPV* rc=NULL;
|
||||
casPV* pPV=NULL;
|
||||
int val;
|
||||
|
||||
Debug1("createPV: %s\n",pvname);
|
||||
@@ -199,30 +184,44 @@ casPV* serv::createPV(const casCtx& in,const char* pvname)
|
||||
{
|
||||
Debug("createPV: I am making this PV\n");
|
||||
if(val>=0 && val<pv_total)
|
||||
rc=new servPV(in,*this,pvname,db_sync[val]);
|
||||
pPV=new servPV(*this,pvname,db_sync[val]);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
if (pPV) {
|
||||
return pvCreateReturn(*pPV);
|
||||
}
|
||||
else {
|
||||
return pvCreateReturn(S_casApp_pvNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
void serv::scan(void)
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0;i<pv_total;i++)
|
||||
db_sync[i].eventReady();
|
||||
}
|
||||
|
||||
// -----------------------PV stuff -------------------------------
|
||||
|
||||
servPV::servPV(const casCtx& c,serv& m,const char* n,dBase& x):
|
||||
casPV(c,n),db(x),mgr(m),monitored(0)
|
||||
servPV::servPV(serv& m,const char* n,dBase& x):
|
||||
casPV(m),db(x),mgr(m),monitored(0)
|
||||
{
|
||||
db.node=this;
|
||||
value=new gddScalar(appValue,aitEnumFloat64);
|
||||
pName=new char [strlen(n)+1];
|
||||
assert(pName);
|
||||
strcpy(pName,n);
|
||||
}
|
||||
|
||||
servPV::~servPV(void)
|
||||
{
|
||||
value->unreference();
|
||||
db.node=NULL;
|
||||
delete [] pName;
|
||||
}
|
||||
|
||||
unsigned servPV::maxSimultAsyncOps(void) const { return 100000u; }
|
||||
|
||||
caStatus servPV::interestRegister()
|
||||
{
|
||||
if(!monitored) monitored=1;
|
||||
@@ -239,6 +238,11 @@ aitEnum servPV::bestExternalType() const
|
||||
return aitEnumFloat64;
|
||||
}
|
||||
|
||||
const char *servPV::getName() const
|
||||
{
|
||||
return pName;
|
||||
}
|
||||
|
||||
caStatus servPV::read(const casCtx&, gdd &dd)
|
||||
{
|
||||
Debug1("read: %s\n",db.pvname);
|
||||
@@ -277,3 +281,27 @@ void servPV::eventReady(void)
|
||||
postEvent(mgr.event_mask,*value);
|
||||
}
|
||||
|
||||
//
|
||||
// scanTimer::expire ()
|
||||
//
|
||||
void scanTimer::expire ()
|
||||
{
|
||||
serv.scan();
|
||||
}
|
||||
|
||||
//
|
||||
// scanTimer::again()
|
||||
//
|
||||
osiBool scanTimer::again() const
|
||||
{
|
||||
return osiTrue;
|
||||
}
|
||||
|
||||
//
|
||||
// scanTimer::delay()
|
||||
//
|
||||
const osiTime scanTimer::delay() const
|
||||
{
|
||||
return period;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
/*
|
||||
* $Id$
|
||||
* $Log$
|
||||
* Revision 1.2 1997/03/05 21:16:23 jbk
|
||||
* Fixes cvs log id at top
|
||||
*
|
||||
*/
|
||||
|
||||
#include "casdef.h"
|
||||
@@ -45,19 +48,38 @@ public:
|
||||
servPV* node;
|
||||
};
|
||||
|
||||
class serv;
|
||||
|
||||
//
|
||||
// scanTimer
|
||||
//
|
||||
class scanTimer : public osiTimer {
|
||||
public:
|
||||
scanTimer (double delayIn, serv &servIn) :
|
||||
osiTimer(delayIn), serv(servIn),
|
||||
period(delayIn) {}
|
||||
void expire ();
|
||||
osiBool again() const;
|
||||
const osiTime delay() const;
|
||||
private:
|
||||
serv &serv;
|
||||
double period;
|
||||
};
|
||||
|
||||
class serv : public caServer
|
||||
{
|
||||
public:
|
||||
serv(int totpv,double rate,char* prefix,
|
||||
unsigned maxnamelen,unsigned pvtotalest, unsigned maxsimio);
|
||||
serv(int totpv,double rate,char* prefix,unsigned pvtotalest);
|
||||
virtual ~serv(void);
|
||||
|
||||
virtual pvExistReturn pvExistTest(const casCtx& c,const char* pvname);
|
||||
virtual casPV* createPV(const casCtx& c,const char* pvname);
|
||||
virtual pvCreateReturn createPV(const casCtx& c,const char* pvname);
|
||||
|
||||
int InitDB(void);
|
||||
int Main(void);
|
||||
|
||||
void scan();
|
||||
|
||||
// sloppy
|
||||
char* prefix;
|
||||
int prefix_len;
|
||||
@@ -65,12 +87,13 @@ public:
|
||||
double event_rate;
|
||||
casEventMask event_mask;
|
||||
dBase* db_sync;
|
||||
scanTimer *pScanTimer;
|
||||
};
|
||||
|
||||
class servPV : public casPV
|
||||
{
|
||||
public:
|
||||
servPV(const casCtx&,serv&,const char* pvname,dBase&);
|
||||
servPV(serv&,const char* pvname,dBase&);
|
||||
virtual ~servPV(void);
|
||||
|
||||
virtual caStatus interestRegister(void);
|
||||
@@ -79,7 +102,7 @@ public:
|
||||
virtual caStatus read(const casCtx &ctx, gdd &prototype);
|
||||
virtual caStatus write(const casCtx &ctx, gdd &value);
|
||||
virtual void destroy(void);
|
||||
virtual unsigned maxSimultAsyncOps(void) const;
|
||||
virtual const char *getName() const;
|
||||
|
||||
void eventReady(void);
|
||||
|
||||
@@ -88,5 +111,7 @@ private:
|
||||
dBase& db;
|
||||
gdd* value;
|
||||
int monitored;
|
||||
char *pName;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
TOP = ../../../..
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
INC := casdef.h casInternal.h casEventMask.h
|
||||
INC := casdef.h casInternal.h casEventMask.h caNetAddr.h
|
||||
|
||||
include $(TOP)/config/RULES.Host
|
||||
|
||||
|
||||
163
src/cas/generic/caNetAddr.h
Normal file
163
src/cas/generic/caNetAddr.h
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// caNetAddr
|
||||
//
|
||||
// special cas specific network address class so:
|
||||
// 1) we dont drag BSD socket headers into
|
||||
// the server tool
|
||||
// 2) we are able to use other networking services
|
||||
// besides sockets in the future
|
||||
//
|
||||
// get() will assert fail if the init flag has not been
|
||||
// set
|
||||
//
|
||||
|
||||
#ifndef caNetAddrH
|
||||
#define caNetAddrH
|
||||
|
||||
#ifdef caNetAddrSock
|
||||
#include <osiSock.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
class verifyCANetAddr {
|
||||
public:
|
||||
inline void checkSize();
|
||||
};
|
||||
|
||||
enum caNetAddrType {casnaUDF, casnaSock}; // only IP addresses (and undefined) supported at this time
|
||||
class caNetAddr {
|
||||
friend class verifyCANetAddr;
|
||||
public:
|
||||
|
||||
//
|
||||
// clear()
|
||||
//
|
||||
inline void clear ()
|
||||
{
|
||||
this->type = casnaUDF;
|
||||
}
|
||||
|
||||
//
|
||||
// caNetAddr()
|
||||
//
|
||||
inline caNetAddr ()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
inline int isSock () const
|
||||
{
|
||||
return this->type == casnaSock;
|
||||
}
|
||||
|
||||
//
|
||||
// conditionally drag BSD socket headers into the server
|
||||
// and server tool
|
||||
//
|
||||
// to use this #define caNetAddrSock
|
||||
//
|
||||
# ifdef caNetAddrSock
|
||||
inline void setSockIP(unsigned long inaIn, unsigned short portIn)
|
||||
{
|
||||
this->type = casnaSock;
|
||||
this->addr.sock.sin_family = AF_INET;
|
||||
this->addr.sock.sin_addr.s_addr = inaIn;
|
||||
this->addr.sock.sin_port = portIn;
|
||||
}
|
||||
|
||||
inline void setSockIP(const struct sockaddr_in &sockIPIn)
|
||||
{
|
||||
this->type = casnaSock;
|
||||
assert(sockIPIn.sin_family == AF_INET);
|
||||
this->addr.sock = sockIPIn;
|
||||
}
|
||||
|
||||
inline void setSock(const struct sockaddr &sock)
|
||||
{
|
||||
this->type = casnaSock;
|
||||
struct sockaddr_in *psip = (struct sockaddr_in *) &sock;
|
||||
assert(sizeof(sock)==sizeof(this->addr.sock));
|
||||
this->addr.sock = *psip;
|
||||
}
|
||||
|
||||
inline caNetAddr(const struct sockaddr_in &sockIPIn)
|
||||
{
|
||||
this->setSockIP(sockIPIn);
|
||||
}
|
||||
|
||||
inline caNetAddr operator = (const struct sockaddr_in &sockIPIn)
|
||||
{
|
||||
this->setSockIP(sockIPIn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline caNetAddr operator = (const struct sockaddr &sockIn)
|
||||
{
|
||||
this->setSock(sockIn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline struct sockaddr_in getSockIP() const
|
||||
{
|
||||
assert (this->type==casnaSock);
|
||||
return this->addr.sock;
|
||||
}
|
||||
|
||||
inline struct sockaddr getSock() const
|
||||
{
|
||||
struct sockaddr sa;
|
||||
assert (this->type==casnaSock);
|
||||
assert (sizeof(sa)==sizeof(this->addr.sock));
|
||||
struct sockaddr_in *psain = (struct sockaddr_in *) &sa;
|
||||
*psain = this->addr.sock;
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
||||
inline operator sockaddr_in () const
|
||||
{
|
||||
return this->getSockIP();
|
||||
}
|
||||
|
||||
inline operator sockaddr () const
|
||||
{
|
||||
return this->getSock();
|
||||
}
|
||||
|
||||
# endif // caNetAddrSock
|
||||
|
||||
private:
|
||||
union {
|
||||
# ifdef caNetAddrSock
|
||||
struct sockaddr_in sock;
|
||||
# endif
|
||||
//
|
||||
// this must be as big or bigger
|
||||
// than the largest field
|
||||
//
|
||||
// see checkDummySize() above
|
||||
//
|
||||
unsigned char dummy[16];
|
||||
}addr;
|
||||
|
||||
caNetAddrType type;
|
||||
|
||||
static verifyCANetAddr verify;
|
||||
};
|
||||
|
||||
inline void verifyCANetAddr::checkSize()
|
||||
{
|
||||
//
|
||||
// temp used because brain dead
|
||||
// ms compiler does not allow
|
||||
// use of scope res operator
|
||||
//
|
||||
caNetAddr t;
|
||||
size_t ds = sizeof (t.addr.dummy);
|
||||
size_t as = sizeof (t.addr);
|
||||
assert (ds==as);
|
||||
}
|
||||
|
||||
|
||||
#endif // caNetAddrH
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.5 1997/04/10 19:33:52 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.4 1996/11/02 00:53:53 jhill
|
||||
* many improvements
|
||||
*
|
||||
@@ -89,6 +92,22 @@ caServer::~caServer()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// caServer::pvExistTest()
|
||||
//
|
||||
pvExistReturn caServer::pvExistTest (const casCtx &, const char *)
|
||||
{
|
||||
return pverDoesNotExistHere;
|
||||
}
|
||||
|
||||
//
|
||||
// caServer::createPV()
|
||||
//
|
||||
pvCreateReturn caServer::createPV (const casCtx &, const char *)
|
||||
{
|
||||
return S_casApp_pvNotFound;
|
||||
}
|
||||
|
||||
//
|
||||
// caServer::registerEvent()
|
||||
//
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.7 1997/04/10 19:33:53 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.6 1996/11/02 00:53:54 jhill
|
||||
* many improvements
|
||||
*
|
||||
@@ -333,7 +336,7 @@ void serverToolDebugFunc(const char *pFile, unsigned line, const char *pComment)
|
||||
//
|
||||
// caServerI::addAddr()
|
||||
//
|
||||
caStatus caServerI::addAddr(const caAddr &caAddr, int autoBeaconAddr,
|
||||
caStatus caServerI::addAddr(const caNetAddr &addr, int autoBeaconAddr,
|
||||
int addConfigBeaconAddr)
|
||||
{
|
||||
caStatus stat;
|
||||
@@ -341,7 +344,7 @@ caStatus caServerI::addAddr(const caAddr &caAddr, int autoBeaconAddr,
|
||||
|
||||
pIntf = new casIntfOS(*this);
|
||||
if (pIntf) {
|
||||
stat = pIntf->init(caAddr, this->dgClient,
|
||||
stat = pIntf->init(addr, this->dgClient,
|
||||
autoBeaconAddr, addConfigBeaconAddr);
|
||||
if (stat==S_cas_success) {
|
||||
this->osiLock();
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.4 1997/04/10 19:33:54 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.3 1996/11/02 00:53:56 jhill
|
||||
* many improvements
|
||||
*
|
||||
@@ -96,15 +99,6 @@ inline casChannelI *caServerI::resIdToChannel(const caResId &id)
|
||||
return (casChannelI *) pRes;
|
||||
}
|
||||
|
||||
//
|
||||
// find the channel associated with a resource id
|
||||
//
|
||||
inline casPVExistReturn caServerI::pvExistTest(
|
||||
const casCtx &ctxIn, const char *pPVName)
|
||||
{
|
||||
return casPVExistReturn((*this)->pvExistTest(ctxIn, pPVName));
|
||||
}
|
||||
|
||||
//
|
||||
// caServerI::installItem()
|
||||
//
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1997/04/10 19:33:54 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.2 1996/11/06 22:15:53 jhill
|
||||
* allow monitor init read to using rd async io
|
||||
*
|
||||
@@ -43,17 +46,17 @@
|
||||
#include "server.h"
|
||||
#include "casAsyncIOIIL.h" // casAsyncIOI in line func
|
||||
#include "casChannelIIL.h" // casChannelI in line func
|
||||
#include "casOpaqueAddrIL.h" // casOpaqueAddr in line func
|
||||
#include "casCtxIL.h" // casCtx in line func
|
||||
#include "casCoreClientIL.h" // casCoreClient in line func
|
||||
|
||||
//
|
||||
// casAsyncExIOI::casAsyncExIOI()
|
||||
//
|
||||
casAsyncExIOI::casAsyncExIOI(const casCtx &ctx,
|
||||
casAsyncPVExistIO &ioIn) :
|
||||
casAsyncExIOI::casAsyncExIOI(
|
||||
const casCtx &ctx, casAsyncPVExistIO &ioIn) :
|
||||
casAsyncIOI(*ctx.getClient(), ioIn),
|
||||
msg(*ctx.getMsg()),
|
||||
retVal(pverDoesNotExistHere),
|
||||
pOutDGIntfIO(ctx.getClient()->fetchOutIntf()),
|
||||
dgOutAddr(ctx.getClient()->fetchRespAddr())
|
||||
{
|
||||
@@ -94,7 +97,7 @@ caStatus casAsyncExIOI::cbFuncAsyncIO()
|
||||
//
|
||||
assert(this->pOutDGIntfIO);
|
||||
status = this->client.asyncSearchResponse(*this->pOutDGIntfIO,
|
||||
this->dgOutAddr.get(), this->msg, this->retVal);
|
||||
this->dgOutAddr, this->msg, this->retVal);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1 1997/04/10 19:38:14 jhill
|
||||
* installed
|
||||
*
|
||||
* Revision 1.2 1996/11/06 22:15:53 jhill
|
||||
* allow monitor init read to using rd async io
|
||||
*
|
||||
@@ -43,7 +46,6 @@
|
||||
#include "server.h"
|
||||
#include "casAsyncIOIIL.h" // casAsyncIOI in line func
|
||||
#include "casChannelIIL.h" // casChannelI in line func
|
||||
#include "casOpaqueAddrIL.h" // casOpaqueAddr in line func
|
||||
#include "casCtxIL.h" // casCtx in line func
|
||||
#include "casCoreClientIL.h" // casCoreClient in line func
|
||||
|
||||
@@ -53,7 +55,8 @@
|
||||
casAsyncPVCIOI::casAsyncPVCIOI(const casCtx &ctx,
|
||||
casAsyncPVCreateIO &ioIn) :
|
||||
casAsyncIOI(*ctx.getClient(), ioIn),
|
||||
msg(*ctx.getMsg())
|
||||
msg(*ctx.getMsg()),
|
||||
retVal(S_cas_badParameter)
|
||||
{
|
||||
assert (&this->msg);
|
||||
this->client.installAsyncIO(*this);
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1997/04/10 19:33:58 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.2 1996/11/02 00:54:01 jhill
|
||||
* many improvements
|
||||
*
|
||||
@@ -42,6 +45,13 @@
|
||||
#include "server.h"
|
||||
#include "casEventSysIL.h" // casEventSys in line func
|
||||
|
||||
//
|
||||
// casChanDelEv()
|
||||
//
|
||||
casChanDelEv::~casChanDelEv()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// casChanDelEv()
|
||||
//
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.5 1997/04/10 19:34:03 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.4 1996/11/02 00:54:07 jhill
|
||||
* many improvements
|
||||
*
|
||||
@@ -182,7 +185,7 @@ void casCoreClient::show (unsigned level) const
|
||||
// asynchronous completion
|
||||
//
|
||||
caStatus casCoreClient::asyncSearchResponse(casDGIntfIO &,
|
||||
const caAddr &, const caHdr &, const pvExistReturn)
|
||||
const caNetAddr &, const caHdr &, const pvExistReturn &)
|
||||
{
|
||||
return S_casApp_noSupport;
|
||||
}
|
||||
@@ -239,11 +242,9 @@ void casCoreClient::removeChannel(casChannelI &)
|
||||
//
|
||||
// casCoreClient::fetchRespAddr()
|
||||
//
|
||||
caAddr casCoreClient::fetchRespAddr()
|
||||
caNetAddr casCoreClient::fetchRespAddr()
|
||||
{
|
||||
caAddr addr;
|
||||
memset (&addr, '\0', sizeof(addr));
|
||||
return addr;
|
||||
return caNetAddr(); // sets addr type to UDF
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.9 1997/04/10 19:34:06 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.8 1997/01/10 21:17:53 jhill
|
||||
* code around gnu g++ inline bug when -O isnt used
|
||||
*
|
||||
@@ -127,7 +130,6 @@ caStatus casDGClient::searchAction()
|
||||
void *dp = this->ctx.getData();
|
||||
const char *pChanName = (const char *) dp;
|
||||
caStatus status;
|
||||
pvExistReturn pver;
|
||||
|
||||
if (this->ctx.getServer()->getDebugLevel()>2u) {
|
||||
printf("client is searching for \"%s\"\n", pChanName);
|
||||
@@ -149,38 +151,34 @@ caStatus casDGClient::searchAction()
|
||||
// ask the server tool if this PV exists
|
||||
//
|
||||
this->asyncIOFlag = 0u;
|
||||
casPVExistReturn retVal =
|
||||
this->ctx.getServer()->pvExistTest(this->ctx, pChanName);
|
||||
if (retVal.getStatus()!=S_cas_success) {
|
||||
return retVal.getStatus();
|
||||
}
|
||||
pvExistReturn pver =
|
||||
(*this->ctx.getServer())->pvExistTest(this->ctx, pChanName);
|
||||
|
||||
//
|
||||
// prevent problems when they initiate
|
||||
// async IO but dont return status
|
||||
// indicating so (and vise versa)
|
||||
//
|
||||
pver = retVal.getAppStat();
|
||||
if (this->asyncIOFlag) {
|
||||
pver = pverAsyncCompletion;
|
||||
}
|
||||
else if (pver == pverAsyncCompletion) {
|
||||
else if (pver.getStatus() == pverAsyncCompletion) {
|
||||
pver = pverDoesNotExistHere;
|
||||
errMessage(S_cas_badParameter,
|
||||
"- expected asynch IO creation from caServer::pvExistTest()");
|
||||
"- expected asynch IO status from caServer::pvExistTest()");
|
||||
}
|
||||
|
||||
//
|
||||
// otherwise we assume sync IO operation was initiated
|
||||
//
|
||||
switch (pver) {
|
||||
switch (pver.getStatus()) {
|
||||
case pverDoesNotExistHere:
|
||||
case pverAsyncCompletion:
|
||||
status = S_cas_success;
|
||||
break;
|
||||
|
||||
case pverExistsHere:
|
||||
status = this->searchResponse(*mp, retVal.getAppStat());
|
||||
status = this->searchResponse(*mp, pver);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -196,7 +194,7 @@ caStatus casDGClient::searchAction()
|
||||
// caStatus casDGClient::searchResponse()
|
||||
//
|
||||
caStatus casDGClient::searchResponse(const caHdr &msg,
|
||||
const pvExistReturn retVal)
|
||||
const pvExistReturn &retVal)
|
||||
{
|
||||
caStatus status;
|
||||
caHdr *search_reply;
|
||||
@@ -205,11 +203,11 @@ caStatus casDGClient::searchResponse(const caHdr &msg,
|
||||
//
|
||||
// normal search failure is ignored
|
||||
//
|
||||
if (retVal==pverDoesNotExistHere) {
|
||||
if (retVal.getStatus()==pverDoesNotExistHere) {
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
if (retVal!=pverExistsHere) {
|
||||
if (retVal.getStatus()!=pverExistsHere) {
|
||||
fprintf(stderr,
|
||||
"async exist completion with invalid return code \"pverAsynchCompletion\"?\n");
|
||||
return S_cas_success;
|
||||
@@ -250,16 +248,42 @@ caStatus casDGClient::searchResponse(const caHdr &msg,
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
*search_reply = msg;
|
||||
search_reply->m_postsize = sizeof(*pMinorVersion);
|
||||
/*
|
||||
* cid field is abused to carry the IP
|
||||
* address in CA_V48 or higher
|
||||
* (this allows a CA servers to serve
|
||||
* as a directory service)
|
||||
*
|
||||
* type field is abused to carry the IP
|
||||
* port number here CA_V44 or higher
|
||||
* (this allows multiple CA servers on one
|
||||
* host)
|
||||
*/
|
||||
*search_reply = msg;
|
||||
search_reply->m_postsize = sizeof(*pMinorVersion);
|
||||
search_reply->m_cid = ~0U;
|
||||
search_reply->m_type = this->pOutMsgIO->serverPortNumber();
|
||||
if (CA_V48(CA_PROTOCOL_VERSION,msg.m_count)) {
|
||||
if (retVal.addrIsValid()) {
|
||||
caNetAddr addr = retVal.getAddr();
|
||||
struct sockaddr_in ina = addr.getSockIP();
|
||||
search_reply->m_cid = ina.sin_addr.s_addr;
|
||||
if (ina.sin_port==0u) {
|
||||
search_reply->m_type = this->pOutMsgIO->serverPortNumber();
|
||||
}
|
||||
else {
|
||||
search_reply->m_type = ina.sin_port;
|
||||
}
|
||||
}
|
||||
else {
|
||||
search_reply->m_cid = ~0U;
|
||||
search_reply->m_type = this->pOutMsgIO->serverPortNumber();
|
||||
}
|
||||
}
|
||||
else {
|
||||
search_reply->m_cid = ~0U;
|
||||
search_reply->m_type = this->pOutMsgIO->serverPortNumber();
|
||||
}
|
||||
|
||||
search_reply->m_count = 0ul;
|
||||
|
||||
/*
|
||||
@@ -322,7 +346,7 @@ void casDGClient::sendBeacon(casDGIntfIO &io)
|
||||
//
|
||||
// send it to all addresses on the beacon list
|
||||
//
|
||||
io.sendBeacon(buf, sizeof(msg), msg.m_available);
|
||||
io.sendBeacon(buf, sizeof(msg), msg.m_available, msg.m_count);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -400,8 +424,9 @@ void casDGClient::processDG(casDGIntfIO &inMsgIO, casDGIntfIO &outMsgIO)
|
||||
//
|
||||
// casDGClient::asyncSearchResp()
|
||||
//
|
||||
caStatus casDGClient::asyncSearchResponse(casDGIntfIO &outMsgIO, const caAddr &outAddr,
|
||||
const caHdr &msg, const pvExistReturn retVal)
|
||||
caStatus casDGClient::asyncSearchResponse(
|
||||
casDGIntfIO &outMsgIO, const caNetAddr &outAddr,
|
||||
const caHdr &msg, const pvExistReturn &retVal)
|
||||
{
|
||||
caStatus stat;
|
||||
|
||||
@@ -425,7 +450,7 @@ caStatus casDGClient::asyncSearchResponse(casDGIntfIO &outMsgIO, const caAddr &o
|
||||
// casDGClient::xDGSend()
|
||||
//
|
||||
xSendStatus casDGClient::xDGSend (char *pBufIn, bufSizeT nBytesNeedToBeSent,
|
||||
bufSizeT &nBytesSent, const caAddr &recipient)
|
||||
bufSizeT &nBytesSent, const caNetAddr &recipient)
|
||||
{
|
||||
xSendStatus stat;
|
||||
|
||||
@@ -447,7 +472,7 @@ xSendStatus casDGClient::xDGSend (char *pBufIn, bufSizeT nBytesNeedToBeSent,
|
||||
// casDGClient::xDGRecv()
|
||||
//
|
||||
xRecvStatus casDGClient::xDGRecv (char *pBufIn, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv, caAddr &sender)
|
||||
bufSizeT &nByesRecv, caNetAddr &sender)
|
||||
{
|
||||
xRecvStatus stat;
|
||||
|
||||
@@ -489,7 +514,7 @@ unsigned casDGClient::getDebugLevel() const
|
||||
//
|
||||
// casDGClient::fetchRespAddr()
|
||||
//
|
||||
caAddr casDGClient::fetchRespAddr()
|
||||
caNetAddr casDGClient::fetchRespAddr()
|
||||
{
|
||||
return this->getRecipient();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.11 1997/04/10 19:34:10 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.10 1997/01/10 21:17:55 jhill
|
||||
* code around gnu g++ inline bug when -O isnt used
|
||||
*
|
||||
@@ -87,6 +90,7 @@ private:
|
||||
class casChanDelEv : public casEvent {
|
||||
public:
|
||||
casChanDelEv(caResId idIn) : id(idIn) {}
|
||||
~casChanDelEv();
|
||||
caStatus cbFunc(casEventSys &);
|
||||
private:
|
||||
caResId id;
|
||||
@@ -114,7 +118,7 @@ class ioBlocked : public tsDLNode<ioBlocked> {
|
||||
friend class ioBlockedList;
|
||||
public:
|
||||
ioBlocked ();
|
||||
virtual ~ioBlocked ()=0;
|
||||
virtual ~ioBlocked ();
|
||||
private:
|
||||
ioBlockedList *pList;
|
||||
virtual void ioBlockedSignal ();
|
||||
@@ -358,51 +362,6 @@ private:
|
||||
caStatus completionStatus;
|
||||
};
|
||||
|
||||
union ca_addr;
|
||||
|
||||
//
|
||||
// casOpaqueAddr
|
||||
//
|
||||
// store address as an opaque array of bytes so that
|
||||
// we dont drag the socket (or other IO specific)
|
||||
// headers into the server tool.
|
||||
//
|
||||
//
|
||||
// get() will assert fail if the init flag has not been
|
||||
// set
|
||||
//
|
||||
class casOpaqueAddr
|
||||
{
|
||||
public:
|
||||
//
|
||||
// casOpaqueAddr()
|
||||
//
|
||||
casOpaqueAddr();
|
||||
|
||||
//
|
||||
// clear()
|
||||
//
|
||||
void clear();
|
||||
|
||||
inline int hasBeenInitialized() const;
|
||||
inline casOpaqueAddr (const union ca_addr &addr);
|
||||
inline void set (const union ca_addr &);
|
||||
inline union ca_addr get () const;
|
||||
private:
|
||||
char opaqueAddr[16u]; // large enough for socket addresses
|
||||
char init;
|
||||
|
||||
//
|
||||
// simple class that will assert fail if
|
||||
// sizeof(opaqueAddr) < sizeof(caAddr)
|
||||
//
|
||||
class checkSize {
|
||||
public:
|
||||
checkSize();
|
||||
};
|
||||
static checkSize sizeChecker;
|
||||
};
|
||||
|
||||
class casDGIntfIO;
|
||||
|
||||
//
|
||||
@@ -426,7 +385,7 @@ private:
|
||||
caHdr const msg;
|
||||
pvExistReturn retVal;
|
||||
casDGIntfIO * const pOutDGIntfIO;
|
||||
const casOpaqueAddr dgOutAddr;
|
||||
const caNetAddr dgOutAddr;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.4 1997/04/10 19:34:13 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.3 1996/11/02 00:54:19 jhill
|
||||
* many improvements
|
||||
*
|
||||
@@ -41,9 +44,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include"server.h"
|
||||
|
||||
class casMsgIO {
|
||||
@@ -65,9 +65,9 @@ public:
|
||||
//
|
||||
xSendStatus xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
|
||||
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent,
|
||||
const caAddr &addr);
|
||||
const caNetAddr &addr);
|
||||
xRecvStatus xRecv (char *pBuf, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv, caAddr &addr);
|
||||
bufSizeT &nByesRecv, caNetAddr &addr);
|
||||
|
||||
virtual bufSizeT incommingBytesPresent() const;
|
||||
virtual casIOState state() const=0;
|
||||
@@ -93,9 +93,9 @@ private:
|
||||
xBlockingStatus blockingStatus;
|
||||
|
||||
virtual xSendStatus osdSend (const char *pBuf, bufSizeT nBytesReq,
|
||||
bufSizeT &nBytesActual, const caAddr &addr) =0;
|
||||
bufSizeT &nBytesActual, const caNetAddr &addr) =0;
|
||||
virtual xRecvStatus osdRecv (char *pBuf, bufSizeT nBytesReq,
|
||||
bufSizeT &nBytesActual, caAddr &addr) =0;
|
||||
bufSizeT &nBytesActual, caNetAddr &addr) =0;
|
||||
virtual void osdShow (unsigned level) const = 0;
|
||||
virtual void xSetNonBlocking();
|
||||
};
|
||||
@@ -139,7 +139,7 @@ void casMsgIO::show(unsigned level) const
|
||||
// casMsgIO::xRecv()
|
||||
//
|
||||
xRecvStatus casMsgIO::xRecv(char *pBuf, bufSizeT nBytes,
|
||||
bufSizeT &nActualBytes, caAddr &from)
|
||||
bufSizeT &nActualBytes, caNetAddr &from)
|
||||
{
|
||||
xRecvStatus stat;
|
||||
|
||||
@@ -155,7 +155,7 @@ xRecvStatus casMsgIO::xRecv(char *pBuf, bufSizeT nBytes,
|
||||
//
|
||||
xSendStatus casMsgIO::xSend(char *pBuf, bufSizeT nBytesAvailableToSend,
|
||||
bufSizeT nBytesNeedToBeSent, bufSizeT &nActualBytes,
|
||||
const caAddr &to)
|
||||
const caNetAddr &to)
|
||||
{
|
||||
xSendStatus stat;
|
||||
bufSizeT nActualBytesDelta;
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.15 1997/04/10 19:34:18 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.14 1996/12/12 18:56:27 jhill
|
||||
* doc
|
||||
*
|
||||
@@ -84,6 +87,7 @@
|
||||
#include "inBufIL.h" // inBuf inline functions
|
||||
#include "outBufIL.h" // outBuf inline functions
|
||||
#include "gddApps.h"
|
||||
#include "net_convert.h" // byte order conversion from libca
|
||||
|
||||
VERSIONID(casStrmClientcc,"%W% %G%")
|
||||
|
||||
@@ -349,6 +353,14 @@ caStatus casStrmClient::readResponse (casChannelI *pChan, const caHdr &msg,
|
||||
//
|
||||
gddMapDbr[msg.m_type].conv_dbr((reply+1), pDesc);
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
/* use type as index into conversion jumptable */
|
||||
(* cac_dbr_cvrt[msg.m_type])
|
||||
( reply + 1,
|
||||
reply + 1,
|
||||
TRUE, /* host -> net format */
|
||||
msg.m_count);
|
||||
#endif
|
||||
//
|
||||
// force string message size to be the true size rounded to even
|
||||
// boundary
|
||||
@@ -483,6 +495,14 @@ caStatus casStrmClient::readNotifyResponse (casChannelI *,
|
||||
memset ((char *)(reply+1), '\0', size);
|
||||
}
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
/* use type as index into conversion jumptable */
|
||||
(* cac_dbr_cvrt[msg.m_type])
|
||||
( reply + 1,
|
||||
reply + 1,
|
||||
TRUE, /* host -> net format */
|
||||
msg.m_count);
|
||||
#endif
|
||||
//
|
||||
// force string message size to be the true size rounded to even
|
||||
// boundary
|
||||
@@ -579,6 +599,14 @@ caStatus casStrmClient::monitorResponse (casChannelI *pChan,
|
||||
//
|
||||
gddMapDbr[msg.m_type].conv_dbr ((pReply+1), pDBRDD);
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
/* use type as index into conversion jumptable */
|
||||
(* cac_dbr_cvrt[msg.m_type])
|
||||
( pReply + 1,
|
||||
pReply + 1,
|
||||
TRUE, /* host -> net format */
|
||||
msg.m_count);
|
||||
#endif
|
||||
//
|
||||
// force string message size to be the true size
|
||||
//
|
||||
@@ -1181,6 +1209,7 @@ caStatus casStrmClient::eventAddAction ()
|
||||
gdd *pDD;
|
||||
caStatus status;
|
||||
casEventMask mask;
|
||||
unsigned short caProtoMask;
|
||||
|
||||
status = casStrmClient::verifyRequest (pciu);
|
||||
if (status != S_cas_validRequest) {
|
||||
@@ -1190,22 +1219,23 @@ caStatus casStrmClient::eventAddAction ()
|
||||
//
|
||||
// place monitor mask in correct byte order
|
||||
//
|
||||
pMonInfo->m_mask = ntohs (pMonInfo->m_mask);
|
||||
|
||||
if (pMonInfo->m_mask&DBE_VALUE) {
|
||||
caProtoMask = ntohs (pMonInfo->m_mask);
|
||||
if (caProtoMask&DBE_VALUE) {
|
||||
mask |= this->getCAS().getAdapter()->valueEventMask;
|
||||
}
|
||||
|
||||
if (pMonInfo->m_mask&DBE_LOG) {
|
||||
if (caProtoMask&DBE_LOG) {
|
||||
mask |= this->getCAS().getAdapter()->logEventMask;
|
||||
}
|
||||
|
||||
if (pMonInfo->m_mask&DBE_ALARM) {
|
||||
if (caProtoMask&DBE_ALARM) {
|
||||
mask |= this->getCAS().getAdapter()->alarmEventMask;
|
||||
}
|
||||
|
||||
if (mask.noEventsSelected()) {
|
||||
this->sendErr(mp, ECA_BADMASK, "event add request");
|
||||
char errStr[40];
|
||||
sprintf(errStr, "event add req with mask=0X%X\n", caProtoMask);
|
||||
this->sendErr(mp, ECA_BADMASK, errStr);
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
@@ -1513,6 +1543,15 @@ caStatus casStrmClient::write()
|
||||
return S_cas_badType;
|
||||
}
|
||||
|
||||
#ifdef CONVERSION_REQUIRED
|
||||
/* use type as index into conversion jumptable */
|
||||
(* cac_dbr_cvrt[pHdr->m_type])
|
||||
( this->ctx.getData(),
|
||||
this->ctx.getData(),
|
||||
FALSE, /* net -> host format */
|
||||
pHdr->m_count);
|
||||
#endif
|
||||
|
||||
//
|
||||
// the PV state must not be modified during a transaction
|
||||
//
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.12 1997/04/10 19:34:19 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.11 1997/01/09 22:24:46 jhill
|
||||
* eliminate MSVC++ warning resulting from passing *this to a base
|
||||
*
|
||||
@@ -112,7 +115,7 @@
|
||||
// This eliminates a warning resulting from passing *this
|
||||
// to a base class during derived class construction.
|
||||
//
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32)
|
||||
# pragma warning (disable:4355)
|
||||
#endif
|
||||
|
||||
@@ -173,6 +176,8 @@ typedef aitUint32 caStatus;
|
||||
#define S_casApp_undefined (M_casApp | 9) /*undefined value*/
|
||||
#define S_casApp_postponeAsyncIO (M_casApp | 10) /*postpone asynchronous IO*/
|
||||
|
||||
#include <caNetAddr.h>
|
||||
|
||||
//
|
||||
// pv exist test return
|
||||
//
|
||||
@@ -181,19 +186,79 @@ typedef aitUint32 caStatus;
|
||||
// to do so return pverDoesNotExistHere (and the client will
|
||||
// retry the request later).
|
||||
//
|
||||
enum pvExistReturn {pverExistsHere, pverDoesNotExistHere,
|
||||
enum pvExistReturnEnum {pverExistsHere, pverDoesNotExistHere,
|
||||
pverAsyncCompletion};
|
||||
class pvExistReturn {
|
||||
public:
|
||||
//
|
||||
// most server tools will use this
|
||||
//
|
||||
pvExistReturn (pvExistReturnEnum s=pverDoesNotExistHere) :
|
||||
status(s) {}
|
||||
//
|
||||
// directory service server tools
|
||||
// will use this
|
||||
//
|
||||
// (see caNetAddr.h)
|
||||
//
|
||||
pvExistReturn (const caNetAddr &addressIn) :
|
||||
status(pverExistsHere), address(addressIn) {}
|
||||
|
||||
const pvExistReturn &operator = (pvExistReturnEnum rhs)
|
||||
{
|
||||
this->status = rhs;
|
||||
this->address.clear();
|
||||
return *this;
|
||||
}
|
||||
const pvExistReturn &operator = (const caNetAddr &rhs)
|
||||
{
|
||||
this->status = pverExistsHere;
|
||||
this->address = rhs;
|
||||
return *this;
|
||||
}
|
||||
pvExistReturnEnum getStatus() const {return this->status;}
|
||||
int addrIsValid() const {return this->address.isSock();}
|
||||
caNetAddr getAddr() const {return this->address;}
|
||||
private:
|
||||
pvExistReturnEnum status;
|
||||
caNetAddr address;
|
||||
};
|
||||
|
||||
class casPV;
|
||||
|
||||
class pvCreateReturn {
|
||||
public:
|
||||
pvCreateReturn()
|
||||
{ this->pPV = NULL; this->stat = S_cas_badParameter; }
|
||||
pvCreateReturn(caStatus statIn)
|
||||
{ this->pPV = NULL; this->stat = statIn; }
|
||||
pvCreateReturn(casPV &pv)
|
||||
{ this->pPV = &pv; this->stat = S_casApp_success; }
|
||||
|
||||
const pvCreateReturn &operator = (caStatus rhs)
|
||||
{
|
||||
this->pPV = NULL;
|
||||
if (rhs == S_casApp_success) {
|
||||
rhs = S_cas_badParameter;
|
||||
}
|
||||
this->stat = rhs;
|
||||
return *this;
|
||||
}
|
||||
const pvCreateReturn &operator = (casPV &pvIn)
|
||||
{
|
||||
this->stat = S_casApp_success;
|
||||
this->pPV = &pvIn;
|
||||
return *this;
|
||||
}
|
||||
const pvCreateReturn &operator = (casPV *pPVIn)
|
||||
{
|
||||
if (pPVIn!=NULL) {
|
||||
this->stat = S_casApp_success;
|
||||
}
|
||||
else {
|
||||
this->stat = S_casApp_pvNotFound;
|
||||
}
|
||||
this->pPV = pPVIn;
|
||||
return *this;
|
||||
}
|
||||
const caStatus getStatus() const { return this->stat; }
|
||||
casPV *getPV() const { return this->pPV; }
|
||||
|
||||
@@ -251,16 +316,14 @@ public:
|
||||
// return pverExistsHere; // server has PV
|
||||
// return pverDoesNotExistHere; // server does know of this PV
|
||||
// return pverAsynchCompletion; // deferred result
|
||||
// return pverNoMemoryForAsyncOP; // unable to defer result
|
||||
//
|
||||
// Return S_casApp_postponeAsyncIO if too many simultaneous
|
||||
// asynchronous IO operations are pending aginst the server.
|
||||
// The server library will retry the request whenever an
|
||||
// asynchronous IO operation (create or exist) completes
|
||||
// against the server.
|
||||
// Return pverDoesNotExistHere if too many simultaneous
|
||||
// asynchronous IO operations are pending against the server.
|
||||
// The client library will retry the request at some time
|
||||
// in the future.
|
||||
//
|
||||
virtual pvExistReturn pvExistTest (const casCtx &ctx,
|
||||
const char *pPVAliasName) = 0;
|
||||
const char *pPVAliasName);
|
||||
|
||||
//
|
||||
// createPV() is called _every_ time that a PV is attached to
|
||||
@@ -281,19 +344,20 @@ public:
|
||||
// PV).
|
||||
//
|
||||
// example return from this procedure:
|
||||
// return pvCreateReturn(*pPV); // success
|
||||
// return pvCreateReturn(S_casApp_pvNotFound); // no PV by that name here
|
||||
// return pvCreateReturn(S_casApp_noMemory); // no resource to create pv
|
||||
// return pvCreateReturn(S_casApp_asyncCompletion); // deferred completion
|
||||
// return pPV; // success (pass by pointer)
|
||||
// return PV; // success (pass by ref)
|
||||
// return S_casApp_pvNotFound; // no PV by that name here
|
||||
// return S_casApp_noMemory; // no resource to create pv
|
||||
// return S_casApp_asyncCompletion; // deferred completion
|
||||
//
|
||||
// Return S_casApp_postponeAsyncIO if too many simultaneous
|
||||
// asynchronous IO operations are pending aginst the server.
|
||||
// asynchronous IO operations are pending against the server.
|
||||
// The server library will retry the request whenever an
|
||||
// asynchronous IO operation (create or exist) completes
|
||||
// against the server.
|
||||
//
|
||||
virtual pvCreateReturn createPV (const casCtx &ctx,
|
||||
const char *pPVAliasName) = 0;
|
||||
const char *pPVAliasName);
|
||||
|
||||
//
|
||||
// common event masks
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
#include "server.h"
|
||||
#include "inBufIL.h"
|
||||
#include "casOpaqueAddrIL.h"
|
||||
|
||||
//
|
||||
// this needs to be here (and not in dgInBufIL.h) if we
|
||||
@@ -30,7 +29,7 @@ dgInBuf::~dgInBuf()
|
||||
//
|
||||
int dgInBuf::hasAddress() const
|
||||
{
|
||||
return this->from.hasBeenInitialized();
|
||||
return this->from.isSock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -39,12 +38,12 @@ int dgInBuf::hasAddress() const
|
||||
xRecvStatus dgInBuf::xRecv (char *pBufIn, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv)
|
||||
{
|
||||
caAddr addr;
|
||||
caNetAddr addr;
|
||||
xRecvStatus stat;
|
||||
|
||||
stat = this->xDGRecv (pBufIn, nBytesToRecv, nByesRecv, addr);
|
||||
if (stat == xRecvOK) {
|
||||
this->from.set(addr);
|
||||
this->from = addr;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
@@ -52,8 +51,8 @@ xRecvStatus dgInBuf::xRecv (char *pBufIn, bufSizeT nBytesToRecv,
|
||||
//
|
||||
// dgInBuf::getSender()
|
||||
//
|
||||
caAddr dgInBuf::getSender() const
|
||||
caNetAddr dgInBuf::getSender() const
|
||||
{
|
||||
return this->from.get();
|
||||
return this->from;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#ifndef dgInBufILh
|
||||
#define dgInBufILh
|
||||
|
||||
#include "casOpaqueAddrIL.h"
|
||||
#include "inBufIL.h"
|
||||
|
||||
//
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
#include "server.h"
|
||||
#include "casOpaqueAddrIL.h"
|
||||
#include "outBufIL.h"
|
||||
|
||||
//
|
||||
@@ -31,8 +30,7 @@ xSendStatus dgOutBuf::xSend (char *pBufIn,
|
||||
bufSizeT &nBytesSent)
|
||||
{
|
||||
assert(nBytesAvailableToSend>=nBytesNeedToBeSent);
|
||||
return xDGSend(pBufIn, nBytesAvailableToSend, nBytesSent,
|
||||
this->to.get());
|
||||
return xDGSend(pBufIn, nBytesAvailableToSend, nBytesSent, this->to);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -53,9 +51,9 @@ void dgOutBuf::clear()
|
||||
//
|
||||
// dgOutBuf::setRecipient()
|
||||
//
|
||||
void dgOutBuf::setRecipient(const caAddr &addr)
|
||||
void dgOutBuf::setRecipient(const caNetAddr &addr)
|
||||
{
|
||||
this->to.set(addr);
|
||||
this->to = addr;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -64,8 +62,8 @@ void dgOutBuf::setRecipient(const caAddr &addr)
|
||||
//
|
||||
// dgOutBuf::getRecipient()
|
||||
//
|
||||
caAddr dgOutBuf::getRecipient()
|
||||
caNetAddr dgOutBuf::getRecipient()
|
||||
{
|
||||
return this->to.get();
|
||||
return this->to;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#ifndef dgOutBufILh
|
||||
#define dgOutBufILh
|
||||
|
||||
#include "casOpaqueAddrIL.h"
|
||||
#include "outBufIL.h"
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.16 1997/04/10 19:34:23 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.15 1997/01/10 21:18:05 jhill
|
||||
* code around gnu g++ inline bug when -O isnt used
|
||||
*
|
||||
@@ -115,7 +118,6 @@ HDRVERSIONID(serverh, "%W% %G%")
|
||||
//
|
||||
// CAS
|
||||
//
|
||||
#include "casAddr.h"
|
||||
#include "osiMutexCAS.h" // NOOP on single threaded OS
|
||||
void casVerifyFunc(const char *pFile, unsigned line, const char *pExp);
|
||||
void serverToolDebugFunc(const char *pFile, unsigned line, const char *pComment);
|
||||
@@ -335,15 +337,15 @@ public:
|
||||
|
||||
int hasAddress() const;
|
||||
|
||||
caAddr getSender() const;
|
||||
caNetAddr getSender() const;
|
||||
|
||||
xRecvStatus xRecv (char *pBufIn, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv);
|
||||
|
||||
virtual xRecvStatus xDGRecv (char *pBuf, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv, caAddr &sender) = 0;
|
||||
bufSizeT &nByesRecv, caNetAddr &sender) = 0;
|
||||
private:
|
||||
casOpaqueAddr from;
|
||||
caNetAddr from;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -416,9 +418,9 @@ public:
|
||||
|
||||
virtual ~dgOutBuf();
|
||||
|
||||
caAddr getRecipient();
|
||||
caNetAddr getRecipient();
|
||||
|
||||
void setRecipient(const caAddr &addr);
|
||||
void setRecipient(const caNetAddr &addr);
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -426,9 +428,9 @@ public:
|
||||
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent);
|
||||
|
||||
virtual xSendStatus xDGSend (char *pBuf, bufSizeT nBytesNeedToBeSent,
|
||||
bufSizeT &nBytesSent, const caAddr &recipient) = 0;
|
||||
bufSizeT &nBytesSent, const caNetAddr &recipient) = 0;
|
||||
private:
|
||||
casOpaqueAddr to;
|
||||
caNetAddr to;
|
||||
};
|
||||
|
||||
|
||||
@@ -476,23 +478,27 @@ public:
|
||||
// one virtual function for each CA request type that has
|
||||
// asynchronous completion
|
||||
//
|
||||
virtual caStatus asyncSearchResponse(casDGIntfIO &outMsgIO,
|
||||
const caAddr &outAddr, const caHdr &, const pvExistReturn);
|
||||
virtual caStatus createChanResponse(const caHdr &, const pvCreateReturn &);
|
||||
virtual caStatus readResponse(casChannelI *, const caHdr &,
|
||||
gdd *, const caStatus);
|
||||
virtual caStatus readNotifyResponse(casChannelI *, const caHdr &,
|
||||
gdd *, const caStatus);
|
||||
virtual caStatus writeResponse(casChannelI *, const caHdr &,
|
||||
const caStatus);
|
||||
virtual caStatus writeNotifyResponse(casChannelI *, const caHdr &,
|
||||
const caStatus);
|
||||
virtual caStatus asyncSearchResponse(
|
||||
casDGIntfIO &outMsgIO, const caNetAddr &outAddr,
|
||||
const caHdr &, const pvExistReturn &);
|
||||
virtual caStatus createChanResponse(
|
||||
const caHdr &, const pvCreateReturn &);
|
||||
virtual caStatus readResponse(
|
||||
casChannelI *, const caHdr &,
|
||||
gdd *, const caStatus);
|
||||
virtual caStatus readNotifyResponse(
|
||||
casChannelI *, const caHdr &,
|
||||
gdd *, const caStatus);
|
||||
virtual caStatus writeResponse(
|
||||
casChannelI *, const caHdr &, const caStatus);
|
||||
virtual caStatus writeNotifyResponse(
|
||||
casChannelI *, const caHdr &, const caStatus);
|
||||
|
||||
//
|
||||
// The following are only used with async IO for
|
||||
// DG clients
|
||||
//
|
||||
virtual caAddr fetchRespAddr();
|
||||
virtual caNetAddr fetchRespAddr();
|
||||
virtual casDGIntfIO* fetchOutIntf();
|
||||
protected:
|
||||
casCtx ctx;
|
||||
@@ -774,12 +780,12 @@ private:
|
||||
//
|
||||
caStatus searchFailResponse(const caHdr *pMsg);
|
||||
|
||||
caStatus searchResponse(const caHdr &, const pvExistReturn);
|
||||
caStatus searchResponse(const caHdr &, const pvExistReturn &);
|
||||
|
||||
caStatus asyncSearchResponse(casDGIntfIO &outMsgIO,
|
||||
const caAddr &outAddr, const caHdr &msg,
|
||||
const pvExistReturn);
|
||||
caAddr fetchRespAddr();
|
||||
caStatus asyncSearchResponse(
|
||||
casDGIntfIO &outMsgIO, const caNetAddr &outAddr,
|
||||
const caHdr &msg, const pvExistReturn &);
|
||||
caNetAddr fetchRespAddr();
|
||||
casDGIntfIO* fetchOutIntf();
|
||||
|
||||
|
||||
@@ -787,9 +793,9 @@ private:
|
||||
// IO depen
|
||||
//
|
||||
xRecvStatus xDGRecv (char *pBuf, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv, caAddr &sender);
|
||||
bufSizeT &nByesRecv, caNetAddr &sender);
|
||||
xSendStatus xDGSend (char *pBuf, bufSizeT nBytesNeedToBeSent,
|
||||
bufSizeT &nBytesSent, const caAddr &recipient);
|
||||
bufSizeT &nBytesSent, const caNetAddr &recipient);
|
||||
bufSizeT incommingBytesPresent() const;
|
||||
};
|
||||
|
||||
@@ -813,7 +819,7 @@ private:
|
||||
// casEventRegistry
|
||||
//
|
||||
class casEventRegistry : private resTable <casEventMaskEntry, stringId> {
|
||||
friend casEventMaskEntry;
|
||||
friend class casEventMaskEntry;
|
||||
public:
|
||||
casEventRegistry(osiMutex &mutexIn) :
|
||||
mutex(mutexIn), allocator(0), hasBeenInitialized(0) {}
|
||||
@@ -842,24 +848,6 @@ private:
|
||||
|
||||
class casClientMon;
|
||||
|
||||
//
|
||||
// casPVExistReturn
|
||||
//
|
||||
// special return code for the server internal version of pvExistTest()
|
||||
//
|
||||
class casPVExistReturn {
|
||||
public:
|
||||
casPVExistReturn(pvExistReturn appIn)
|
||||
{app=appIn; stat = S_cas_success; }
|
||||
casPVExistReturn(caStatus statIn)
|
||||
{app=pverDoesNotExistHere; stat = statIn; }
|
||||
caStatus getStatus() const {return stat;}
|
||||
pvExistReturn getAppStat() const {return app;}
|
||||
private:
|
||||
pvExistReturn app;
|
||||
caStatus stat;
|
||||
};
|
||||
|
||||
//
|
||||
// caServerI
|
||||
//
|
||||
@@ -909,7 +897,6 @@ public:
|
||||
|
||||
unsigned getDebugLevel() const { return debugLevel; }
|
||||
inline void setDebugLevel(unsigned debugLevelIn);
|
||||
inline casPVExistReturn pvExistTest (const casCtx &ctx, const char *pPVName);
|
||||
|
||||
osiTime getBeaconPeriod() const { return this->beaconPeriod; }
|
||||
|
||||
@@ -932,7 +919,7 @@ public:
|
||||
|
||||
inline aitBool ready();
|
||||
|
||||
caStatus addAddr(const caAddr &caAddr, int autoBeaconAddr,
|
||||
caStatus addAddr(const caNetAddr &addr, int autoBeaconAddr,
|
||||
int addConfigAddr);
|
||||
private:
|
||||
void advanceBeaconPeriod();
|
||||
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
//
|
||||
// casIntfOS::init()
|
||||
//
|
||||
caStatus casIntfOS::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
caStatus casIntfOS::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
|
||||
int autoBeaconAddr, int addConfigBeaconAddr)
|
||||
{
|
||||
caStatus stat;
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// Some BSD calls have crept in here
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1997/04/10 19:34:31 jhill
|
||||
// API changes
|
||||
//
|
||||
// Revision 1.1 1996/11/02 01:01:32 jhill
|
||||
// installed
|
||||
//
|
||||
@@ -83,7 +86,7 @@ class casIntfOS : public casIntfIO, public tsDLNode<casIntfOS>
|
||||
public:
|
||||
casIntfOS (caServerI &casIn) :
|
||||
cas (casIn), pRdReg (NULL) {}
|
||||
caStatus init(const caAddr &addr, casDGClient &dgClientIn,
|
||||
caStatus init(const caNetAddr &addr, casDGClient &dgClientIn,
|
||||
int autoBeaconAddr, int addConfigBeaconAddr);
|
||||
virtual ~casIntfOS();
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// (for single threaded version of the server)
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1997/04/10 19:34:32 jhill
|
||||
// API changes
|
||||
//
|
||||
// Revision 1.1 1996/11/02 01:01:34 jhill
|
||||
// installed
|
||||
//
|
||||
@@ -19,7 +22,7 @@
|
||||
|
||||
|
||||
//
|
||||
// ioBlocked::~ioBlocked()
|
||||
// ioBlocked::ioBlocked()
|
||||
//
|
||||
ioBlocked::ioBlocked() :
|
||||
pList(NULL)
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.4 1997/04/10 19:40:31 jhill
|
||||
// API changes
|
||||
//
|
||||
// Revision 1.3 1996/11/02 00:54:42 jhill
|
||||
// many improvements
|
||||
//
|
||||
@@ -20,6 +23,7 @@
|
||||
|
||||
#include "server.h"
|
||||
#include "sigPipeIgnore.h"
|
||||
#include "addrList.h"
|
||||
|
||||
static char *getToken(const char **ppString, char *pBuf, unsigned bufSIze);
|
||||
|
||||
@@ -52,12 +56,12 @@ inline void caServerIO::staticInit()
|
||||
//
|
||||
caStatus caServerIO::init(caServerI &cas)
|
||||
{
|
||||
char buf[64u];
|
||||
const char *pStr;
|
||||
char buf[64u];
|
||||
const char *pStr;
|
||||
char *pToken;
|
||||
caStatus stat;
|
||||
unsigned short port;
|
||||
caAddr addr;
|
||||
struct sockaddr_in saddr;
|
||||
int autoBeaconAddr;
|
||||
|
||||
caServerIO::staticInit();
|
||||
@@ -75,9 +79,9 @@ caStatus caServerIO::init(caServerI &cas)
|
||||
port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
|
||||
}
|
||||
|
||||
memset((char *)&addr,0,sizeof(addr));
|
||||
addr.sa.sa_family = AF_INET;
|
||||
addr.in.sin_port = ntohs (port);
|
||||
memset((char *)&saddr,0,sizeof(saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = ntohs (port);
|
||||
|
||||
pStr = envGetConfigParam(&EPICS_CA_AUTO_ADDR_LIST, sizeof(buf), buf);
|
||||
if (pStr) {
|
||||
@@ -106,8 +110,8 @@ caStatus caServerIO::init(caServerI &cas)
|
||||
int configAddrOnceFlag = TRUE;
|
||||
stat = S_cas_noInterface;
|
||||
while ( (pToken = getToken(&pStr, buf, sizeof(buf))) ) {
|
||||
addr.in.sin_addr.s_addr = inet_addr(pToken);
|
||||
if (addr.in.sin_addr.s_addr == ~0ul) {
|
||||
saddr.sin_addr.s_addr = inet_addr(pToken);
|
||||
if (saddr.sin_addr.s_addr == ~0ul) {
|
||||
ca_printf(
|
||||
"%s: Parsing '%s'\n",
|
||||
__FILE__,
|
||||
@@ -117,7 +121,7 @@ caStatus caServerIO::init(caServerI &cas)
|
||||
pToken);
|
||||
continue;
|
||||
}
|
||||
stat = cas.addAddr(addr, autoBeaconAddr, configAddrOnceFlag);
|
||||
stat = cas.addAddr(caNetAddr(saddr), autoBeaconAddr, configAddrOnceFlag);
|
||||
if (stat) {
|
||||
errMessage(stat, NULL);
|
||||
break;
|
||||
@@ -126,8 +130,8 @@ caStatus caServerIO::init(caServerI &cas)
|
||||
}
|
||||
}
|
||||
else {
|
||||
addr.in.sin_addr.s_addr = INADDR_ANY;
|
||||
stat = cas.addAddr(addr, autoBeaconAddr, TRUE);
|
||||
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||
stat = cas.addAddr(caNetAddr(saddr), autoBeaconAddr, TRUE);
|
||||
if (stat) {
|
||||
errMessage(stat, NULL);
|
||||
}
|
||||
@@ -175,4 +179,3 @@ static char *getToken(const char **ppString, char *pBuf, unsigned bufSIze)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
void casDGIO::clientHostName (char *pBufIn, unsigned bufSizeIn) const
|
||||
{
|
||||
if (this->hasAddress()) {
|
||||
const caAddr addr = this->getSender();
|
||||
ipAddrToA (&addr.in, pBufIn, bufSizeIn);
|
||||
struct sockaddr_in addr = this->getSender();
|
||||
ipAddrToA (&addr, pBufIn, bufSizeIn);
|
||||
}
|
||||
else {
|
||||
if (bufSizeIn>=1u) {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "server.h"
|
||||
#include "ipAddrToA.h"
|
||||
#include "addrList.h"
|
||||
|
||||
//
|
||||
// casDGIntfIO::casDGIntfIO()
|
||||
@@ -45,7 +46,8 @@ casDGIntfIO::casDGIntfIO(casDGClient &clientIn) :
|
||||
client(clientIn),
|
||||
sock(INVALID_SOCKET),
|
||||
sockState(casOffLine),
|
||||
connectWithThisPort(0)
|
||||
connectWithThisPort(0),
|
||||
dgPort(0)
|
||||
{
|
||||
ellInit(&this->beaconAddrList);
|
||||
}
|
||||
@@ -53,16 +55,15 @@ casDGIntfIO::casDGIntfIO(casDGClient &clientIn) :
|
||||
//
|
||||
// casDGIntfIO::init()
|
||||
//
|
||||
caStatus casDGIntfIO::init(const caAddr &addr, unsigned connectWithThisPortIn,
|
||||
caStatus casDGIntfIO::init(const caNetAddr &addr, unsigned connectWithThisPortIn,
|
||||
int autoBeaconAddr, int addConfigBeaconAddr,
|
||||
int useBroadcastAddr, casDGIntfIO *pAltOutIn)
|
||||
{
|
||||
int yes = TRUE;
|
||||
caAddr serverAddr;
|
||||
int status;
|
||||
unsigned short serverPort;
|
||||
unsigned short beaconPort;
|
||||
ELLLIST BCastAddrList;
|
||||
int yes = TRUE;
|
||||
struct sockaddr_in serverAddr;
|
||||
int status;
|
||||
aitInt16 beaconPort;
|
||||
ELLLIST BCastAddrList;
|
||||
|
||||
if (pAltOutIn) {
|
||||
this->pAltOutIO = pAltOutIn;
|
||||
@@ -133,11 +134,11 @@ caStatus casDGIntfIO::init(const caAddr &addr, unsigned connectWithThisPortIn,
|
||||
// Fetch port configuration from EPICS environment variables
|
||||
//
|
||||
if (envGetConfigParamPtr(&EPICS_CAS_SERVER_PORT)) {
|
||||
serverPort = caFetchPortConfig(&EPICS_CAS_SERVER_PORT,
|
||||
this->dgPort = caFetchPortConfig(&EPICS_CAS_SERVER_PORT,
|
||||
CA_SERVER_PORT);
|
||||
}
|
||||
else {
|
||||
serverPort = caFetchPortConfig(&EPICS_CA_SERVER_PORT,
|
||||
this->dgPort = caFetchPortConfig(&EPICS_CA_SERVER_PORT,
|
||||
CA_SERVER_PORT);
|
||||
}
|
||||
beaconPort = caFetchPortConfig(&EPICS_CA_REPEATER_PORT,
|
||||
@@ -146,21 +147,21 @@ caStatus casDGIntfIO::init(const caAddr &addr, unsigned connectWithThisPortIn,
|
||||
/*
|
||||
* discover beacon addresses associated with this interface
|
||||
*/
|
||||
serverAddr.in = addr.in;
|
||||
serverAddr = addr;
|
||||
if (autoBeaconAddr || useBroadcastAddr) {
|
||||
ellInit(&BCastAddrList);
|
||||
caDiscoverInterfaces(
|
||||
&BCastAddrList,
|
||||
this->sock,
|
||||
beaconPort,
|
||||
serverAddr.in.sin_addr); /* match addr */
|
||||
serverAddr.sin_addr); /* match addr */
|
||||
if (useBroadcastAddr) {
|
||||
caAddrNode *pAddr;
|
||||
if (ellCount(&BCastAddrList)!=1) {
|
||||
return S_cas_noInterface;
|
||||
}
|
||||
pAddr = (caAddrNode *) ellFirst(&BCastAddrList);
|
||||
serverAddr.in.sin_addr = pAddr->destAddr.in.sin_addr;
|
||||
serverAddr.sin_addr = pAddr->destAddr.in.sin_addr;
|
||||
}
|
||||
if (autoBeaconAddr) {
|
||||
ellConcat(&this->beaconAddrList, &BCastAddrList);
|
||||
@@ -170,17 +171,17 @@ caStatus casDGIntfIO::init(const caAddr &addr, unsigned connectWithThisPortIn,
|
||||
}
|
||||
}
|
||||
|
||||
serverAddr.in.sin_port = htons (serverPort);
|
||||
serverAddr.sin_port = htons (this->dgPort);
|
||||
status = bind(
|
||||
this->sock,
|
||||
&serverAddr.sa,
|
||||
sizeof (serverAddr.sa));
|
||||
(struct sockaddr *)&serverAddr,
|
||||
sizeof (serverAddr));
|
||||
if (status<0) {
|
||||
errPrintf(S_cas_bindFail,
|
||||
__FILE__, __LINE__,
|
||||
"- bind UDP IP addr=%s port=%u failed because %s",
|
||||
inet_ntoa(serverAddr.in.sin_addr),
|
||||
(unsigned) serverPort,
|
||||
inet_ntoa(serverAddr.sin_addr),
|
||||
(unsigned) this->dgPort,
|
||||
strerror(SOCKERRNO));
|
||||
return S_cas_bindFail;
|
||||
}
|
||||
@@ -278,18 +279,19 @@ void casDGIntfIO::xSetNonBlocking()
|
||||
// casDGIntfIO::osdRecv()
|
||||
//
|
||||
xRecvStatus casDGIntfIO::osdRecv(char *pBuf, bufSizeT size,
|
||||
bufSizeT &actualSize, caAddr &from)
|
||||
bufSizeT &actualSize, caNetAddr &fromOut)
|
||||
{
|
||||
int status;
|
||||
int addrSize;
|
||||
struct sockaddr from;
|
||||
|
||||
if (this->sockState!=casOnLine) {
|
||||
return xRecvDisconnect;
|
||||
}
|
||||
|
||||
addrSize = sizeof(from.sa);
|
||||
addrSize = sizeof(from);
|
||||
status = recvfrom(this->sock, pBuf, size, 0,
|
||||
&from.sa, &addrSize);
|
||||
&from, &addrSize);
|
||||
if (status<0) {
|
||||
if(SOCKERRNO == EWOULDBLOCK){
|
||||
actualSize = 0u;
|
||||
@@ -303,6 +305,7 @@ xRecvStatus casDGIntfIO::osdRecv(char *pBuf, bufSizeT size,
|
||||
}
|
||||
}
|
||||
|
||||
fromOut = from;
|
||||
actualSize = (bufSizeT) status;
|
||||
return xRecvOK;
|
||||
}
|
||||
@@ -311,7 +314,7 @@ xRecvStatus casDGIntfIO::osdRecv(char *pBuf, bufSizeT size,
|
||||
// casDGIntfIO::osdSend()
|
||||
//
|
||||
xSendStatus casDGIntfIO::osdSend(const char *pBuf, bufSizeT size,
|
||||
bufSizeT &actualSize, const caAddr &to)
|
||||
bufSizeT &actualSize, const caNetAddr &to)
|
||||
{
|
||||
int status;
|
||||
int anerrno;
|
||||
@@ -328,8 +331,9 @@ xSendStatus casDGIntfIO::osdSend(const char *pBuf, bufSizeT size,
|
||||
//
|
||||
// (char *) cast below is for brain dead wrs prototype
|
||||
//
|
||||
struct sockaddr dest = to;
|
||||
status = sendto(this->sock, (char *) pBuf, size, 0,
|
||||
(sockaddr *) &to.sa, sizeof(to.sa));
|
||||
&dest, sizeof(dest));
|
||||
if (status>0) {
|
||||
if (size != (unsigned) status) {
|
||||
ca_printf ("CAS: partial UDP msg discarded??\n");
|
||||
@@ -360,7 +364,7 @@ xSendStatus casDGIntfIO::osdSend(const char *pBuf, bufSizeT size,
|
||||
//
|
||||
// casDGIntfIO::sendBeacon()
|
||||
//
|
||||
void casDGIntfIO::sendBeacon(char &msg, unsigned length, aitUint32 &m_avail)
|
||||
void casDGIntfIO::sendBeacon(char &msg, unsigned length, aitUint32 &m_ipa, aitUint16 &m_port)
|
||||
{
|
||||
caAddrNode *pAddr;
|
||||
int status;
|
||||
@@ -373,8 +377,8 @@ void casDGIntfIO::sendBeacon(char &msg, unsigned length, aitUint32 &m_avail)
|
||||
pAddr;
|
||||
pAddr = (caAddrNode *)ellNext(&pAddr->node)) {
|
||||
|
||||
m_avail = htonl(pAddr->srcAddr.in.sin_addr.s_addr);
|
||||
|
||||
m_ipa = htonl(pAddr->srcAddr.in.sin_addr.s_addr);
|
||||
m_port = htons(this->dgPort);
|
||||
status = sendto(
|
||||
this->sock,
|
||||
&msg,
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// Some BSD calls have crept in here
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.7 1997/01/10 21:18:55 jhill
|
||||
// code around gnu g++ inline bug when -O isnt used
|
||||
//
|
||||
// Revision 1.6 1996/11/02 00:54:45 jhill
|
||||
// many improvements
|
||||
//
|
||||
@@ -30,9 +33,10 @@
|
||||
#ifndef includeCASIODH
|
||||
#define includeCASIODH
|
||||
|
||||
void hostNameFromIPAddr (const caAddr *pAddr,
|
||||
char *pBuf, unsigned bufSize);
|
||||
#include "envDefs.h"
|
||||
|
||||
void hostNameFromIPAddr (const caNetAddr *pAddr,
|
||||
char *pBuf, unsigned bufSize);
|
||||
|
||||
class casDGClient;
|
||||
|
||||
@@ -42,21 +46,21 @@ class casDGClient;
|
||||
class casDGIntfIO {
|
||||
public:
|
||||
casDGIntfIO (casDGClient &clientIn);
|
||||
caStatus init(const caAddr &addr, unsigned connectWithThisPort,
|
||||
caStatus init(const caNetAddr &addr, unsigned connectWithThisPort,
|
||||
int autoBeaconAddr=TRUE, int addConfigBeaconAddr=FALSE,
|
||||
int useBroadcastAddr=FALSE, casDGIntfIO *pAltOutIn=NULL);
|
||||
virtual ~casDGIntfIO();
|
||||
|
||||
int getFD() const;
|
||||
void xSetNonBlocking();
|
||||
void sendBeacon(char &msg, bufSizeT length, aitUint32 &m_avail);
|
||||
void sendBeacon(char &msg, bufSizeT length, aitUint32 &m_ipa, aitUint16 &m_port);
|
||||
casIOState state() const;
|
||||
void clientHostName (char *pBuf, unsigned bufSize) const;
|
||||
|
||||
xSendStatus osdSend (const char *pBuf, bufSizeT nBytesReq,
|
||||
bufSizeT &nBytesActual, const caAddr &addr);
|
||||
bufSizeT &nBytesActual, const caNetAddr &addr);
|
||||
xRecvStatus osdRecv (char *pBuf, bufSizeT nBytesReq,
|
||||
bufSizeT &nBytesActual, caAddr &addr);
|
||||
bufSizeT &nBytesActual, caNetAddr &addr);
|
||||
void osdShow (unsigned level) const;
|
||||
|
||||
static bufSizeT optimumBufferSize ();
|
||||
@@ -78,10 +82,11 @@ private:
|
||||
SOCKET sock;
|
||||
casIOState sockState;
|
||||
aitInt16 connectWithThisPort;
|
||||
aitInt16 dgPort;
|
||||
};
|
||||
|
||||
struct ioArgsToNewStreamIO {
|
||||
caAddr addr;
|
||||
caNetAddr addr;
|
||||
SOCKET sock;
|
||||
};
|
||||
|
||||
@@ -133,14 +138,14 @@ public:
|
||||
//
|
||||
unsigned serverPortNumber();
|
||||
|
||||
const caAddr &getAddr()
|
||||
const caNetAddr getAddr()
|
||||
{
|
||||
return addr;
|
||||
return caNetAddr(this->addr);
|
||||
}
|
||||
private:
|
||||
casIOState sockState;
|
||||
SOCKET sock;
|
||||
caAddr addr;
|
||||
struct sockaddr_in addr;
|
||||
xBlockingStatus blockingFlag;
|
||||
};
|
||||
|
||||
@@ -156,7 +161,7 @@ class casIntfIO {
|
||||
public:
|
||||
casIntfIO();
|
||||
//constructor does not return status
|
||||
caStatus init(const caAddr &addr, casDGClient &dgClientIn,
|
||||
caStatus init(const caNetAddr &addr, casDGClient &dgClientIn,
|
||||
int autoBeaconAddr, int addConfigBeaconAddr);
|
||||
virtual ~casIntfIO();
|
||||
void show(unsigned level) const;
|
||||
@@ -180,7 +185,7 @@ private:
|
||||
casDGIntfIO *pNormalUDP; // attached to this intf's addr
|
||||
casDGIntfIO *pBCastUDP; // attached to this intf's broadcast addr
|
||||
SOCKET sock;
|
||||
caAddr addr;
|
||||
struct sockaddr_in addr;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -208,6 +213,7 @@ private:
|
||||
static inline void staticInit();
|
||||
};
|
||||
|
||||
|
||||
// no additions below this line
|
||||
#endif // includeCASIODH
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1997/04/10 19:40:33 jhill
|
||||
// API changes
|
||||
//
|
||||
// Revision 1.1 1996/11/02 01:01:41 jhill
|
||||
// installed
|
||||
//
|
||||
@@ -32,7 +35,7 @@ casIntfIO::casIntfIO() :
|
||||
//
|
||||
// casIntfIO::init()
|
||||
//
|
||||
caStatus casIntfIO::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
|
||||
int autoBeaconAddr, int addConfigBeaconAddr)
|
||||
{
|
||||
int yes = TRUE;
|
||||
@@ -63,10 +66,10 @@ caStatus casIntfIO::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
return S_cas_internal;
|
||||
}
|
||||
|
||||
this->addr = addrIn;
|
||||
this->addr = addrIn.getSockIP();
|
||||
status = bind(
|
||||
this->sock,
|
||||
(sockaddr *) &this->addr.sa,
|
||||
(sockaddr *) &this->addr,
|
||||
sizeof(this->addr));
|
||||
if (status<0) {
|
||||
if (SOCKERRNO == EADDRINUSE) {
|
||||
@@ -75,25 +78,27 @@ caStatus casIntfIO::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
// (so the getsockname() call below will
|
||||
// work correctly)
|
||||
//
|
||||
this->addr.in.sin_port = ntohs (0);
|
||||
|
||||
this->addr.sin_port = ntohs (0);
|
||||
status = bind(
|
||||
this->sock,
|
||||
&this->addr.sa,
|
||||
(sockaddr *)&this->addr,
|
||||
sizeof(this->addr));
|
||||
}
|
||||
if (status<0) {
|
||||
errPrintf(S_cas_bindFail,
|
||||
__FILE__, __LINE__,
|
||||
"- bind TCP IP addr=%s port=%u failed because %s",
|
||||
inet_ntoa(this->addr.in.sin_addr),
|
||||
ntohs(this->addr.in.sin_port),
|
||||
inet_ntoa(this->addr.sin_addr),
|
||||
ntohs(this->addr.sin_port),
|
||||
strerror(SOCKERRNO));
|
||||
return S_cas_bindFail;
|
||||
}
|
||||
}
|
||||
|
||||
addrSize = sizeof(this->addr);
|
||||
status = getsockname(this->sock, &this->addr.sa, &addrSize);
|
||||
status = getsockname(this->sock,
|
||||
(struct sockaddr *)&this->addr, &addrSize);
|
||||
if (status) {
|
||||
ca_printf("CAS: getsockname() error %s\n", strerror(SOCKERRNO));
|
||||
return S_cas_internal;
|
||||
@@ -103,7 +108,7 @@ caStatus casIntfIO::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
// be sure of this now so that we can fetch the IP
|
||||
// address and port number later
|
||||
//
|
||||
assert (this->addr.sa.sa_family == AF_INET);
|
||||
assert (this->addr.sin_family == AF_INET);
|
||||
|
||||
status = listen(this->sock, caServerConnectPendQueueSize);
|
||||
if(status < 0) {
|
||||
@@ -119,7 +124,7 @@ caStatus casIntfIO::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
if (!this->pNormalUDP) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
stat = this->pNormalUDP->init(addr, this->portNumber(),
|
||||
stat = this->pNormalUDP->init(this->addr, this->portNumber(),
|
||||
autoBeaconAddr, addConfigBeaconAddr);
|
||||
if (stat) {
|
||||
return stat;
|
||||
@@ -133,7 +138,7 @@ caStatus casIntfIO::init(const caAddr &addrIn, casDGClient &dgClientIn,
|
||||
// we will also need to bind to the broadcast address
|
||||
// for that interface (if it has one)
|
||||
//
|
||||
if (this->addr.in.sin_addr.s_addr != INADDR_ANY) {
|
||||
if (this->addr.sin_addr.s_addr != INADDR_ANY) {
|
||||
this->pBCastUDP = this->newDGIntfIO(dgClientIn);
|
||||
if (this->pBCastUDP) {
|
||||
stat = this->pBCastUDP->init(addr, this->portNumber(),
|
||||
@@ -181,13 +186,13 @@ casIntfIO::~casIntfIO()
|
||||
//
|
||||
casStreamOS *casIntfIO::newStreamClient(caServerI &cas) const
|
||||
{
|
||||
caAddr newAddr;
|
||||
struct sockaddr newAddr;
|
||||
SOCKET newSock;
|
||||
int length;
|
||||
casStreamOS *pOS;
|
||||
|
||||
length = sizeof(newAddr.sa);
|
||||
newSock = accept(this->sock, &newAddr.sa, &length);
|
||||
length = sizeof(newAddr);
|
||||
newSock = accept(this->sock, &newAddr, &length);
|
||||
if (newSock==INVALID_SOCKET) {
|
||||
if (SOCKERRNO!=EWOULDBLOCK) {
|
||||
ca_printf(
|
||||
@@ -197,7 +202,7 @@ casStreamOS *casIntfIO::newStreamClient(caServerI &cas) const
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else if (sizeof(newAddr.sa)>(size_t)length) {
|
||||
else if (sizeof(newAddr)>(size_t)length) {
|
||||
socket_close(newSock);
|
||||
ca_printf("CAS: accept returned bad address len?\n");
|
||||
return NULL;
|
||||
@@ -252,7 +257,7 @@ void casIntfIO::show(unsigned level) const
|
||||
//
|
||||
unsigned casIntfIO::portNumber() const
|
||||
{
|
||||
return ntohs(this->addr.in.sin_port);
|
||||
return ntohs(this->addr.sin_port);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.11 1997/05/01 19:59:09 jhill
|
||||
// new header file for ipAddrToA()
|
||||
//
|
||||
// Revision 1.10 1997/04/23 17:27:01 jhill
|
||||
// use matching buffer sizes
|
||||
//
|
||||
@@ -218,7 +221,7 @@ xRecvStatus casStreamIO::osdRecv(char *pInBuf, bufSizeT nBytes,
|
||||
break;
|
||||
|
||||
default:
|
||||
ipAddrToA(&this->addr.in, buf, sizeof(buf));
|
||||
ipAddrToA(&this->addr, buf, sizeof(buf));
|
||||
ca_printf(
|
||||
"CAS: client %s disconnected because \"%s\"\n",
|
||||
buf, strerror(SOCKERRNO));
|
||||
@@ -240,10 +243,10 @@ void casStreamIO::osdShow (unsigned level) const
|
||||
printf ("casStreamIO at %x\n", (unsigned) this);
|
||||
if (level>1u) {
|
||||
char buf[64];
|
||||
ipAddrToA(&this->addr.in, buf, sizeof(buf));
|
||||
ipAddrToA(&this->addr, buf, sizeof(buf));
|
||||
printf (
|
||||
"client=%s, port=%x\n",
|
||||
buf, ntohs(this->addr.in.sin_port));
|
||||
buf, ntohs(this->addr.sin_port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +305,7 @@ bufSizeT casStreamIO::incommingBytesPresent() const
|
||||
break;
|
||||
|
||||
default:
|
||||
ipAddrToA(&this->addr.in, buf, sizeof(buf));
|
||||
ipAddrToA(&this->addr, buf, sizeof(buf));
|
||||
ca_printf(
|
||||
"CAS: FIONREAD for %s failed because \"%s\"\n",
|
||||
buf, strerror(SOCKERRNO));
|
||||
@@ -323,7 +326,7 @@ bufSizeT casStreamIO::incommingBytesPresent() const
|
||||
//
|
||||
void casStreamIO::clientHostName (char *pInBuf, unsigned bufSizeIn) const
|
||||
{
|
||||
ipAddrToA (&this->addr.in, pInBuf, bufSizeIn);
|
||||
ipAddrToA (&this->addr, pInBuf, bufSizeIn);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// Some BSD calls have crept in here
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.3 1996/11/02 00:55:00 jhill
|
||||
// many improvements
|
||||
//
|
||||
// Revision 1.2 1996/09/16 18:27:10 jhill
|
||||
// vxWorks port changes
|
||||
//
|
||||
@@ -103,7 +106,7 @@ class casIntfOS : public casIntfIO, public tsDLNode<casIntfOS>
|
||||
public:
|
||||
casIntfOS (caServerI &casIn) :
|
||||
cas (casIn), pRdReg (NULL) {}
|
||||
caStatus init(const caAddr &addr, casDGClient &dgClientIn,
|
||||
caStatus init(const caNetAddr &addr, casDGClient &dgClientIn,
|
||||
int autoBeaconAddr, int addConfigBeaconAddr);
|
||||
~casIntfOS();
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.9 1997/04/23 17:11:15 jhill
|
||||
* stringId::T[] => stringIdFastHash[]
|
||||
*
|
||||
* Revision 1.8 1997/04/10 19:43:09 jhill
|
||||
* API changes
|
||||
*
|
||||
@@ -66,6 +69,7 @@
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "tsSLList.h"
|
||||
#include "shareLib.h"
|
||||
@@ -322,7 +326,7 @@ public:
|
||||
// CPU architectures)
|
||||
//
|
||||
unsigned long src = (unsigned long) this->id;
|
||||
resTableIndex hashid;
|
||||
unsigned long hashid;
|
||||
|
||||
hashid = src;
|
||||
src = src >> nBitsId;
|
||||
@@ -334,7 +338,7 @@ public:
|
||||
// the result here is always masked to the
|
||||
// proper size after it is returned to the resource class
|
||||
//
|
||||
return hashid;
|
||||
return (resTableIndex) hashid;
|
||||
}
|
||||
|
||||
int operator == (const ptrId &idIn)
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.8 1997/04/11 20:49:48 jhill
|
||||
* added no arg reset() to bwd iter
|
||||
*
|
||||
* Revision 1.7 1997/04/10 19:43:10 jhill
|
||||
* API changes
|
||||
*
|
||||
@@ -58,6 +61,12 @@
|
||||
#ifndef tsDLListH_include
|
||||
#define tsDLListH_include
|
||||
|
||||
template <class T> class tsDLList;
|
||||
template <class T> class tsDLIterBD;
|
||||
template <class T> class tsDLIter;
|
||||
template <class T> class tsDLFwdIter;
|
||||
template <class T> class tsDLBwdIter;
|
||||
|
||||
//
|
||||
// tsDLNode<T>
|
||||
// NOTE: T must derive from tsDLNode<T>
|
||||
@@ -507,7 +516,7 @@ protected:
|
||||
template <class T>
|
||||
class tsDLFwdIter: private tsDLIter<T> {
|
||||
public:
|
||||
tsDLFwdIter (tsDLList<T> &listIn) :
|
||||
tsDLFwdIter (const tsDLList<T> &listIn) :
|
||||
tsDLIter<T>(listIn) {}
|
||||
|
||||
void reset ()
|
||||
@@ -587,7 +596,7 @@ public:
|
||||
template <class T>
|
||||
class tsDLBwdIter : private tsDLIter<T> {
|
||||
public:
|
||||
tsDLBwdIter(tsDLList<T> &listIn) :
|
||||
tsDLBwdIter(const tsDLList<T> &listIn) :
|
||||
tsDLIter<T>(listIn) {}
|
||||
|
||||
void reset ()
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.7 1997/04/10 19:43:10 jhill
|
||||
* API changes
|
||||
*
|
||||
* Revision 1.6 1997/01/22 21:14:21 jhill
|
||||
* fixed class decl order for VMS
|
||||
*
|
||||
@@ -52,6 +55,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// the hp compiler complains about parameterized friend
|
||||
// class that has not been declared without this?
|
||||
//
|
||||
template <class T> class tsSLList;
|
||||
template <class T> class tsSLIter;
|
||||
template <class T> class tsSLIterRm;
|
||||
|
||||
//
|
||||
// tsSLNode<>
|
||||
// NOTE: T must derive from tsSLNode<T>
|
||||
|
||||
@@ -62,8 +62,7 @@ device(ai,CONSTANT,devAiSoft,"Soft Channel")
|
||||
#device(ai,VME_IO,devAiAt5Vxi,"VXI-AT5-AI")
|
||||
#device(ai,GPIB_IO,devAiK486Gpib,"Keithley-486")
|
||||
#device(ai,VME_IO,devAiKscV215,"KSC-V215")
|
||||
#device(ai,VME_IO,devAiSysmon,"SYSMON")
|
||||
#device(ai,VME_IO,devAiStats,"VX stats")
|
||||
#device(ai,VME_IO,devAiVXStats,"VX stats")
|
||||
#device(aai,CAMAC_IO,devAaiCamac,"Camac")
|
||||
device(ao,CONSTANT,devAoSoft,"Soft Channel")
|
||||
#device(ao,CONSTANT,devAoSoftRaw,"Raw Soft Channel")
|
||||
@@ -74,7 +73,7 @@ device(ao,CONSTANT,devAoSoft,"Soft Channel")
|
||||
#device(ao,AB_IO,devAoAbSclDcm,"AB-SCL500DCM")
|
||||
#device(ao,CAMAC_IO,devAoCamac,"Camac")
|
||||
#device(ao,VME_IO,devAoAt5Vxi,"VXI-AT5-AO")
|
||||
#device(ao,VME_IO,devAoStats,"VX stats")
|
||||
#device(ao,VME_IO,devAoVXStats,"VX stats")
|
||||
device(bi,CONSTANT,devBiSoft,"Soft Channel")
|
||||
#device(bi,CONSTANT,devBiSoftRaw,"Raw Soft Channel")
|
||||
#device(bi,VME_IO,devBiMpv910,"MPV-910")
|
||||
@@ -89,7 +88,6 @@ device(bi,CONSTANT,devBiSoft,"Soft Channel")
|
||||
#device(bi,VME_IO,devBiHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(bi,VME_IO,devBiAt8Fp,"AT8-FP10S")
|
||||
#device(bi,VME_IO,devBiAvme9440,"AVME9440 I")
|
||||
#device(bi,VME_IO,devBiSysmon,"SYSMON")
|
||||
#device(bi,VME_IO,devBiMpc,"MPC")
|
||||
device(bo,CONSTANT,devBoSoft,"Soft Channel")
|
||||
#device(bo,CONSTANT,devBoSoftRaw,"Raw Soft Channel")
|
||||
@@ -106,7 +104,6 @@ device(bo,CONSTANT,devBoSoft,"Soft Channel")
|
||||
#device(bo,VME_IO,devBoHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(bo,VME_IO,devBoAt8Fp,"AT8-FP10S")
|
||||
#device(bo,VME_IO,devBoAvme9440,"AVME9440 O")
|
||||
#device(bo,VME_IO,devBoSysmon,"SYSMON")
|
||||
#device(bo,VME_IO,devBoMpc,"MPC")
|
||||
device(event,CONSTANT,devEventSoft,"Soft Channel")
|
||||
#device(event,VME_IO,devEventMz8310,"Mizar-8310")
|
||||
@@ -138,7 +135,6 @@ device(mbbi,CONSTANT,devMbbiSoft,"Soft Channel")
|
||||
#device(mbbi,VME_IO,devMbbiHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(mbbi,VME_IO,devMbbiAt8Fp,"AT8-FP10S")
|
||||
#device(mbbi,VME_IO,devMbbiAvme9440,"AVME9440 I")
|
||||
#device(mbbi,VME_IO,devMbbiSysmon,"SYSMON")
|
||||
device(mbbiDirect,CONSTANT,devMbbiDirectSoft,"Soft Channel")
|
||||
#device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel")
|
||||
#device(mbbiDirect,VME_IO,devMbbiDirectMpv910,"MPV-910")
|
||||
@@ -162,7 +158,6 @@ device(mbbo,CONSTANT,devMbboSoft,"Soft Channel")
|
||||
#device(mbbo,VME_IO,devMbboHpe1368a,"VXI-HPE1368-VS")
|
||||
#device(mbbo,VME_IO,devMbboAt8Fp,"AT8-FP10S")
|
||||
#device(mbbo,VME_IO,devMbboAvme9440,"AVME9440 O")
|
||||
#device(mbbo,VME_IO,devMbboSysmon,"SYSMON")
|
||||
device(mbboDirect,CONSTANT,devMbboDirectSoft,"Soft Channel")
|
||||
#device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel")
|
||||
#device(mbboDirect,VME_IO,devMbboDirectMpv902,"MPV-902")
|
||||
@@ -174,7 +169,6 @@ device(mbboDirect,CONSTANT,devMbboDirectSoft,"Soft Channel")
|
||||
#device(mbboDirect,VME_IO,devMbboDirectAt5Vxi,"VXI-AT5-BO")
|
||||
#device(pulseCounter,VME_IO,devPcMz8310,"Mizar-8310")
|
||||
#device(pulseDelay,VME_IO,devPdMz8310,"Mizar-8310")
|
||||
#device(pulseDelay,VXI_IO,devPdVxiTDM,"VXI Time Delay Module")
|
||||
#device(pulseTrain,CONSTANT,devPtSoft,"Soft Channel")
|
||||
#device(pulseTrain,VME_IO,devPtMz8310,"Mizar-8310")
|
||||
#device(steppermotor,VME_IO,devSmCompumotor1830,"Compumotor 1830")
|
||||
|
||||
@@ -51,7 +51,7 @@ LIBOBJS += $(EPICS_BASE_BIN)/waveformRecord.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiKscV215.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiSoftRaw.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiStats.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devVXStats.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiSymb.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devAiTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAiXy566Di.o
|
||||
@@ -126,9 +126,7 @@ LIBOBJS += $(EPICS_BASE_BIN)/devSiTestAsyn.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSoSoft.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSoSymb.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devSoTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devSysmon.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devTimerMz8310.o
|
||||
LIBOBJS += $(EPICS_BASE_BIN)/devVxiTDM.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfCamac.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfComet.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devWfDvx2502.o
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
#ifndef dbAddrh
|
||||
#define dbAddrh
|
||||
|
||||
#ifdef __cplusplus
|
||||
//
|
||||
// for brain dead C++ compilers
|
||||
//
|
||||
struct dbCommon;
|
||||
struct putNotify;
|
||||
#endif
|
||||
|
||||
typedef struct dbAddr{
|
||||
struct dbCommon *precord;/* address of record */
|
||||
void *pfield; /* address of field */
|
||||
|
||||
@@ -117,6 +117,7 @@ typedef epicsUInt16 dbr_ushort_t;
|
||||
typedef epicsInt16 dbr_int_t;
|
||||
typedef epicsUInt16 dbr_enum_t;
|
||||
typedef epicsInt32 dbr_long_t;
|
||||
typedef epicsUInt32 dbr_ulong_t;
|
||||
typedef epicsFloat32 dbr_float_t;
|
||||
typedef epicsFloat64 dbr_double_t;
|
||||
typedef epicsUInt16 dbr_put_ackt_t;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.19 1997/03/05 13:20:44 jbk
|
||||
* Fixed a bug in TSreport - printing of IP addresses was incorrect
|
||||
*
|
||||
* Revision 1.18 1997/01/20 15:31:00 jbk
|
||||
* Print IP address on report
|
||||
*
|
||||
@@ -1097,12 +1100,15 @@ static long TSgetMasterTime(struct timespec* tsp)
|
||||
static long TSsetClockFromUnix()
|
||||
{
|
||||
struct timespec tp;
|
||||
unsigned long ulongtemp;
|
||||
|
||||
Debug0(3,"in TSsetClockFromUnix()\n");
|
||||
|
||||
if(TSgetUnixTime(&tp)!=0) return -1;
|
||||
|
||||
tp.tv_sec-=TS_1900_TO_VXWORKS_EPOCH;
|
||||
ulongtemp = (unsigned long)tp.tv_sec;
|
||||
ulongtemp -= TS_1900_TO_VXWORKS_EPOCH;
|
||||
tp.tv_sec = (long)ulongtemp;
|
||||
|
||||
if(MAKE_DEBUG>=9)
|
||||
TSprintf("set time: %9.9lu.%9.9lu\n", tp.tv_sec,tp.tv_nsec);
|
||||
@@ -1477,11 +1483,14 @@ static long TSasyncClient()
|
||||
else
|
||||
{
|
||||
int i;
|
||||
unsigned long ulongtemp;
|
||||
/* get the current time */
|
||||
cts=TSdata.event_table[TSdata.sync_event];
|
||||
/* adjust the ntp time */
|
||||
ts.tv_sec = ntohl(buf_ntp.transmit_ts.tv_sec) -
|
||||
TS_1900_TO_EPICS_EPOCH;
|
||||
ts.tv_sec = ntohl(buf_ntp.transmit_ts.tv_sec);
|
||||
ulongtemp = (unsigned long)ts.tv_sec;
|
||||
ulongtemp -= TS_1900_TO_EPICS_EPOCH;
|
||||
ts.tv_sec = (long)ulongtemp;
|
||||
nsecs=ntohl(buf_ntp.transmit_ts.tv_nsec);
|
||||
for(i=0,ts.tv_nsec=0;i<32;i++)
|
||||
if(bit_pat[i]&nsecs) ts.tv_nsec+=ns_val[i];
|
||||
|
||||
@@ -128,7 +128,7 @@ int BSmakeServer(char** argv)
|
||||
perror("Cannot fork");
|
||||
return -1;
|
||||
case 0: /* child */
|
||||
#if defined linux || defined SOLARIS || defined SGI || defined _OSF_SOURCE || defined HP_UX
|
||||
#if defined linux || defined SOLARIS || defined SGI || defined HP_UX
|
||||
setpgrp();
|
||||
#else
|
||||
setpgrp(0,0);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user