Compare commits

...

46 Commits

Author SHA1 Message Date
Janet B. Anderson
297f0b8c31 Added *COPYRIGHT* files to release tar file. 1995-10-03 15:42:26 +00:00
Jeff Hill
cc20412693 added locking for previous change 1995-09-29 22:53:38 +00:00
Jeff Hill
7021cd3589 use unsigned short for port 1995-09-29 22:18:53 +00:00
Jeff Hill
b7acf453c2 added arch independent type 1995-09-29 22:17:57 +00:00
Jeff Hill
c9abc2c82e ms windows changes 1995-09-29 22:17:13 +00:00
Jeff Hill
a7484494c4 changes from LBL 1995-09-29 22:15:26 +00:00
Jeff Hill
52cfbe92bf check for nill dbr pointer 1995-09-29 22:13:59 +00:00
Jeff Hill
75f0fb2b0c allow server to refuse to create a channel without a client disconnect 1995-09-29 22:13:05 +00:00
Jeff Hill
ed36723d6c ms windows changes 1995-09-29 21:58:16 +00:00
Jeff Hill
f7a5da9139 added minor version 6 which allows the server to refuse to create a channel
without disconnecting the client
1995-09-29 21:57:11 +00:00
Jeff Hill
254c5b1620 added func proto for cacDisconnectChannel() 1995-09-29 21:55:38 +00:00
Jeff Hill
c6aab85d79 MS windows changes and added cacDisconnectChannel() 1995-09-29 21:54:40 +00:00
Jeff Hill
d54724fce1 MS windows changes 1995-09-29 21:48:33 +00:00
Jeff Hill
60c0acab3c MS windows changes 1995-09-29 21:47:58 +00:00
Jeff Hill
69f33b9e23 alignment fix for SPARC IOC client and changes to prevent running of
access rights or connection handlers when the connection is lost just
after deleting a channel
1995-09-29 21:47:33 +00:00
Janet B. Anderson
9191863094 Added test for Linux. 1995-09-27 22:09:43 +00:00
Marty Kraimer
1beb157ab0 new database access has units as 16 char null terminated. old has 8 char null 1995-09-27 19:54:50 +00:00
Marty Kraimer
41ae285075 copy units string using DB_UNITS_SIZE 1995-09-27 19:52:45 +00:00
John Winans
222063ac53 Added code to send last byte of a RAC_RESET in pepTxTask(). It was left
out in a previous mod that modes the last byte transmission into a locked
region in order to prevent a TxTask/RxTask race condition.
1995-09-26 14:50:31 +00:00
Janet B. Anderson
3342ca120f Specified return type of functions. 1995-09-21 19:48:26 +00:00
cvs2svn
13b785e594 This commit was manufactured by cvs2svn to create tag 'R3.12.1.2'. 1995-09-13 18:27:49 +00:00
Jim Kowalkowski
6931273fef New utilities to list PVs on an IOC and loaded applications. 1995-09-13 18:27:48 +00:00
Jim Kowalkowski
8d52177933 Fixed the address of ioc by name in BSlib.c.
Added app list to the services of PVSvx.
Removed rdbls from PVSserver - made it a separate file.
1995-09-13 18:26:42 +00:00
Jim Kowalkowski
b64fa8bd87 Fixed bug in TSinit - Gives defaults to TSdirectTime() and TSdriverInit() if
event time disabled with TSconfigure().
1995-09-12 15:01:09 +00:00
Janet B. Anderson
34ce2ab6ac Added include for sockio and a cast for tsin in memset. 1995-09-08 14:56:30 +00:00
Jim Kowalkowski
43ef20b90c Completed first version of vx info server and workstation utility.
Removed the stupid program PVSget.
1995-09-07 21:25:59 +00:00
Jim Kowalkowski
818bc0d475 New library and PV dump programs for IOC and client workstation 1995-09-06 21:06:07 +00:00
Jim Kowalkowski
ca2f9aff52 Corrected a problem with building dbLoadTemplate/subtool.
Added the BS and PVS test functions
1995-09-06 21:05:09 +00:00
Jim Kowalkowski
64a93df872 Changed the error message 1995-09-06 21:04:22 +00:00
Jim Kowalkowski
ecc03e9ad9 Cleanup and addition of application() to db file 1995-09-06 21:03:07 +00:00
John Winans
db1b46e5f9 Added ability to change default clock speed from shell. 1995-09-01 14:36:35 +00:00
Marty Kraimer
d87295397e Still new 1995-09-01 14:35:27 +00:00
Marty Kraimer
7277c336f7 Fixed bug causing memory problem 1995-09-01 14:31:32 +00:00
Marty Kraimer
30ad5b1149 Added so that individual files dont have to have long notice 1995-09-01 12:47:28 +00:00
Marty Kraimer
c6bcd1a10b Still new 1995-08-30 21:31:43 +00:00
Marty Kraimer
f3cf369071 made separate from recDynLink 1995-08-30 21:18:29 +00:00
Marty Kraimer
adffe02a2d Still new 1995-08-30 21:17:46 +00:00
Marty Kraimer
e635080cef Fixed problems with freeing pvd 1995-08-30 17:43:19 +00:00
Jim Kowalkowski
be85da6a3a *** empty log message *** 1995-08-30 15:38:39 +00:00
Marty Kraimer
c16006f34d recDynLink is new 1995-08-29 17:55:20 +00:00
Janet B. Anderson
72491d8829 Added startup directory to release tar file 1995-08-28 15:49:54 +00:00
Marty Kraimer
cb78c5adb8 Changes so that function prototype for db_post_event defined 1995-08-28 14:50:32 +00:00
Jeff Hill
1a2cd5953d added log entries 1995-08-23 00:35:17 +00:00
Jeff Hill
5da79a5f56 fixed vxWorks specific SPARC data alignment problem 1995-08-23 00:34:06 +00:00
Jeff Hill
9f2d9587f0 additional parenthesis in macro to be safe 1995-08-23 00:31:13 +00:00
cvs2svn
74e405969a This commit was manufactured by cvs2svn to create tag 'R3.12.1.1'. 1995-08-22 12:23:38 +00:00
70 changed files with 3484 additions and 284 deletions

View File

@@ -0,0 +1,45 @@
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
AND IN ALL SOURCE LISTINGS OF THE CODE.
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
Argonne National Laboratory (ANL), with facilities in the States of
Illinois and Idaho, is owned by the United States Government, and
operated by the University of Chicago under provision of a contract
with the Department of Energy.
Portions of this material resulted from work developed under a U.S.
Government contract and are subject to the following license: For
a period of five years from March 30, 1993, the Government is
granted for itself and others acting on its behalf a paid-up,
nonexclusive, irrevocable worldwide license in this computer
software to reproduce, prepare derivative works, and perform
publicly and display publicly. With the approval of DOE, this
period may be renewed for two additional five year periods.
Following the expiration of this period or periods, the Government
is granted for itself and others acting on its behalf, a paid-up,
nonexclusive, irrevocable worldwide license in this computer
software to reproduce, prepare derivative works, distribute copies
to the public, perform publicly and display publicly, and to permit
others to do so.
*****************************************************************
DISCLAIMER
*****************************************************************
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
OWNED RIGHTS.
*****************************************************************
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).

View File

@@ -10,6 +10,13 @@
# [-b] - For fully built release
#
# $Log$
# Revision 1.2 1995/08/28 15:49:54 jba
# Added startup directory to release tar file
#
# Revision 1.1 1995/08/17 20:14:56 jba
# Added base/tools scripts functionality to base/Makefile, removed scripts
# Moved base/tools/MakeRelease to base dir.
#
# Revision 1.14 1994/12/19 18:42:08 tang
# Make the args length compatible for HP and SUN.
#
@@ -100,6 +107,14 @@ ls base/README* | xargs tar cvf ${RELS}.Tar
ls base/Makefile* > /tmp/make_release.out.$$;
ls base/*COPYRIGHT* >> /tmp/make_release.out.$$;
if [ -d startup ];
then
find startup -name CVS -prune -o ! -type d -print \
>> /tmp/make_release.out.$$;
fi
find config base/include base/man base/tools -name CVS -prune -o \
! -type d -print >> /tmp/make_release.out.$$;

View File

@@ -0,0 +1,10 @@
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
**********************************************************************/

View File

@@ -1,3 +1,4 @@
/* $Id$ */
/************************************************************************/
/* */
/* L O S A L A M O S */
@@ -98,6 +99,16 @@
/************************************************************************/
/*
* $Log$
* Revision 1.77 1995/09/01 14:31:32 mrk
* Fixed bug causing memory problem
*
* Revision 1.76 1995/08/23 00:34:06 jhill
* fixed vxWorks specific SPARC data alignment problem
*
* Revision 1.75 1995/08/22 00:15:19 jhill
* Use 1.0/USEC_PER_SEC and not 1.0e-6
* Check for S_db_Pending when calling dbPutNotify()
*
* Revision 1.74 1995/08/22 00:12:07 jhill
* *** empty log message ***
*
@@ -968,13 +979,14 @@ int epicsShareAPI ca_search_and_connect
* also allocate enough for the channel name & paddr
* block
*/
size = sizeof(*chix) + strcnt + sizeof(struct db_addr);
size = CA_MESSAGE_ALIGN(sizeof(*chix) + strcnt) +
sizeof(struct db_addr);
*chixptr = chix = (chid) calloc(1,size);
if (!chix){
return ECA_ALLOCMEM;
}
chix->id.paddr = (struct db_addr *)
(strcnt + (char *) (chix + 1));
(CA_MESSAGE_ALIGN(sizeof(*chix)+strcnt) + (char *)chix);
*chix->id.paddr = tmp_paddr;
chix->puser = puser;
chix->pConnFunc = conn_func;
@@ -1963,7 +1975,7 @@ void (*pfunc)(struct access_rights_handler_args))
/*
* make certain that it runs at least once
*/
if(chan->state == cs_conn){
if(chan->state == cs_conn && chan->pAccessRightsFunc){
args.chid = chan;
args.ar = chan->ar;
(*chan->pAccessRightsFunc)(args);
@@ -2522,6 +2534,8 @@ int epicsShareAPI ca_clear_channel (chid chix)
chix->type = TYPENOTINUSE;
old_chan_state = chix->state;
chix->state = cs_closed;
chix->pAccessRightsFunc = NULL;
chix->pConnFunc = NULL;
/* the while is only so I can break to the lock exit */
LOCK;

View File

@@ -7,6 +7,9 @@ static char *sccsId = "@(#) $Id$";
/*
* $Log$
* Revision 1.29 1995/08/22 00:16:34 jhill
* Added test of the duration of ca_pend_event()
*
*/
#ifdef VMS
@@ -103,13 +106,13 @@ int doacctst(char *pname)
chid chix4;
struct dbr_gr_float *ptr = NULL;
struct dbr_gr_float *pgrfloat = NULL;
float *pfloat = NULL;
double *pdouble = NULL;
dbr_float_t *pfloat = NULL;
dbr_double_t *pdouble = NULL;
long status;
long i, j;
evid monix;
char pstring[NUM][MAX_STRING_SIZE];
unsigned size;
SEVCHK(ca_task_initialize(), "Unable to initialize");
@@ -123,9 +126,9 @@ int doacctst(char *pname)
{
TS_STAMP end_time;
TS_STAMP start_time;
double delay;
double request = 0.5;
double accuracy;
dbr_double_t delay;
dbr_double_t request = 0.5;
dbr_double_t accuracy;
tsLocalTime(&start_time);
status = ca_pend_event(request);
@@ -140,8 +143,8 @@ int doacctst(char *pname)
assert (abs(accuracy) < 10.0);
}
ptr = (struct dbr_gr_float *)
malloc(dbr_size_n(DBR_GR_FLOAT, NUM));
size = dbr_size_n(DBR_GR_FLOAT, NUM);
ptr = (struct dbr_gr_float *) malloc(size);
for (i = 0; i < 10; i++) {
@@ -264,9 +267,9 @@ int doacctst(char *pname)
ca_read_access(chix1) &&
ca_write_access(chix1)){
double incr;
double epsil;
double base;
dbr_double_t incr;
dbr_double_t epsil;
dbr_double_t base;
unsigned long iter;
printf ("float test ...");
@@ -328,7 +331,7 @@ int doacctst(char *pname)
* solicitations
*/
if(ca_read_access(chix4)){
float temp;
dbr_float_t temp;
printf("Performing multiple get test...");
fflush(stdout);
@@ -349,7 +352,7 @@ int doacctst(char *pname)
printf("Performing multiple put test...");
fflush(stdout);
for(i=0; i<10000; i++){
double fval = 3.3;
dbr_double_t fval = 3.3;
status = ca_put(DBR_DOUBLE, chix4, &fval);
SEVCHK(status, NULL);
}
@@ -396,7 +399,7 @@ int doacctst(char *pname)
printf("Performing multiple put callback test...");
fflush(stdout);
for(i=0; i<10000; i++){
float fval = 3.3;
dbr_float_t fval = 3.3F;
status = ca_array_put_callback(
DBR_FLOAT,
1,
@@ -420,8 +423,8 @@ int doacctst(char *pname)
printf("Performing multiple monitor test...");
fflush(stdout);
{
evid mid[1000];
float temp;
evid mid[1000];
dbr_float_t temp;
for(i=0; i<NELEMENTS(mid); i++){
SEVCHK(ca_add_event(DBR_GR_FLOAT, chix4, null_event,
@@ -499,8 +502,8 @@ int doacctst(char *pname)
SEVCHK(status, NULL);
}
pfloat = (float *) calloc(sizeof(float),NUM);
pdouble = (double *) calloc(sizeof(double),NUM);
pfloat = (dbr_float_t *) calloc(sizeof(*pfloat),NUM);
pdouble = (dbr_double_t *) calloc(sizeof(*pdouble),NUM);
pgrfloat = (struct dbr_gr_float *) calloc(sizeof(*pgrfloat),NUM);
if (VALID_DB_REQ(chix1->type))
@@ -654,9 +657,15 @@ void null_event(struct event_handler_args args)
void write_event(struct event_handler_args args)
{
int status;
float a = *(float *) args.dbr;
dbr_float_t *pFloat = (dbr_float_t *) args.dbr;
dbr_float_t a;
a += 10.1;
if (!args.dbr) {
return;
}
a = *pFloat;
a += 10.1F;
status = ca_array_put(
DBR_FLOAT,
@@ -745,10 +754,10 @@ void test_sync_groups(chid chix)
*/
void multiple_sg_requests(chid chix, CA_SYNC_GID gid)
{
int status;
unsigned i;
static float fvalput = 3.3;
static float fvalget;
int status;
unsigned i;
static dbr_float_t fvalput = 3.3F;
static dbr_float_t fvalget;
for(i=0; i<1000; i++){
if(ca_write_access(chix)){

View File

@@ -19,7 +19,7 @@ void caAddConfiguredAddr(
int port);
int local_addr(SOCKET socket, struct sockaddr_in *plcladdr);
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort);
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort);
union caAddr{
struct sockaddr_in inetAddr;

View File

@@ -757,7 +757,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu)
CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status);
if (status != sendCnt) {
if (((unsigned long)status) != sendCnt) {
UNLOCK;
return;
}
@@ -928,7 +928,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
break;
}
assert (status<=writeSpace);
assert (((unsigned long)status)<=writeSpace);
CAC_RING_BUFFER_WRITE_ADVANCE(&piiu->recv, status);
@@ -938,7 +938,7 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu)
*/
piiu->timeAtLastRecv = ca_static->currentTime;
if (status != writeSpace) {
if (((unsigned long)status) != writeSpace) {
break;
}
}
@@ -1196,6 +1196,8 @@ void close_ioc (struct ioc_in_use *piiu)
piiuCast = NULL;
}
else {
chid *pNext;
/*
* remove IOC from the hash table
*/
@@ -1209,73 +1211,20 @@ void close_ioc (struct ioc_in_use *piiu)
* handler tries to use a channel before
* I mark it disconnected.
*/
chix = (chid) &piiu->chidlist.node.next;
while (chix = (chid) chix->node.next) {
chix->type = TYPENOTCONN;
chix->count = 0U;
chix = (chid) ellFirst(&piiu->chidlist);
while (chix) {
chix->state = cs_prev_conn;
chix->id.sid = ~0U;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
/*
* try to reconnect
*/
chix->retry = 0U;
chix = (chid) ellNext(&chix->node);
}
if (piiu->chidlist.count) {
ca_signal (ECA_DISCONN,piiu->host_name_str);
chix = (chid) ellFirst(&piiu->chidlist);
while (chix) {
pNext = (chid) ellNext(&chix->node);
cacDisconnectChannel(chix, TRUE);
chix = pNext;
}
/*
* clear outstanding get call backs
*/
caIOBlockListFree (&pend_read_list, chix, TRUE, ECA_DISCONN);
/*
* clear outstanding put call backs
*/
caIOBlockListFree (&pend_write_list, chix, TRUE, ECA_DISCONN);
/*
* call their connection handler as required
*/
chix = (chid) &piiu->chidlist.node.next;
while (chix = (chid) chix->node.next) {
LOCKEVENTS;
if (chix->pConnFunc) {
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->pConnFunc) (args);
}
if (chix->pAccessRightsFunc) {
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->pAccessRightsFunc) (args);
}
UNLOCKEVENTS;
chix->piiu = piiuCast;
}
/*
* move all channels to the broadcast IIU
*
* if we loose the broadcast IIU its a severe error
*/
assert (piiuCast);
ellConcat (&piiuCast->chidlist, &piiu->chidlist);
assert (piiu->chidlist.count==0);
}
/*
* Try to reconnect
*/
ca_static->ca_search_retry = 0;
if (fd_register_func) {
LOCKEVENTS;
(*fd_register_func) (fd_register_arg, piiu->sock_chan, FALSE);
@@ -1298,11 +1247,78 @@ void close_ioc (struct ioc_in_use *piiu)
ellFree (&piiu->destAddr);
ca_signal (ECA_DISCONN,piiu->host_name_str);
free (piiu);
UNLOCK;
}
/*
* cacDisconnectChannel()
*/
void cacDisconnectChannel(chid chix, int fullDisconnect)
{
struct ioc_in_use *piiu;
chix->type = TYPENOTCONN;
chix->count = 0U;
chix->id.sid = ~0U;
chix->ar.read_access = FALSE;
chix->ar.write_access = FALSE;
/*
* try to reconnect
*/
chix->retry = 0U;
/*
* call their connection handler as required
*/
if (fullDisconnect) {
chix->state = cs_prev_conn;
/*
* clear outstanding get call backs
*/
caIOBlockListFree (&pend_read_list, chix,
TRUE, ECA_DISCONN);
/*
* clear outstanding put call backs
*/
caIOBlockListFree (&pend_write_list, chix,
TRUE, ECA_DISCONN);
LOCKEVENTS;
if (chix->pConnFunc) {
struct connection_handler_args args;
args.chid = chix;
args.op = CA_OP_CONN_DOWN;
(*chix->pConnFunc) (args);
}
if (chix->pAccessRightsFunc) {
struct access_rights_handler_args args;
args.chid = chix;
args.ar = chix->ar;
(*chix->pAccessRightsFunc) (args);
}
UNLOCKEVENTS;
}
piiu = (struct ioc_in_use *)chix->piiu;
ellDelete(&piiu->chidlist, &chix->node);
assert (piiuCast);
chix->piiu = piiuCast;
ellAdd(&piiuCast->chidlist, &chix->node);
/*
* Try to reconnect this channel
*/
ca_static->ca_search_retry = 0;
}
/*
@@ -1705,7 +1721,7 @@ void caPrintAddrList(ELLLIST *pList)
/*
* caFetchPortConfig()
*/
int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort)
{
long longStatus;
long epicsParam;
@@ -1713,29 +1729,29 @@ int caFetchPortConfig(ENV_PARAM *pEnv, int defaultPort)
longStatus = envGetLongConfigParam(pEnv, &epicsParam);
if (longStatus!=0) {
epicsParam = defaultPort;
epicsParam = (long) defaultPort;
ca_printf ("EPICS \"%s\" integer fetch failed\n", pEnv->name);
ca_printf ("setting \"%s\" = %ld\n", pEnv->name, epicsParam);
}
/*
* This must be a server port that will fit in a signed
* This must be a server port that will fit in an unsigned
* short
*/
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>SHRT_MAX) {
if (epicsParam<=IPPORT_USERRESERVED || epicsParam>USHRT_MAX) {
ca_printf ("EPICS \"%s\" out of range\n", pEnv->name);
/*
* Quit if the port is wrong due CA coding error
*/
assert (epicsParam != defaultPort);
epicsParam = defaultPort;
assert (epicsParam != (long) defaultPort);
epicsParam = (long) defaultPort;
ca_printf ("Setting \"%s\" = %ld\n", pEnv->name, epicsParam);
}
/*
* ok to clip to int here because we checked the range
*/
port = (int) epicsParam;
port = (unsigned short) epicsParam;
return port;
}

View File

@@ -29,7 +29,10 @@
/* .17 121892 joh added TCP send buf size var */
/* .18 122192 joh added outstanding ack var */
/* .19 012094 joh added minor version (for each server) */
/* $Log$ */
/* $Log$
* Revision 1.47 1995/08/22 00:20:27 jhill
* added KLUDGE def of S_db_Pending
* */
/* */
/*_begin */
/************************************************************************/
@@ -412,9 +415,11 @@ struct ca_static{
void (*ca_exception_func)
(struct exception_handler_args);
void *ca_exception_arg;
#if 0
void (*ca_connection_func)
(struct connection_handler_args);
void *ca_connection_arg;
#endif
int (*ca_printf_func)(const char *pformat, va_list args);
void (*ca_fd_register_func)
(void *, SOCKET, int);
@@ -608,7 +613,7 @@ ca_time cac_time_sum(ca_time *pTVA, ca_time *pTVB);
void caIOBlockFree(evid pIOBlock);
void clearChannelResources(unsigned id);
void caSetDefaultPrintfHandler ();
void cacDisconnectChannel(chid chix, int fullDisconnect);
/*
* !!KLUDGE!!
*

View File

@@ -1,4 +1,5 @@
#ifndef __IOCMSG__
/* $Id$ */
/*
* History
* .01 01xx90 joh removed status field in favor of a independent m_cmmd-
@@ -23,6 +24,10 @@
* .09 050594 joh New command added for CA V4.3 - repeater fanout register
*
* .10 050594 joh New command added for CA V4.3 - wakeup the server
* $Log$
* Revision 1.23 1995/08/23 00:35:17 jhill
* added log entries
*
*/
#define __IOCMSG__
@@ -31,7 +36,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
/* TCP/UDP port number (bumped each protocol change) */
#define CA_PROTOCOL_VERSION 4
#define CA_MINOR_VERSION 5
#define CA_MINOR_VERSION 6
#define CA_UKN_MINOR_VERSION 0 /* unknown minor version */
#if CA_PROTOCOL_VERSION == 4
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1)
@@ -39,18 +44,21 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
#define CA_V43(MAJOR,MINOR) ((MINOR)>=3)
#define CA_V44(MAJOR,MINOR) ((MINOR)>=4)
#define CA_V45(MAJOR,MINOR) ((MINOR)>=5)
#define CA_V46(MAJOR,MINOR) ((MINOR)>=6)
#elif CA_PROTOCOL_VERSION > 4
#define CA_V41(MAJOR,MINOR) ( 1 )
#define CA_V42(MAJOR,MINOR) ( 1 )
#define CA_V43(MAJOR,MINOR) ( 1 )
#define CA_V44(MAJOR,MINOR) ( 1 )
#define CA_V45(MAJOR,MINOR) ( 1 )
#define CA_V46(MAJOR,MINOR) ( 1 )
#else
#define CA_V41(MAJOR,MINOR) ( 0 )
#define CA_V42(MAJOR,MINOR) ( 0 )
#define CA_V43(MAJOR,MINOR) ( 0 )
#define CA_V44(MAJOR,MINOR) ( 0 )
#define CA_V45(MAJOR,MINOR) ( 0 )
#define CA_V46(MAJOR,MINOR) ( 0 )
#endif
/*
@@ -59,7 +67,7 @@ HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4")
* environment variables "EPICS_CA_REPEATER_PORT" and
* "EPICS_CA_SERVER_PORT"
*/
#define CA_PORT_BASE IPPORT_USERRESERVED + 56
#define CA_PORT_BASE IPPORT_USERRESERVED + 56U
#define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2)
#define CA_REPEATER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1)
@@ -104,6 +112,7 @@ typedef ca_uint32_t caResId;
#define IOC_ECHO 23 /* CA V4.3 connection verify */
#define REPEATER_REGISTER 24 /* registr for repeater fan out */
#define IOC_SIGNAL 25 /* knock the server out of select */
#define IOC_CLAIM_CIU_FAILED 26 /* unable to create chan resource in server */
/*
* for use with search and not_found (if search fails and
@@ -113,15 +122,15 @@ typedef ca_uint32_t caResId;
#define DONTREPLY 5
/* size of object in bytes rounded up to nearest oct word */
#define OCT_ROUND(A) ((((unsigned long)A)+7)>>3)
#define OCT_ROUND(A) ((((unsigned long)(A))+7)>>3)
#define OCT_SIZEOF(A) (OCT_ROUND(sizeof(A)))
/* size of object in bytes rounded up to nearest long word */
#define QUAD_ROUND(A) (((unsigned long)A)+3)>>2)
#define QUAD_ROUND(A) (((unsigned long)(A))+3)>>2)
#define QUAD_SIZEOF(A) (QUAD_ROUND(sizeof(A)))
/* size of object in bytes rounded up to nearest short word */
#define BI_ROUND(A) ((((unsigned long)A)+1)>>1)
#define BI_ROUND(A) ((((unsigned long)(A))+1)>>1)
#define BI_SIZEOF(A) (BI_ROUND(sizeof(A)))
/*

View File

@@ -307,12 +307,13 @@ static char *os_depenhSccsId = "$Id$";
# define UNLOCKEVENTS
# define EVENTLOCKTEST (post_msg_active)
# define MAXHOSTNAMELEN 75
# define IPPORT_USERRESERVED 5000
# define IPPORT_USERRESERVED 5000U
# define EWOULDBLOCK WSAEWOULDBLOCK
# define ENOBUFS WSAENOBUFS
# define ECONNRESET WSAECONNRESET
# define ETIMEDOUT WSAETIMEDOUT
# define EADDRINUSE WSAEADDRINUSE
# define ECONNREFUSED WSAECONNREFUSED
# define socket_close(S) closesocket(S)
# define socket_ioctl(A,B,C) ioctlsocket(A,B,C)
# define MYERRNO WSAGetLastError()

View File

@@ -85,8 +85,8 @@ static char buf[MAX_UDP];
LOCAL void register_new_client(struct sockaddr_in *pLocal,
struct sockaddr_in *pFrom);
#define PORT_ANY 0
LOCAL int makeSocket(int port);
#define PORT_ANY 0U
LOCAL SOCKET makeSocket(unsigned short port);
LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize);
@@ -104,7 +104,7 @@ void ca_repeater()
struct sockaddr_in from;
struct sockaddr_in local;
int from_size = sizeof from;
short port;
unsigned short port;
port = caFetchPortConfig(
&EPICS_CA_REPEATER_PORT,
@@ -241,11 +241,11 @@ LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize)
/*
* makeSocket()
*/
LOCAL int makeSocket(int port)
LOCAL SOCKET makeSocket(unsigned short port)
{
int status;
struct sockaddr_in bd;
int sock;
SOCKET sock;
int true = 1;
sock = socket( AF_INET, /* domain */

View File

@@ -263,8 +263,6 @@ const struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client write io id from server");
break;
}
@@ -313,8 +311,6 @@ const struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client read notify io id from server");
break;
}
@@ -384,8 +380,6 @@ const struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!monix){
ca_signal(ECA_INTERNAL,
"bad client event id from server");
break;
}
@@ -465,8 +459,6 @@ const struct in_addr *pnet_addr
&piiu->curMsg.m_available);
UNLOCK;
if(!pIOBlock){
ca_signal(ECA_INTERNAL,
"bad client read io id from server");
break;
}
@@ -640,9 +632,6 @@ const struct in_addr *pnet_addr
if (pList) {
ellDelete(pList, &monix->node);
}
else {
printf ("CAC - Protocol err - no list for IO blk\n");
}
caIOBlockFree(monix);
}
@@ -712,6 +701,31 @@ const struct in_addr *pnet_addr
reconnect_channel(piiu, chan);
break;
}
case IOC_CLAIM_CIU_FAILED:
{
chid chan;
LOCK;
chan = bucketLookupItemUnsignedId(
pSlowBucket, &piiu->curMsg.m_cid);
UNLOCK;
if(!chan){
/*
* end up here if they delete the channel
* prior to this response
*/
break;
}
/*
* need to move the channel back to the cast IIU
* (so we will be able to reconnect)
*/
LOCK;
cacDisconnectChannel(chan, FALSE);
UNLOCK;
break;
}
default:
ca_printf("CAC: post_msg(): Corrupt cmd in msg %x\n",
piiu->curMsg.m_cmmd);
@@ -828,7 +842,7 @@ const struct in_addr *pnet_addr
case ECA_DISCONN:
/*
* This indicates that the connection is tagged
* is tagged for shutdown and we are waiting for
* for shutdown and we are waiting for
* it to go away. Search replies are ignored
* in the interim.
*/
@@ -979,9 +993,6 @@ chid chan
/* decrement the outstanding IO count */
CLRPENDRECV(TRUE);
}
UNLOCK;
}

View File

@@ -29,6 +29,9 @@
* Modification Log:
* -----------------
* $Log$
* Revision 1.16 1995/08/22 00:27:55 jhill
* added cvs style mod log
*
*
* NOTES:
* 1) Need to fix if the OP is on a FD that
@@ -520,7 +523,7 @@ LOCAL void io_complete(struct event_handler_args args)
* Update the user's variable
* (if its a get)
*/
if(pcasgop->pValue){
if(pcasgop->pValue && args.dbr){
size = dbr_size_n(args.type, args.count);
memcpy(pcasgop->pValue, args.dbr, size);
}

View File

@@ -13,7 +13,6 @@
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
@@ -27,9 +26,10 @@
* Advanced Photon Source
* Argonne National Laboratory
*
* Lawrence Berkley National Laboratory
*
* Modification Log:
* -----------------
* $Log$
*
*/
@@ -58,8 +58,7 @@ void cac_gettimeval(struct timeval *pt)
SYSTEMTIME st;
GetSystemTime(&st);
pt->tv_sec = (long)st.wSecond + (long)st.wMinute*60 +
(long)st.wHour*360;
pt->tv_sec = time(NULL);
pt->tv_usec = st.wMilliseconds*1000;
}
@@ -80,11 +79,6 @@ void cac_mux_io(struct timeval *ptimeout)
cac_clean_iiu_list();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout = *ptimeout;
do{
count = cac_select_io(
@@ -93,6 +87,11 @@ void cac_mux_io(struct timeval *ptimeout)
ca_process_input_queue();
/*
* manage search timers and detect disconnects
*/
manage_conn(TRUE);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
@@ -291,11 +290,8 @@ int local_addr (SOCKET s, struct sockaddr_in *plcladdr)
*/
void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port)
{
struct sockaddr_in localAddr;
struct sockaddr_in InetAddr;
struct in_addr bcast_addr;
caAddrNode *pNode;
int status;
pNode = (caAddrNode *) calloc(1,sizeof(*pNode));
if(!pNode){
@@ -353,6 +349,13 @@ static int get_subnet_mask ( char SubNetMaskStr[256])
return RegTcpParams (localadr, SubNetMaskStr);
}
/* For NT 3.51, enumerates network interfaces returns the ip address */
/* and subnet mask for the LAST interface found. This needs to be changed */
/* to work in conjuction with caDiscoverInterfaces to add all the */
/* add all the interfaces to the elist. Also could be more efficient in
calling */
/* RegKeyOpen */
static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
{
#define MAX_VALUE_NAME 128
@@ -361,37 +364,65 @@ static int RegTcpParams (char IpAddrStr[256], char SubNetMaskStr[256])
DWORD cbDataLen;
CHAR cbData[256];
DWORD dwType;
int status;
int status, i, card_cnt;
char *pNetCard[16], *pData;
static char IpAddr[256], SubNetMask[256];
cbDataLen = sizeof(cbData);
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\1");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
/****
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\NetworkCards\\1");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType,
cbData, &cbDataLen);
if (status) {
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\01");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType, cbData, &cbDataLen);
strcpy(RegPath,"SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\NetworkCards\\01");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "ServiceName", &dwType,
cbData, &cbDataLen);
if (status)
return status;
}
****/
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
strcat(RegPath,cbData);
strcat(RegPath,"\\Parameters\\Tcpip");
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage");
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "Route", &dwType, cbData,
&cbDataLen);
if (status) {
return status;
}
i=0; card_cnt = 0; pData = cbData; /* enumerate network interfaces */
while( i < 16 && (pNetCard[i]=strtok(pData,"\"")) ) {
strcpy(RegPath,"SYSTEM\\CurrentControlSet\\Services\\");
strcat(RegPath,pNetCard[i]);
strcat(RegPath,"\\Parameters\\Tcpip");
cbDataLen = sizeof(IpAddr);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType,
IpAddr, &cbDataLen);
if (status == 0) {
cbDataLen = sizeof(SubNetMask);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask",
&dwType, SubNetMask, &cbDataLen);
if (status)
return status;
card_cnt++;
}
pData += strlen(pNetCard[i])+3;
i++;
}
if (card_cnt == 0)
return 1;
cbDataLen = sizeof(IpAddr);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "IPAddress", &dwType, IpAddr, &cbDataLen);
if (status)
return status;
strcpy(IpAddrStr,IpAddr);
cbDataLen = sizeof(SubNetMask);
status = RegKeyData (RegPath, HKEY_LOCAL_MACHINE, "SubnetMask", &dwType, SubNetMask, &cbDataLen);
if (status)
return status;
strcpy(SubNetMaskStr,SubNetMask);
return 0;
return 0;
}
@@ -418,7 +449,8 @@ static int RegKeyData (CHAR *RegPath, HANDLE hKeyRoot, LPSTR lpzValueName,
}
retCode = RegQueryValueEx (hKey, // Key handle returned from RegOpenKeyEx.
retCode = RegQueryValueEx (hKey, // Key handle returned from
RegOpenKeyEx.
lpzValueName, // Name of value.
NULL, // Reserved, dword = NULL.
lpdwType, // Type of data.
@@ -462,11 +494,15 @@ BOOL epicsShareAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
break;
case DLL_THREAD_ATTACH:
#if _DEBUG
fprintf(stderr, "Thread attached to ca.dll R12\n");
#endif
break;
case DLL_THREAD_DETACH:
#if _DEBUG
fprintf(stderr, "Thread detached from ca.dll R12\n");
#endif
break;
default:
@@ -476,3 +512,5 @@ BOOL epicsShareAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
return TRUE;
}

View File

@@ -90,6 +90,7 @@
#include <dbFldTypes.h>
#include <dbRecDes.h>
#include <dbRecType.h>
#include <dbEvent.h>
#include <db_field_log.h>
#include <errMdef.h>
#include <recSup.h>

View File

@@ -622,14 +622,16 @@ int db_post_single_event(struct event_block *pevent)
*
*/
int db_post_events(
struct dbCommon *precord,
union native_value *pvalue,
unsigned int select
void *prec,
void *pval,
unsigned int select
)
{
struct event_block *event;
struct event_que *ev_que;
unsigned int putix;
struct dbCommon *precord = (struct dbCommon *)prec;
union native_value *pvalue = (union native_value *)pval;
struct event_block *event;
struct event_que *ev_que;
unsigned int putix;
if (precord->mlis.count == 0) return OK; /* no monitors set */

View File

@@ -83,6 +83,7 @@
#include <dbFldTypes.h>
#include <dbRecDes.h>
#include <dbRecType.h>
#include <dbEvent.h>
#include <db_field_log.h>
#include <errMdef.h>
#include <recSup.h>
@@ -2784,7 +2785,6 @@ void *pflin
long (*pconvert_routine)();
struct dbCommon *pcommon;
long status;
long *perr_status=NULL;
prset=GET_PRSET(pdbBase->precSup,paddr->record_type);
@@ -2803,11 +2803,13 @@ void *pflin
}
*((unsigned short *)pbuffer)++ = pcommon->acks;
*((unsigned short *)pbuffer)++ = pcommon->ackt;
*perr_status = 0;
}
if( (*options) & DBR_UNITS ) {
if( prset && prset->get_units ){
(*prset->get_units)(paddr,pbuffer);
char * pchr = (char *)pbuffer;
(*prset->get_units)(paddr,pchr);
pchr[DB_UNITS_SIZE-1] = '\0';
} else {
memset(pbuffer,'\0',dbr_units_size);
*options = (*options) ^ DBR_UNITS; /*Turn off DBR_UNITS*/
@@ -2854,7 +2856,6 @@ GET_DATA:
sprintf(message,"dbGet - database request type is %d",dbrType);
recGblDbaddrError(S_db_badDbrtype,paddr,message);
if(perr_status) *perr_status = S_db_badDbrtype;
return(S_db_badDbrtype);
}
@@ -2869,7 +2870,6 @@ GET_DATA:
sprintf(message,"dbGet - database request type is %d",dbrType);
recGblDbaddrError(S_db_badDbrtype,paddr,message);
if(perr_status) *perr_status = S_db_badDbrtype;
return(S_db_badDbrtype);
}
/* convert database field to buffer type and place it in the buffer */
@@ -2885,7 +2885,6 @@ GET_DATA:
status=(*pconvert_routine)(paddr,pbuffer,*nRequest,
no_elements,offset);
}
if(perr_status) *perr_status = status;
return(status);
}

View File

@@ -51,6 +51,7 @@
#include <ellLib.h>
#include <vxLib.h>
#include <tickLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <dbAccess.h>

View File

@@ -439,7 +439,6 @@ DBBASE *pdbbase;
ELLLIST *preclist;
int recType;
if (!pdbbase || !ppvd || !precType) return;
dbPvdFreeMem(pdbbase);
/* loop thru the recLocs - removing lists then recLoc only */
for (recType = 0; recType < precType->number; recType++) {
if (!(precLoc = GET_PRECLOC(precHeader, recType))) continue;
@@ -461,6 +460,7 @@ DBBASE *pdbbase;
free((void *) precLoc);
}
/* free the rest of the memory allocations */
dbPvdFreeMem(pdbbase);
if (pdbbase->pchoiceCvt)
free((void *) pdbbase->pchoiceCvt);
if (pdbbase->pchoiceDev)
@@ -4316,7 +4316,8 @@ RECNODE *precnode;
ppvdlist=ppvd[hashInd];
ppvdNode = (PVDENTRY *) ellFirst(ppvdlist);
while(ppvdNode) {
if(strcmp(name,(char *)ppvdNode->precnode->precord) == 0) {
if(ppvdNode->precnode && ppvdNode->precnode->precord
&& strcmp(name,(char *)ppvdNode->precnode->precord) == 0) {
ellDelete(ppvdlist, (ELLNODE*)ppvdNode);
free((void *)ppvdNode);
return;

View File

@@ -96,6 +96,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <timexLib.h>
#include <ellLib.h>
#include <fast_lock.h>
@@ -112,6 +113,7 @@
#include <special.h>
#include <dbRecDes.h>
#include <dbStaticLib.h>
#include <dbEvent.h>
#include <ellLib.h>
#include <callback.h>
@@ -170,18 +172,6 @@ long dba(char*pname)
if(status) return(1); else return(0);
}
/*Following definition is from dbEvent.c*/
struct event_block{
ELLNODE node;
struct dbAddr *paddr;
void (*user_sub)();
void *user_arg;
struct event_que *ev_que;
unsigned char select;
char valque;
unsigned short npend; /* n times this event is on the que */
};
long dbel(char*pname)
{
struct dbAddr addr;
@@ -200,7 +190,7 @@ long dbel(char*pname)
return(0);
}
while(peb) {
pfldDes = peb->paddr->pfldDes;
pfldDes = ((struct dbAddr *)peb->paddr)->pfldDes;
printf("%4.4s",&pfldDes->fldname[0]);
if(peb->select&&DBE_VALUE) printf(" VALUE");
if(peb->select&&DBE_LOG) printf(" LOG");
@@ -1756,7 +1746,8 @@ char *record_name;
* Time the record
*/
dbScanLock(precord);
timexN(timing_routine, precord);
timexN((FUNCPTR)timing_routine, (int)precord,
0,0,0,0,0,0,0);
dbScanUnlock(precord);
return(0);

View File

@@ -129,6 +129,9 @@
#define MAX_STRING_SIZE 40
#endif
#ifndef MAX_UNITS_SIZE
#define MAX_UNITS_SIZE 8
#endif
/* VALUES WITH STATUS STRUCTURES */
@@ -269,7 +272,7 @@ struct dbr_time_double{
struct dbr_gr_int{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -281,7 +284,7 @@ struct dbr_gr_int{
struct dbr_gr_short{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -297,7 +300,7 @@ struct dbr_gr_float{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad0; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
float upper_disp_limit; /* upper limit of graph */
float lower_disp_limit; /* lower limit of graph */
float upper_alarm_limit;
@@ -320,7 +323,7 @@ struct dbr_gr_enum{
struct dbr_gr_char{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
unsigned char upper_disp_limit; /* upper limit of graph */
unsigned char lower_disp_limit; /* lower limit of graph */
unsigned char upper_alarm_limit;
@@ -335,7 +338,7 @@ struct dbr_gr_char{
struct dbr_gr_long{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
long upper_disp_limit; /* upper limit of graph */
long lower_disp_limit; /* lower limit of graph */
long upper_alarm_limit;
@@ -351,7 +354,7 @@ struct dbr_gr_double{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad0; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
double upper_disp_limit; /* upper limit of graph */
double lower_disp_limit; /* lower limit of graph */
double upper_alarm_limit;
@@ -370,7 +373,7 @@ struct dbr_gr_double{
struct dbr_ctrl_int{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -384,7 +387,7 @@ struct dbr_ctrl_int{
struct dbr_ctrl_short{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
short upper_disp_limit; /* upper limit of graph */
short lower_disp_limit; /* lower limit of graph */
short upper_alarm_limit;
@@ -402,7 +405,7 @@ struct dbr_ctrl_float{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
float upper_disp_limit; /* upper limit of graph */
float lower_disp_limit; /* lower limit of graph */
float upper_alarm_limit;
@@ -427,7 +430,7 @@ struct dbr_ctrl_enum{
struct dbr_ctrl_char{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
unsigned char upper_disp_limit; /* upper limit of graph */
unsigned char lower_disp_limit; /* lower limit of graph */
unsigned char upper_alarm_limit;
@@ -444,7 +447,7 @@ struct dbr_ctrl_char{
struct dbr_ctrl_long{
short status; /* status of value */
short severity; /* severity of alarm */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
long upper_disp_limit; /* upper limit of graph */
long lower_disp_limit; /* lower limit of graph */
long upper_alarm_limit;
@@ -462,7 +465,7 @@ struct dbr_ctrl_double{
short severity; /* severity of alarm */
short precision; /* number of decimal places */
short RISC_pad0; /* RISC alignment */
char units[8]; /* units of value */
char units[MAX_UNITS_SIZE]; /* units of value */
double upper_disp_limit; /* upper limit of graph */
double lower_disp_limit; /* lower limit of graph */
double upper_alarm_limit;
@@ -1017,7 +1020,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1051,7 +1055,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1083,7 +1088,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1114,7 +1120,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1148,7 +1155,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1182,7 +1190,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1219,7 +1228,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1286,7 +1296,8 @@ void *pfl;
pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1320,7 +1331,8 @@ void *pfl;
status = dbGetField(paddr,DBR_LONG,&new,&options,&nRequest,pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;
@@ -1357,7 +1369,8 @@ void *pfl;
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision;
strncpy(pold->units,new.units,8);
strncpy(pold->units,new.units,MAX_UNITS_SIZE);
pold->units[MAX_UNITS_SIZE-1] = '\0';
pold->upper_disp_limit = new.upper_disp_limit;
pold->lower_disp_limit = new.lower_disp_limit;
pold->upper_alarm_limit = new.upper_alarm_limit;

View File

@@ -1,6 +1,12 @@
/*
* $Log$
* Revision 1.14 1995/08/30 15:38:39 jbk
* *** empty log message ***
*
* Revision 1.13 1995/08/18 13:19:31 mrk
* Made changes for ansi c
*
* Revision 1.12 1995/08/17 20:35:09 jbk
* fixed all the -pendantic errors (pain)
*
@@ -99,7 +105,8 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
*/
#define MAKE_DEBUG TSdriverDebug
#define TS_DRIVER
#define TS_DRIVER 1
#define TS_ALLOW_FORCE 1
#include <vxWorks.h>
#include <vme.h>
@@ -213,6 +220,9 @@ TSinfo TSdata = { TS_master_dead, TS_async_slave, TS_async_none,
extern char* sysBootLine;
int TSdirectTimeVar = 0; /* aother way to indicate direct time */
int TSgoodTimeStamps = 0; /* a way to force use of accurate time stamps */
static WDOG_ID wd;
static long correction_factor = 0;
static long correction_count = 0;
@@ -383,8 +393,13 @@ long TSgetTimeStamp(int event_number,struct timespec* sp)
switch(event_number)
{
case 0:
*sp = TSdata.event_table[0]; /* one tick watch dog maintains */
break;
#ifdef TS_ALLOW_FORCE
if(TSgoodTimeStamps==0)
#endif
{
*sp = TSdata.event_table[0]; /* one tick watch dog maintains */
break;
}
case -1:
{
struct timespec ts;
@@ -494,6 +509,8 @@ long TSinit(void)
TSregisterErrorHandler = TSregisterErrorHandlerError;
TSforceSync = TSforceSoftSync;
TSgetTime = TSgetCurrentTime;
TSdriverInit = TSdriverInitError;
TSdirectTime = TSdirectTimeError;
TSdata.sync_event=ER_EVENT_RESET_TICK;
}
@@ -518,7 +535,7 @@ long TSinit(void)
else
TSdata.has_event_system = 1;
if(TSdirectTime()>0) TSdata.has_direct_time=1;
if(TSdirectTime()>0 || TSdirectTimeVar>0) TSdata.has_direct_time=1;
/* allocate the event table */
TSdata.event_table=(struct timespec*)malloc(

View File

@@ -52,6 +52,7 @@
#include <dbBase.h>
#include <dbRecType.h>
#include <dbRecDes.h>
#include <dbEvent.h>
#include <dbAccess.h>
#include <dbScan.h>
#include <devSup.h>

986
src/dbtools/BSlib.c Normal file
View File

@@ -0,0 +1,986 @@
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include "BSlib.h"
#ifdef linux
#include <sys/time.h>
#include <sys/resource.h>
#endif
#ifdef vxWorks
#include <vxWorks.h>
#include <in.h>
#include <ioctl.h>
#include <inetLib.h>
#include <taskLib.h>
#include <ioLib.h>
#include <sockLib.h>
#include <selectLib.h>
#else
#include <sys/sockio.h>
#include <sys/time.h>
#include <netdb.h>
#include <fcntl.h>
#endif
#ifdef SOLARIS
#define BSD_COMP
#include <sys/ioctl.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/if.h>
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin);
/* ---------------------------------------------------------------------- */
/* server mode functions */
#ifndef vxWorks /* server mode functions */
static char* filename=(char*)NULL;
/* ----------------------------- */
/* signal catcher for the server */
/* ----------------------------- */
static void catch_sig(int sig)
{
fprintf(stderr,"\nbdt server exiting\n");
unlink(filename);
exit(0);
}
/* -------------------------------- */
/* child reaper for the server mode */
/* -------------------------------- */
static void get_child(int sig)
{
#ifdef SOLARIS
while(waitpid(-1,(int*)NULL,WNOHANG)>0);
#else
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
#endif
#if defined linux || defined SOLARIS
signal(SIGCHLD,get_child); /* for reaping children */
#endif
}
/* ------------------------------- */
/* Clear the signals for a process */
/* ------------------------------- */
int BSserverClearSignals()
{
signal(SIGCHLD,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGINT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
return 0;
}
/* ----------------------------------------------------- */
/* Make a unix process into a generic background process */
/* ----------------------------------------------------- */
int BSmakeServer(char** argv)
{
FILE* fd;
if(filename) return -1;
/* set up signal handling for the server */
signal(SIGCHLD,get_child); /* for reaping children */
signal(SIGHUP,catch_sig);
signal(SIGINT,catch_sig);
signal(SIGTERM,catch_sig);
signal(SIGQUIT,catch_sig);
/* disconnect from parent */
switch(fork())
{
case -1: /* error */
perror("Cannot fork");
return -1;
case 0: /* child */
#if defined linux || defined SOLARIS
setpgrp();
#else
setpgrp(0,0);
#endif
setsid();
break;
default: /* parent goes away */
exit(0);
}
/* save process ID */
filename=(char*)malloc(strlen(argv[0])+10);
sprintf(filename,"%s.%d",argv[0],getpid());
fd=fopen(filename,"w");
fprintf(fd,"%d",getpid());
fprintf(stderr,"\npv server pid: %d\n",getpid());
fclose(fd);
return 0;
}
#endif /* server mode functions */
/* --------------------------------------------------------------- */
/* open a bulk data socket to a server given the server IP address */
/* --------------------------------------------------------------- */
BS* BSipOpen(char* address, int Port)
{
struct hostent* pHostent;
unsigned long addr;
BSDATA info;
struct sockaddr_in* tsin;
tsin=(struct sockaddr_in*)&(info.sin);
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(address[0]))
{
#endif
addr=inet_addr(address);
#ifndef vxWorks
}
else
{
if((pHostent=gethostbyname(address))==NULL) return NULL;
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
}
#endif
tsin->sin_port=htons(Port);
tsin->sin_family=AF_INET;
memcpy((char*)&(tsin->sin_addr),(char*)&addr,sizeof(addr));
return BSipOpenData(&info);
}
BS* BSipOpenData(BSDATA* info)
{
struct sockaddr_in tsin;
int osoc;
BS* bdt;
tsin.sin_port=0;
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((osoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
{
perror("BSipOpen: create socket failed");
return (BS*)NULL;
}
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BSipOpen: local address bind failed");
return (BS*)NULL;
}
if(connect(osoc,(struct sockaddr*)&(info->sin),sizeof(info->sin))<0)
{
perror("BSipOpen: connect failed");
close(osoc);
return (BS*)NULL;
}
bdt=(BS*)malloc(sizeof(BS));
bdt->soc=osoc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BSidle;
#ifndef vxWorks
{
int j;
j = fcntl(bdt->soc, F_GETFL, 0);
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
}
#endif
/* now connected to the bulk data socket on the IOC */
return bdt;
}
/* -------------------------------------- */
/* write size bytes from buffer to socket */
/* -------------------------------------- */
int BSwrite(int soc,void* buffer,int size)
{
int rc;
int total;
unsigned char* data;
fd_set fds;
struct timeval to;
data=(unsigned char*)buffer;
total=size;
to.tv_sec = 5;
to.tv_usec = 0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if(select(FD_SETSIZE,NULL,&fds,NULL,&to) != 1)
{
printf("BSwrite: timeout waiting to write data\n");
return -1;
}
/* send block of data */
if((rc=send(soc,(char*)&data[size-total],total,0))<0)
{
if(errno == EINTR)
rc = 0;
else
perror("BSwrite: Send to remote failed");
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* --------------------------------------- */
/* send a message header down a BS socket */
/* --------------------------------------- */
int BSsendHeader(BS* bdt,unsigned short verb,int size)
{
BSmsgHead buf;
if(bdt->state!=BSidle)
{
fprintf(stderr,"BSsendHeader: Interface not idle\n");
bdt->state=BSbad;
return -1;
}
buf.verb=htons(verb);
buf.size=htonl((unsigned long)size);
if(BSwrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
{
fprintf(stderr,"BSsendHeader: write to remote failed");
return -1;
}
if(BSwrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
{
fprintf(stderr,"BSsendHeader: write to remote failed");
return -1;
}
/* don't wait for response if data must go out */
if(size)
{
bdt->remaining_send=size;
bdt->state=BSsData;
}
return 0;
}
/* ------------------------------------------- */
/* send a message data chunk down a BS socket */
/* ------------------------------------------- */
int BSsendData(BS* bdt,void* buffer,int size)
{
int len;
int remaining;
int rc;
if(bdt->state!=BSsData)
{
fprintf(stderr,"BSsendData: Interface not in send data mode\n");
bdt->state=BSbad;
return -1;
}
remaining=bdt->remaining_send-size;
if(remaining<0)
{
fprintf(stderr,"WARNING -- BSsendData: To much data to send\n");
len=bdt->remaining_send;
}
else
len=size;
if (BSwrite(bdt->soc, buffer, len) < 0)
return -1;
bdt->remaining_send-=len;
if(bdt->remaining_send<0)
{
fprintf(stderr,"BSsendData: To much data Sent\n");
bdt->remaining_send=0;
}
if(bdt->remaining_send==0)
bdt->state=BSidle;
return len;
}
int BSflushOutput(BS* bdt)
{
#ifdef vxWorks
ioctl(bdt->soc, FIOWFLUSH, 0);
#endif
return 0;
}
/* ------------------------------------- */
/* Read exactly size bytes from remote */
/* ------------------------------------- */
int BSread(int soc,void* buffer,int size)
{
int rc,total;
unsigned char* data;
fd_set fds;
struct timeval to;
to.tv_sec = 5;
to.tv_usec = 0;
data=(unsigned char*)buffer;
total=size;
do
{
#if 1
/* wait for data chunk */
FD_ZERO(&fds);
FD_SET(soc, &fds);
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
{
printf("BSread: timeout waiting for data\n");
return(-1);
}
#endif
if((rc=recv(soc,(char*)&data[size-total],total,0))<0)
{
if(errno==EINTR)
{
printf("BSread: EINTR");
rc=0;
}
else
{
perror("BSread: Receive data chunk failed");
}
}
else
total-=rc;
}
while(rc>0 && total>0);
return (rc<=0)?-1:0;
}
/* ------------------------------------- */
/* wait for a message header from remote */
/* ------------------------------------- */
int BSreceiveHeader(BS* bdt,int* verb,int* size)
{
BSmsgHead buf;
/* can only receive header when in the idle state */
if (bdt->state == BSeof)
return -1;
if(bdt->state != BSidle)
{
fprintf(stderr,"BSreceiveHeader: Interface not idle\n");
bdt->state=BSbad;
return -1;
}
if(BSread(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
{
fprintf(stderr,"BSreceiveHeader: Read failed\n");
return -1;
}
if(BSread(bdt->soc,&buf.size,sizeof(buf.size))<0)
{
fprintf(stderr,"BSreceiveHeader: Read failed\n");
return -1;
}
/* copy message data to user */
*verb=ntohs(buf.verb);
*size=ntohl(buf.size);
if(*size)
bdt->state=BSrData;
bdt->remaining_recv=*size;
return 0;
}
/* ------------------------------------------------------------------------
Wait for a chunk of data from remote.
User can continually call this with a maximum size until it return 0.
------------------------------------------------------------------------ */
int BSreceiveData(BS* bdt,void* buffer,int size)
{
int rc;
/* can only receive data when in the receive data state */
switch(bdt->state)
{
case BSrData: break;
case BSidle: return 0;
default:
fprintf(stderr,"BSreceiveData: bad receive state\n");
bdt->state=BSbad;
break;
}
if (bdt->remaining_recv < size)
size = bdt->remaining_recv;
if(BSread(bdt->soc,buffer,size)<0)
{
fprintf(stderr,"BSreceiveData: Read failed\n");
bdt->state = BSeof;
return -1;
}
bdt->remaining_recv-=size;
if(bdt->remaining_recv<0)
{
fprintf(stderr,"BSreceiveData: To much data received\n");
bdt->remaining_recv=0;
}
if(bdt->remaining_recv==0)
bdt->state=BSidle;
return size;
}
/* -------------------- */
/* close the connection */
/* -------------------- */
int BSclose(BS* bdt)
{
int verb,size,done;
/* send a close message out */
if(BSsendHeader(bdt,BS_Close,0)<0)
{
fprintf(stderr,"BSclose: Cannot send close message\n");
return -1;
}
done=0;
do
{
/* check response */
if(BSreceiveHeader(bdt,&verb,&size)<0)
{
fprintf(stderr,"BSclose: Close message response error\n");
return -1;
}
switch(verb)
{
case BS_Ok:
done=1;
break;
case BS_Error:
fprintf(stderr,"BSclose: Close rejected\n");
return -1;
default: break;
}
}
while(done==0);
BSfreeBS(bdt);
return 0;
}
/* --------------------------------------- */
/* make a listener socket for UDP - simple */
/* --------------------------------------- */
int BSopenListenerUDP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
tsin.sin_port=htons(Port);
tsin.sin_family=AF_INET;
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_DGRAM,BS_UDP))<0)
{
perror("BSopenListenerUDP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BSopenListenerUDP: local bind failed");
close(nsoc);
return -1;
}
return nsoc;
}
/* --------------------------------------- */
/* make a listener socket for TCP - simple */
/* --------------------------------------- */
int BSopenListenerTCP(int Port)
{
int nsoc;
struct sockaddr_in tsin;
memset ((void *)&tsin, 0, sizeof(struct sockaddr_in));
tsin.sin_port=htons(Port);
tsin.sin_family=htons(AF_INET);
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
if((nsoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
{
perror("BSopenListenerTCP: open socket failed");
return -1;
}
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
{
perror("BSopenListenerTCP: local bind failed");
close(nsoc);
return -1;
}
listen(nsoc,5);
return nsoc;
}
/* ------------------------------- */
/* make BS from a socket - simple */
/* ------------------------------- */
BS* BSmakeBS(int soc)
{
BS* bdt;
bdt=(BS*)malloc(sizeof(BS));
bdt->soc=soc;
bdt->remaining_send=0;
bdt->remaining_recv=0;
bdt->state=BSidle;
return bdt;
}
/* --------------------------- */
/* free a BS and close socket */
/* --------------------------- */
int BSfreeBS(BS* bdt)
{
close(bdt->soc);
free(bdt);
return 0;
}
/*-----------------------------------------------------------------------*/
/*
Next three function adjust the fields of the BSDATA structure.
*/
/*-----------------------------------------------------------------------*/
int BSgetAddressPort(BSDATA* info, char* ip_addr, int* dest_port)
{
char* name;
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
*dest_port=sin->sin_port;
name=inet_ntoa(sin->sin_addr);
strcpy(ip_addr,name);
return 0;
}
int BSsetAddressPort(BSDATA* info, char* ip_addr, int dest_port)
{
BSsetPort(info, dest_port);
return BSsetAddress(info, ip_addr);
}
int BSsetPort(BSDATA* info, int dest_port)
{
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
sin->sin_family=AF_INET;
sin->sin_port=htons(dest_port);
return 0;
}
int BSsetAddress(BSDATA* info, char* ip_addr)
{
struct hostent *pHostent;
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
unsigned long addr;
#ifndef vxWorks
/* Deal with the name -vs- IP number issue. */
if (isdigit(ip_addr[0]))
{
#endif
if((addr=inet_addr(ip_addr))==-1) return -1;
#ifndef vxWorks
}
else
{
if((pHostent=gethostbyname(ip_addr))==NULL) return -1;
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
}
#endif
sin->sin_family=AF_INET;
memcpy((char*)&(sin->sin_addr),(char*)&addr,sizeof(addr));
return 0;
}
/* ----------------------------------------------------------------- */
/*
All this function does is send a broadcast message and return the
addressing info to the caller of a responder to the broadcast.
arguments:
soc - broadcast socket to use for sending data
trys - number of times to send if no response
o_info - outgoing BSDATA, address/port info
i_info - incoming BSDATA, address/port where response came from
omsg/osize - outgoing message and size
imsg/isize - incoming message and buffer size
Returns the number of bytes read.
*/
/* ----------------------------------------------------------------- */
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
void* omsg,int osize,void* imsg,int isize)
{
int i;
int rc=0;
for(i=0;rc==0 && i<trys;i++)
{
/* send out the message */
rc=BSwriteUDP(soc,o_info,omsg,osize);
if(rc<0) return rc;
/* wait for a response */
rc=BSreadUDP(soc,i_info,1,imsg,isize);
}
return rc;
}
int BSbroadcast(int soc,BSDATA* o_info, void* omsg,int osize)
{
int rc;
/* send out the message */
rc=BSwriteUDP(soc,o_info,omsg,osize);
return rc;
}
/* ----------------------------------------------------------------------- */
/*
This function waits for a message and sends out an ACK when it gets one.
addressing info to the caller of a responder to the broadcast.
Lots of arguments:
soc - The socket to send the message down.
info - The socket information telling where the data read came from
(returned to the user).
tout - Timeout for read in seconds. 0=no wait, -1=wait forever.
buf - Buffer to populate with read data.
size - Size of the buf.
returns the length the read message, 0 is timeout, -1 is error
*/
/* ----------------------------------------------------------------------- */
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size)
{
int mlen,rc;
fd_set fds;
struct timeval to;
int error=0;
do
{
FD_ZERO(&fds);
FD_SET(soc, &fds);
if(tout==-1)
rc=select(FD_SETSIZE,&fds,NULL,NULL,NULL);
else
{
to.tv_sec=tout;
to.tv_usec=0;
rc=select(FD_SETSIZE,&fds,NULL,NULL,&to);
}
switch(rc)
{
case -1: /* bad */
switch(errno)
{
case EINTR: break;
default: error=-1; break;
}
break;
case 0: /* timeout */
break;
default: /* data ready */
break;
}
}
while(rc<0 && error==0);
error=0;
if(rc>0)
{
error=0;
do
{
info->len=sizeof(info->sin);
mlen=recvfrom(soc,(char*)buf,size,0, &info->sin,&info->len);
if(mlen<0)
{
switch(errno)
{
case EINTR: break;
default: error=-1; break;
}
}
}
while(mlen<0 && error==0);
if(mlen<0)
rc=-1;
else
rc=mlen;
}
return rc;
}
/*-----------------------------------------------------------------------*/
/*
Write a chuck of data to a UDP socket at an internet address
*/
/*-----------------------------------------------------------------------*/
int BSwriteDataUDP(int soc,int dest_port,char* ip_addr,void* buf,int size)
{
BSDATA data;
BSsetAddress(&data,ip_addr);
BSsetPort(&data,dest_port);
return BSwriteUDP(soc,&data,buf,size);
}
/*-----------------------------------------------------------------------*/
/*
Write a chunk of data to a UDP socket using BSDATA.
Arguments:
*/
/*-----------------------------------------------------------------------*/
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize)
{
int mlen;
mlen=sendto(soc,(char*)obuf,osize,0,&info->sin,sizeof(info->sin));
return mlen;
}
/*-----------------------------------------------------------------------*/
/*
Write/Read a chuck of data to a UDP socket using BSDATA.
Arguments:
soc - socket to send message down and read from
info - address/port to send message to
obuf/osize - outgoing message and size of it.
ibuf/isize - incoming message and size of the buffer.
Returns the number of bytes read, -1 for error.
*/
/*-----------------------------------------------------------------------*/
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize)
{
int done,i,mlen,flen;
struct sockaddr fromsin;
fd_set fds;
struct timeval tout;
done=0;
mlen=0;
for(i=0;i<BS_RETRY_COUNT && done==0;i++)
{
mlen=sendto(soc,(char*)obuf,osize,0,&(info->sin),sizeof(info->sin));
if(mlen<0)
{
printf("send failed\n");
return -1;
}
tout.tv_sec=0;
tout.tv_usec=200000;
FD_ZERO(&fds);
FD_SET(soc,&fds);
switch(select(FD_SETSIZE,&fds,(fd_set*)0,(fd_set*)0,&tout))
{
case 0: /* timeout */ break;
case -1: /* error */
printf("select failed\n");
return -1;
default: /* data ready */
flen=sizeof(fromsin);
mlen=recvfrom(soc,(char*)ibuf,isize,0,&fromsin,&flen);
if(mlen<0) return -1;
done=1;
break;
}
}
if(i>=BS_RETRY_COUNT) return 0;
return mlen;
}
/*-----------------------------------------------------------------------*/
/*
Open a broadcast socket and set port to a default.
*/
/*-----------------------------------------------------------------------*/
int BSipBroadcastOpen(BSDATA* info, int default_dest_port)
{
struct sockaddr_in* sin;
int soc;
sin=(struct sockaddr_in*)&(info->sin);
if( (soc=BSgetBroadcastSocket(0,sin)) <0) return -1;
sin->sin_port=htons(default_dest_port);
return soc;
}
/*-----------------------------------------------------------------------*/
/*
BSgetBroadcastSocket() - return a broadcast socket for a port, return
a sockaddr also.
*/
/*-----------------------------------------------------------------------*/
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin)
{
int on=1;
int soc;
BS bs;
sin->sin_port=htons(port);
sin->sin_family=AF_INET;
sin->sin_addr.s_addr=htonl(INADDR_ANY);
if( (soc=socket(AF_INET,SOCK_DGRAM,BS_UDP)) < 0 )
{
perror("socket create failed");
return -1;
}
setsockopt(soc,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on));
if( bind(soc,(struct sockaddr*)sin,sizeof(struct sockaddr_in)) < 0 )
{
perror("socket bind failed");
close(soc);
return -1;
}
if( BSgetBroadcastAddr(soc,(struct sockaddr*)sin) < 0 )
return -1;
return soc;
}
/*-----------------------------------------------------------------------*/
/*
BSgetBroadcastAddr() - Determine the broadcast address, this is
directly from the Sun Network Programmer's guide.
*/
/*-----------------------------------------------------------------------*/
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin)
{
struct ifconf ifc;
struct ifreq* ifr;
struct ifreq* save;
char buf[BUFSIZ];
int tot,i;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if(ioctl(soc,SIOCGIFCONF,(int)&ifc) < 0)
{ perror("ioctl SIOCGIFCONF failed"); return -1; }
ifr = ifc.ifc_req;
tot = ifc.ifc_len/sizeof(struct ifreq);
save=(struct ifreq*)NULL;
i=0;
do
{
if(ifr[i].ifr_addr.sa_family==AF_INET)
{
if(ioctl(soc,SIOCGIFFLAGS,(int)&ifr[i])<0)
{ perror("ioctl SIOCGIFFLAGS failed"); return -1; }
if( (ifr[i].ifr_flags&IFF_UP) &&
!(ifr[i].ifr_flags&IFF_LOOPBACK) &&
(ifr[i].ifr_flags&IFF_BROADCAST))
{ save=&ifr[i]; }
}
} while( !save && ++i<tot );
if(save)
{
if(ioctl(soc,SIOCGIFBRDADDR,(int)save)<0)
{ perror("ioctl SIOCGIFBRDADDR failed"); return -1; }
memcpy((char*)sin,(char*)&save->ifr_broadaddr,
sizeof(save->ifr_broadaddr));
}
else
return -1;
return 0;
}

188
src/dbtools/BSlib.h Normal file
View File

@@ -0,0 +1,188 @@
#ifndef ___BS_H
#define ___BS_H
/*
* $Log$
*/
/*
Author: Jim Kowalkowski
Date: 9/1/95
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* got from protocols(5) (cheated) or /etc/protocols */
#define BS_UDP 17
#define BS_TCP 6
/* server ports - in the user reserved area - above 50000 */
#define BS_UDP_PORT 50296
#define BS_TCP_PORT 50297
/* message types */
#define BS_Ok 0
#define BS_Error 1
#define BS_Close 2
#define BS_Ping 3
#define BS_Done 4
#define BS_LAST_VERB 4
#define BS_RETRY_COUNT 3
/* protocol states */
typedef enum { BSidle,BSunbound,BSsData,BSrData,BSbad,BSeof } BSstate;
struct bs
{
int soc;
int remaining_send;
int remaining_recv;
BSstate state;
};
typedef struct bs BS;
struct bs_udp_data
{
struct sockaddr sin;
int len;
};
typedef struct bs_udp_data BSDATA;
struct BSmsgHead
{
unsigned short verb;
unsigned long size;
};
typedef struct BSmsgHead BSmsgHead;
typedef unsigned long BS_ULONG;
#define BSgetSocket(BS) (BS->soc)
#define BSgetResidualWrite(BS) (BS->remaining_send)
#define BSgetResidualRead(BS) (BS->remaining_recv)
#define BSgetProtoState(BS) (BS->state)
/* ------------------------------------------------------------------------
Server functions:
BSopenListenerTCP:
Open a socket locally bound to the bulk data transfer TCP server port.
Set the socket up as a listener. Return the open socket.
BSopenListenerUDP:
Open a socket locally bound to the bulk data transfer UDP server port.
Return the open socket.
------------------------------------------------------------------------ */
int BSopenListenerTCP(int Port);
int BSopenListenerUDP(int Port);
int BSopenTCP(BSDATA*);
/* ------------------------------------------------------------------------
Utilities functions:
BSmakeServer:
Available under unix only. Put process in the background, disassociate
process from controlling terminal and parent process, and prepare
signals for reaping children spawned by the process.
BSserverClearSignals:
Clear the signal handlers for a process, set them to default.
BSmakeBS:
Allocate and initialize a BS from a socket.
BSfreeBS:
Close the open socket and free the memory for the BS.
------------------------------------------------------------------------ */
#ifndef vxWorks
int BSmakeServer(char** argv);
int BSserverClearSignals();
#endif
BS* BSmakeBS(int socket); /* make a BS from a socket */
int BSfreeBS(BS* bdt); /* free a BS */
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin);
int BSipBroadcastOpen(BSDATA* info, int default_dest_port);
int BSgetAddressPort(BSDATA* info,char* ip_addr, int* dest_port);
int BSsetAddressPort(BSDATA* info,char* ip_addr, int dest_port);
int BSsetAddress(BSDATA* info,char* ip_addr);
int BSsetPort(BSDATA* info,int dest_port);
/* ------------------------------------------------------------------------
UDP functions:
------------------------------------------------------------------------ */
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize);
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize);
int BSwriteDataUDP(int soc,int dest_port, char* ip_addr,void* obuf,int osize);
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size);
int BSbroadcast(int soc,BSDATA* info,void* buf,int size);
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
void* obuf,int osize,void* ibuf,int isize);
/* ------------------------------------------------------------------------
Client functions:
BSipOpen:
Open a connection to an bulk data transfer given the IP address of the
machine where the server exists. The returned BS is returned unbound,
a connect must be issued before data transactions can take place.
BSclose:
Completely close a connection to a server and free the BS.
------------------------------------------------------------------------ */
BS* BSipOpen(char* address, int port);
BS* BSipOpenData(BSDATA* info);
int BSclose(BS* bdt);
/* ------------------------------------------------------------------------
Client and Server shared functions:
BSsendHeader:
Send a message header out to a connect BS with command and message body
size information.
BSsendData:
Send a portion or all the message body out a connected BS. A header
must have previously been sent with length information. The interface
will only allow the amount of data specified in the header to be sent.
BSwrite:
This call will block until all the data specified in the size parameter
are sent down the socket.
BSread:
This call will block until all the data specified in the size parameter
is read from the socket.
BSreceiveHeader:
Wait until a message header appears at the BS, return the action and
remaining message body size.
BSreceiveData:
Wait for a chunk or the entire body of a message to appear at the BS.
Put the data into the buffer for a maximum size. Return the amount of
data actually received, or zero if there is no data remaining for the
current message.
------------------------------------------------------------------------ */
int BSsendHeader(BS* bdt, unsigned short verb, int size);
int BSsendData(BS* bdt, void* buffer, int size);
int BSreceiveHeader(BS* bdt, int* verb, int* size);
int BSreceiveData(BS* bdt, void* buffer, int size);
int BSread(int socket, void* buffer, int size);
int BSwrite(int socket, void* buffer, int size);
int BSflushOutput(BS* bdt);
#endif

View File

@@ -2,29 +2,45 @@ EPICS = ../../../..
include Target.include
include $(EPICS)/config/CONFIG_BASE
# USR_CFLAGS = -v
LEX = $(ELEX)
YACC = $(EYACC)
YACCOPT = -l
LEXOPT = -L
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
dbLoadRecords_lex.c dbLoadRecords.c
dbLoadRecords_lex.c dbLoadRecords.c \
../BSlib.c ../PVSserver.c ../rdbapplist.c ../rdbls.o
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
VAR_OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
OBJS = $(VAR_OBJS) BSlib.o PVSserver.o rdbapplist.o rdbls.o
PROD = subtool dbLoadTemplate
PROD = subtool dbLoadTemplate rdbls rdbapplist
TARGETS = PVSserver
include $(EPICS)/config/RULES.Unix
dbLoadTemplate.o: dbLoadTemplate_lex.c
dbLoadRecords.o: dbLoadRecords_lex.c
subtool: dbLoadTemplate.c dbLoadTemplate_lex.c dbVarSub.o
$(RM) $@
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o subtool dbLoadTemplate.c dbVarSub.o -s
PVSserver: PVSserver.o BSlib.o
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
dbLoadTemplate: $(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LDLIBS) -lDb
rdbls: rdbls.o BSlib.o
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
rdbapplist: rdbapplist.o BSlib.o
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
subtool.o: dbLoadTemplate.c dbLoadTemplate_lex.c
$(COMPILE.c) $(CFLAGS) -DSUB_TOOL -o $@ $<
subtool: subtool.o dbVarSub.o
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o $@ $^ -s
dbLoadTemplate: $(VAR_OBJS)
$(LINK.c) -o $@ $^ $(LDLIBS) -lDb
clean::
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \

View File

@@ -8,8 +8,9 @@ YACCOPT = -l
LEXOPT = -L
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
dbLoadRecords_lex.c dbLoadRecords.c
LIBOBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
dbLoadRecords_lex.c dbLoadRecords.c ../BSlib.c ../PVSvx.c
LIBOBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o BSlib.o PVSvx.o
LIBNAME = dbSubs

31
src/dbtools/PVS.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef __PVS_H
#define __PVS_H
#include "BSlib.h"
#define PVS_RETRY_COUNT 4
#define PVS_TRANSFER_SIZE 1024
#define PVS_UDP 17
#define PVS_TCP 6
#define PVS_UDP_PORT 50298
#define PVS_TCP_PORT 50299
#define PVS_UDP_CPORT 50300
#define PVS_Data (BS_LAST_VERB+1)
#define PVS_Alive (BS_LAST_VERB+2)
#define PVS_RecList (BS_LAST_VERB+3)
#define PVS_AppList (BS_LAST_VERB+4)
#define PVS_RecDump (BS_LAST_VERB+5)
#define PVS_LAST_VERB PVS_RecDump
struct pvs_info_packet
{
unsigned short cmd;
char text[90];
};
typedef struct pvs_info_packet PVS_INFO_PACKET;
#define PVS_SET_CMD(pvs_info,command) (pvs_info)->cmd=htons(command)
#endif

263
src/dbtools/PVSserver.c Normal file
View File

@@ -0,0 +1,263 @@
/* only runable on work station now */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
struct PVSnode
{
BSDATA info;
int alive;
struct PVSnode* next;
};
typedef struct PVSnode PVSNODE;
static PVSNODE* ioc_list = (PVSNODE*)NULL;
static int read_pvs(BSDATA* info,int serv,char* sname);
#ifndef PVS_SERVER_PROG
int main(int argc,char** argv)
{
BSDATA info;
int serv;
int rc;
if(argc<4)
{
fprintf(stderr,"usage: %s IOC-name server-number [server-name]\n",
argv[0]);
return -1;
}
serv=atoi(argv[2]);
BSsetAddress(&info,argv[1]);
if(serv>PVS_LAST_VERB)
rc=read_pvs(&info,serv,argv[3]);
else
rc=read_pvs(&info,serv,(char*)NULL);
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
return 0;
}
#else
int main(int argc,char** argv)
{
int soc,mlen;
unsigned short buf,in_buf,ping;
BSDATA info;
PVSNODE* node;
if(BSmakeServer(argv)<0)
{
fprintf(stderr,"Cannot make into a server\n");
return -1;
}
if((soc=BSopenListenerUDP(PVS_UDP_PORT))<0)
{
fprintf(stderr,"Open of UDP listener socket failed\n");
return -1;
}
buf=htons(BS_Ok); /* always sends this out */
ping=htons(BS_Ping); /* always sends this out */
while(1)
{
/* wait forever until a message comes in */
mlen=BSreadUDP(soc,&info,7,&in_buf,sizeof(in_buf));
/* check for errors */
switch(mlen)
{
case 0: /* timeout */
printf("Why did a timeout occur?\n");
/* send out a ping to each of the IOCs in the ioc_list */
for(node=ioc_list;node;node=node->next)
{
mlen=BStransUDP(soc,&(node->info),&ping,sizeof(ping),
&in_buf,sizeof(in_buf));
/* check for errors */
switch(mlen)
{
case 0: /* timeout */
printf("IOC dead\n");
node->alive=0;
break;
case -1: /* error */
printf("Communications failed\n");
break;
default: /* ok */
if(node->alive==0)
{
switch(fork())
{
case -1: /* error */
perror("fork failure");
break;
case 0: /* child */
close(soc);
BSserverClearSignals();
sleep(1);
if(read_pvs(&(node->info))==0)
node->alive=1;
default: /* parent */
break;
}
}
break;
}
}
break;
case -1: /* error */
fprintf(stderr,"Communications failure\n");
break;
default: /* ok */
if(BSwriteUDP(soc,&info,&buf,sizeof(buf))<0)
fprintf(stderr,"respone send failed\n");
else
{
node=(PVSNODE*)malloc(sizeof(PVSNODE));
node->alive=1;
node->info=info;
BSsetPort(&(node->info),PVS_UDP_CPORT);
node->next=ioc_list;
ioc_list=node;
switch(fork())
{
case -1: /* error */
perror("fork failure");
break;
case 0: /* child */
close(soc);
BSserverClearSignals();
sleep(1);
return read_pvs(&info,PVS_RecList,NULL);
default: /* parent */
break;
}
}
break;
}
}
close(soc);
return 0;
}
#endif
static int read_pvs(BSDATA* info,int serv,char* sname)
{
BS* bs;
int verb,size,done,len,i,port,rsize;
char* buffer;
char ip_from[40];
FILE* fd;
BSgetAddressPort(info,ip_from,&port);
/* printf("IOC %s starting\n",ip_from); */
/* verify ioc not already added */
if(access(ip_from,F_OK)==0)
{
/* delete the existing file for this IOC */
unlink(ip_from);
}
done=0;
BSsetPort(info,PVS_TCP_PORT);
if((bs=BSipOpenData(info))==NULL)
{
fprintf(stderr,"Open of socket to IOC failed\n");
return -1;
}
if(serv>PVS_LAST_VERB)
rsize=strlen(sname)+1;
else
rsize=0;
if(BSsendHeader(bs,serv,rsize)<0)
{
fprintf(stderr,"Command send failed\n");
return -1;
}
if(rsize>0)
{
if(BSsendData(bs,sname,rsize)<0)
{
fprintf(stderr,"send of command name failed\n");
return -1;
}
}
#ifdef PVS_SERVER_PROG
if((fd=fopen(ip_from,"w"))==(FILE*)NULL)
{
fprintf(stderr,"Open of name file failed\n");
return -1;
}
#else
fd=stdout;
#endif
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
while(done==0)
{
if(BSreceiveHeader(bs,&verb,&size)<0)
{
fprintf(stderr,"Receive header failed\n");
done=-1;
}
else
{
switch(verb)
{
case PVS_Data: /* read a block of names */
if((len=BSreceiveData(bs,buffer,size))<0)
{
fprintf(stderr,"Receive data failed\n");
}
else
{
for(i=0;i<len;i++)
{
if(buffer[i]==' ') buffer[i]='\n';
}
buffer[len]='\n';
buffer[len+1]='\0';
fputs(buffer,fd);
}
break;
case BS_Done: /* transfers complete */
BSclose(bs);
done=-1;
break;
default:
if(size>0) done=-1;
break;
}
}
}
#ifdef PVS_SERVER_PROG
fclose(fd);
#endif
free(buffer);
return 0;
}

361
src/dbtools/PVSvx.c Normal file
View File

@@ -0,0 +1,361 @@
/* This file not really set up to run under Unix yet, just under vxWorks. */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#ifdef vxWorks
#include <vxWorks.h>
#include <iv.h>
#include <taskLib.h>
#include <sysSymTbl.h>
#include <sysLib.h>
#include <symLib.h>
#include <dbStaticLib.h>
extern struct dbBase *pdbBase;
#else
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#endif
static void PVSserver(int want_annouce,char* name);
static int PVSannouce(int want_annouce,char* name);
static void handle_requests(BS* bs);
static void handle_reclist(BS* bs);
static void handle_applist(BS* bs);
static void handle_recdump(BS* bs);
static void handle_spylist(BS* bs);
static void handle_tasklist(BS* bs);
void PVS_test_server(BS* bs);
static char* names = (char*)NULL;
static char* buffer = (char*)NULL;
#ifdef vxWorks
int PVSstart(int want_annouce, char* name)
#else
int main(int argc,char** argv)
#endif
{
#ifndef vxWorks
char* name;
int want_annouce;
#endif
#ifndef vxWorks
if(argc<3)
{
fprintf(stderr,"bad args\n");
fprintf(stderr," usage: %s a_flag host_name\n",
argv[0]);
fprintf(stderr," where\n");
fprintf(stderr," a_flag=0(want),1(don't want) to annouce boot\n");
fprintf(stderr," host_name=PV master host (if one exists)\n");
return -1;
}
name=argv[2];
if(sscanf(argv[1],"%d",&want_annouce)<1)
{
fprintf(stderr,"bad a_flag\n");
return -1;
}
#endif
taskSpawn("PVS",150,VX_FP_TASK|VX_STDIO,5000,
(FUNCPTR)PVSserver,want_annouce,(int)name,0,0,0,0,0,0,0,0);
return 0;
}
static int PVSannouce(int want_annouce,char* name)
{
int soc,mlen;
PVS_INFO_PACKET buf,in_buf;
BSDATA info,in_info;
if(want_annouce==0 && name)
{
if((soc=BSopenListenerUDP(0))<0)
{
printf("Open of UDP socket failed\n");
return -1;
}
if(BSsetAddressPort(&info,name,PVS_UDP_PORT)<0)
{
printf("Set send port failed\n");
return -1;
}
PVS_SET_CMD(&buf,PVS_Alive);
mlen=BStransUDP(soc,&info,&buf,sizeof(buf),&in_buf,sizeof(in_buf));
/* check for errors */
switch(mlen)
{
case 0: /* timeout */
printf("No server running on host\n");
break;
case -1: /* error */
printf("Communications failed\n");
break;
default: /* ok */
break;
}
close(soc);
}
return 0;
}
static void PVSserver(int want_annouce,char* name)
{
fd_set fds,rfds;
int tsoc,usoc,nsoc,len,s;
struct sockaddr stemp;
int stemp_len;
PVS_INFO_PACKET buf;
BSDATA info;
BS* bs;
bs=(BS*)NULL;
buffer=(char*)malloc(100); /* just make the buffer */
names=(char*)malloc(PVS_TRANSFER_SIZE);
if((tsoc=BSopenListenerTCP(PVS_TCP_PORT))<0)
{
printf("PVSserver: Open of TCP listener socket failed\n");
return;
}
if((usoc=BSopenListenerUDP(PVS_UDP_CPORT))<0)
{
printf("PVSserver: Open of UDP listener socket failed\n");
return;
}
FD_ZERO(&fds);
FD_SET(tsoc,&fds);
FD_SET(usoc,&fds);
PVSannouce(want_annouce,name);
while(1)
{
rfds=fds;
if(select(FD_SETSIZE,&rfds,(fd_set*)NULL,(fd_set*)NULL,
(struct timeval*)NULL)<0)
{
printf("PVSserver: Select failure\n");
}
else
{
if(FD_ISSET(tsoc,&rfds))
{
/* handle the request here - single threaded server */
stemp_len=sizeof(stemp);
if((nsoc=accept(tsoc,&stemp,&stemp_len))<0)
printf("PVSserver: Bad accept\n");
else
{
bs=BSmakeBS(nsoc);
handle_requests(bs);
BSfreeBS(bs);
}
}
if(FD_ISSET(usoc,&rfds))
{
/* only pings will come in here for now */
len=BSreadUDP(usoc,&info,0,&buf,sizeof(buf));
if(len<=0)
printf("PVSserver: UDP listener read failure\n");
else
{
if(BSwriteUDP(usoc,&info,&buf,sizeof(buf))<0)
printf("PVSserver: UDP listener ping write failure\n");
}
}
}
}
}
static void handle_reclist(BS* bs)
{
DBENTRY db;
long rc;
char* n;
unsigned long names_len;
int s;
dbInitEntry(pdbBase,&db);
names_len=0;
for(rc=dbFirstRecdes(&db);rc==0;rc=dbNextRecdes(&db))
{
for(rc=dbFirstRecord(&db);rc==0;rc=dbNextRecord(&db))
{
/* collect the names util we excede the max */
n=dbGetRecordName(&db);
s=strlen(n);
if((names_len+s)>PVS_TRANSFER_SIZE)
{
names[names_len++]='\0';
if(BSsendHeader(bs,PVS_Data,names_len)<0)
printf("PVSserver: data cmd failed\n");
else
{
if(BSsendData(bs,names,names_len)<0)
printf("PVSserver: data send failed\n");
}
names_len=0;
}
memcpy(&names[names_len],n,s);
names_len+=s;
names[names_len++]=' ';
}
}
if(names_len>0)
{
names[names_len++]='\0';
if(BSsendHeader(bs,PVS_Data,names_len)<0)
printf("PVSserver: data cmd failed\n");
else
{
if(BSsendData(bs,names,names_len)<0)
printf("PVSserver: data send failed\n");
}
}
BSsendHeader(bs,BS_Done,0);
}
static void handle_requests(BS* bs)
{
int verb,size,notdone,len;
void (*func)(BS*);
SYM_TYPE stype;
notdone=1;
while(notdone)
{
/* at this point I should be getting a command */
if(BSreceiveHeader(bs,&verb,&size)<0)
{
printf("PVSserver: receive header failed\n");
notdone=0;
}
else
{
switch(verb)
{
case PVS_RecList: handle_reclist(bs); break;
case PVS_AppList: handle_applist(bs); break;
case PVS_RecDump: handle_recdump(bs); break;
case BS_Close:
BSsendHeader(bs,BS_Ok,0);
notdone=0;
break;
case PVS_Data: break;
case PVS_Alive: break;
case BS_Ok: break;
case BS_Error: break;
case BS_Ping: break;
case BS_Done: break;
default:
/* custom service */
if(size>0)
{
/* this should be the name of the service */
/* look up the symbol name in buffer and call as
subroutine, passing it the BS */
len=BSreceiveData(bs,&buffer[1],size);
switch(len)
{
case 0: /* timeout */ notdone=0; break;
case -1: /* error */ notdone=0; break;
default:
buffer[0]='_';
if(strncmp(buffer,"_PVS",4)==0)
{
if(symFindByName(sysSymTbl,buffer,
(char**)&func,&stype)==ERROR)
func=(void (*)(BS*))NULL;
if(func)
func(bs);
else
BSsendHeader(bs,BS_Done,0);
}
else
BSsendHeader(bs,BS_Done,0);
}
}
else
printf("PVSserver: unknown command received\n");
}
}
}
}
/* --------------------------------------------------------------- */
struct dbnode
{
char* name;
struct dbnode* next;
};
typedef struct dbnode DBNODE;
extern DBNODE* DbApplList;
void handle_applist(BS* bs)
{
DBNODE* n;
int size,len;
len=0;
for(n=DbApplList;n;n=n->next)
{
len=strlen(n->name)+1;
if(BSsendHeader(bs,PVS_Data,len)<0)
printf("PVSserver: data cmd failed\n");
else
{
if(BSsendData(bs,n->name,len)<0)
printf("PVSserver: data send failed\n");
}
}
BSsendHeader(bs,BS_Done,0);
}
/* --------------------------------------------------------------- */
void handle_recdump(BS* bs)
{
printf("RecDump server invoked\n");
BSsendHeader(bs,BS_Done,0);
}
void PVS_test_server(BS* bs)
{
printf("PVS_test_server invoked\n");
BSsendHeader(bs,BS_Done,0);
}
void handle_spylist(BS* bs)
{
printf("PVS spy list server invoked\n");
}
void handle_tasklist(BS* bs)
{
printf("PVS task list server invoked\n");
}

View File

@@ -49,6 +49,17 @@ static char subst_buffer[VAR_MAX_SUB_SIZE];
static int subst_used;
static int line_num;
struct db_app_node
{
char* name;
struct db_app_node* next;
};
typedef struct db_app_node DB_APP_NODE;
DB_APP_NODE* DbApplList=(DB_APP_NODE*)NULL;
static DB_APP_NODE* DbCurrentListHead=(DB_APP_NODE*)NULL;
static DB_APP_NODE* DbCurrentListTail=(DB_APP_NODE*)NULL;
static int yyerror();
static void sub_pvname(char*,char*);
@@ -65,8 +76,9 @@ extern struct dbBase *pdbBase;
%token <Str> WORD VALUE
%token <Str> FIELD
%left O_BRACE C_BRACE O_PAREN C_PAREN
%left DATABASE CONTAINER RECORD
%left NOWHERE
%left DATABASE RECORD
%left NOWHERE
%token APPL
%union
{
@@ -105,18 +117,39 @@ n_body: O_BRACE records C_BRACE
;
db_components: /* null */
| db_components container
| db_components applic
| db_components record
;
container: CONTAINER c_head c_body
;
applic: APPL O_PAREN VALUE C_PAREN
{
DB_APP_NODE* an=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE*));
c_head: O_PAREN WORD C_PAREN
{ free($2); }
;
if(subst_used)
{
strcpy(subst_buffer,$<Str>3);
if(dbDoSubst(subst_buffer,sizeof(subst_buffer),NULL)!=0)
fprintf(stderr,"dbDoSubst failed\n");
#ifdef vxWorks
an->name=strdup(subst_buffer);
free($3);
#else
printf("\napplication(\"%s\")\n",subst_buffer);
#endif
}
else
{
#ifdef vxWorks
an->name=$<Str>3;
#else
printf("\napplication(\"%s\")\n",$<Str>3);
#endif
}
if(DbCurrentListHead==(DB_APP_NODE*)NULL) DbCurrentListTail=an;
c_body: O_BRACE db_components C_BRACE
an->next=DbCurrentListHead;
DbCurrentListHead=an;
}
;
records: /* null */
@@ -190,13 +223,24 @@ field: FIELD O_PAREN WORD COMMA VALUE C_PAREN
static int yyerror(str)
char *str;
{ fprintf(stderr,"db file parse, Error line %d : %s\n",line_num, yytext); }
#ifdef vxWorks
static char* strdup(char* x)
{
char* c;
c=(char*)malloc(strlen(x)+1);
strcpy(c,x);
return c;
}
#endif
static int is_not_inited = 1;
int dbLoadRecords(char* pfilename, char* pattern, char* container)
int dbLoadRecords(char* pfilename, char* pattern)
{
FILE* fp;
long status;
DB_APP_NODE* an;
#ifdef vxWorks
if(pdbBase==NULL)
@@ -243,6 +287,21 @@ int dbLoadRecords(char* pfilename, char* pattern, char* container)
if(subst_used) dbFreeSubst();
fclose(fp);
if(DbCurrentListHead==(DB_APP_NODE*)NULL)
{
/* set up a default list to put on the master application list */
DbCurrentListHead=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE));
DbCurrentListTail=DbCurrentListHead;
DbCurrentListHead->name=strdup(pfilename);
DbCurrentListHead->next=(DB_APP_NODE*)NULL;
}
DbCurrentListTail->next=DbApplList;
DbApplList=DbCurrentListHead;
DbCurrentListHead=(DB_APP_NODE*)NULL;
DbCurrentListTail=(DB_APP_NODE*)NULL;
return 0;
}
@@ -276,3 +335,14 @@ static void sub_pvname(char* type, char* name)
}
}
#ifdef vxWorks
int dbAppList()
{
DB_APP_NODE* an;
for(an=DbApplList;an;an=an->next)
printf("%s\n",an->name);
return 0;
}
#endif

View File

@@ -12,9 +12,9 @@ value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
"field" { return(FIELD); }
"grecord" { return(RECORD); }
"record" { return(RECORD); }
"container" { return(CONTAINER); }
"database" { return(DATABASE); }
"nowhere" { return(NOWHERE); }
"application" { return(APPL); }
\"{value}*\" { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(VALUE); }

View File

@@ -276,9 +276,11 @@ sub_pat: WORD EQUALS WORD
#include "dbLoadTemplate_lex.c"
static int yyerror(str)
char *str;
{ fprintf(stderr,"templ file parse, Error line %d : %s\n",line_num, yytext); }
static int yyerror(char* str)
{
fprintf(stderr,"Substitution file parse error\n");
fprintf(stderr,"line %d:%s\n",line_num,yytext);
}
static int is_not_inited = 1;

116
src/dbtools/rdbapplist.c Normal file
View File

@@ -0,0 +1,116 @@
/* only runable on work station now */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static int read_pvs(BSDATA* info,int serv,char* sname);
int main(int argc,char** argv)
{
BSDATA info;
int rc;
if(argc<2)
{
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
return -1;
}
if(BSsetAddress(&info,argv[1])<0)
{
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
return -1;
}
rc=read_pvs(&info,PVS_AppList,(char*)NULL);
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
return 0;
}
static int read_pvs(BSDATA* info,int serv,char* sname)
{
BS* bs;
int verb,size,done,len,i,port,rsize;
char* buffer;
char ip_from[40];
FILE* fd;
BSgetAddressPort(info,ip_from,&port);
/* verify ioc not already added */
if(access(ip_from,F_OK)==0)
{
/* delete the existing file for this IOC */
unlink(ip_from);
}
done=0;
BSsetPort(info,PVS_TCP_PORT);
if((bs=BSipOpenData(info))==NULL)
{
fprintf(stderr,"Open of socket to IOC failed\n");
return -1;
}
if(serv>PVS_LAST_VERB)
rsize=strlen(sname)+1;
else
rsize=0;
if(BSsendHeader(bs,serv,rsize)<0)
{
fprintf(stderr,"Command send failed\n");
return -1;
}
if(rsize>0)
{
if(BSsendData(bs,sname,rsize)<0)
{
fprintf(stderr,"send of command name failed\n");
return -1;
}
}
fd=stdout;
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
while(done==0)
{
if(BSreceiveHeader(bs,&verb,&size)<0)
{
fprintf(stderr,"Receive header failed\n");
done=-1;
}
else
{
switch(verb)
{
case PVS_Data: /* read a block of names */
if((len=BSreceiveData(bs,buffer,size))<0)
fprintf(stderr,"Receive data failed\n");
else
fputs(buffer,fd);
fputc('\n',fd);
break;
case BS_Done: /* transfers complete */
BSclose(bs);
done=-1;
break;
default:
if(size>0) done=-1;
break;
}
}
}
free(buffer);
return 0;
}

128
src/dbtools/rdbls.c Normal file
View File

@@ -0,0 +1,128 @@
/* only runable on work station now */
#include "PVS.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static int read_pvs(BSDATA* info,int serv,char* sname);
int main(int argc,char** argv)
{
BSDATA info;
int rc;
if(argc<2)
{
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
return -1;
}
if(BSsetAddress(&info,argv[1])<0)
{
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
return -1;
}
rc=read_pvs(&info,PVS_RecList,(char*)NULL);
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
return 0;
}
static int read_pvs(BSDATA* info,int serv,char* sname)
{
BS* bs;
int verb,size,done,len,i,port,rsize;
char* buffer;
char ip_from[40];
FILE* fd;
BSgetAddressPort(info,ip_from,&port);
/* printf("IOC %s starting\n",ip_from); */
/* verify ioc not already added */
if(access(ip_from,F_OK)==0)
{
/* delete the existing file for this IOC */
unlink(ip_from);
}
done=0;
BSsetPort(info,PVS_TCP_PORT);
if((bs=BSipOpenData(info))==NULL)
{
fprintf(stderr,"Open of socket to IOC failed\n");
return -1;
}
if(serv>PVS_LAST_VERB)
rsize=strlen(sname)+1;
else
rsize=0;
if(BSsendHeader(bs,serv,rsize)<0)
{
fprintf(stderr,"Command send failed\n");
return -1;
}
if(rsize>0)
{
if(BSsendData(bs,sname,rsize)<0)
{
fprintf(stderr,"send of command name failed\n");
return -1;
}
}
fd=stdout;
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
while(done==0)
{
if(BSreceiveHeader(bs,&verb,&size)<0)
{
fprintf(stderr,"Receive header failed\n");
done=-1;
}
else
{
switch(verb)
{
case PVS_Data: /* read a block of names */
if((len=BSreceiveData(bs,buffer,size))<0)
{
fprintf(stderr,"Receive data failed\n");
}
else
{
for(i=0;i<len;i++)
{
if(buffer[i]==' ') buffer[i]='\n';
}
buffer[len]='\n';
buffer[len+1]='\0';
fputs(buffer,fd);
}
break;
case BS_Done: /* transfers complete */
BSclose(bs);
done=-1;
break;
default:
if(size>0) done=-1;
break;
}
}
}
free(buffer);
return 0;
}

View File

@@ -65,6 +65,9 @@
* This driver currently needs work on error message generation.
*
* $Log$
* Revision 1.1 1995/03/30 19:34:56 jba
* Seperated drv files into ansi and old dirs. Added combine dir.
*
* Revision 1.37 1995/03/24 21:24:25 winans
* Probable race condition in PEP TX task. Moved the final transmission
* byte assignment into the point where the busy list is locked. This
@@ -2532,6 +2535,11 @@ STATIC int pepTxTask(int link)
if (bbDebug)
printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link);
pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg;
if (bbDebug>30)
printf("pepTxTask(%d): outputting last byte %2.2X\n",
link,*txMsg);
pnode->status = BB_OK;
if (pnode->finishProc != NULL) {

View File

@@ -122,6 +122,9 @@
* for the DMA buffer that is appropriate.
*
* $Log$
* Revision 1.1 1995/03/30 19:35:14 jba
* Seperated drv files into ansi and old dirs. Added combine dir.
*
* Revision 1.22 1995/01/06 17:03:43 winans
* Added some ifdef'd out test code to see if the end of the sequence program
* could be updated to NOT cause an extra sample from port zero to be taken
@@ -181,7 +184,7 @@ static char *SccsId = "$Id$";
#define ADVANCE_HOLD 0xC0
#define RESTART 0x00
/* analogic 2502 memory structure */
/* Analogic 2502 memory structure */
struct dvx_2502
{
unsigned short dev_id; /* device id code (CFF5) */
@@ -205,7 +208,7 @@ struct dvx_inbuf
short *data; /* data buffer */
};
/* analogic 2502 control structure */
/* Analogic 2502 control structure */
struct dvx_rec
{
struct dvx_2502 *pdvx2502; /* pointer to device registers */
@@ -224,6 +227,8 @@ struct dvx_rec
int RearmMode; /* zero if auto-rearm, else manual */
unsigned short ScanRate; /* User settable scan rate */
IOSCANPVT *pioscanpvt;
};
@@ -304,19 +309,19 @@ struct {
static struct dvx_rec dvx[MAX_DVX_CARDS] = {
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0 , NULL
0 , DVX_DRATE, NULL
},
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0, NULL
0, DVX_DRATE, NULL
},
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0, NULL
0, DVX_DRATE, NULL
},
{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}
,{0, 0, 0, 0, 0, 0, 0, 0},
0, NULL
0, DVX_DRATE, NULL
}
};
@@ -425,6 +430,16 @@ dvx_int(struct dvx_rec *dvxptr)
cptr->csr = dvxptr->csr_shadow;
}
int dvx_SetScanRate(int Card, unsigned int Rate)
{
/* make sure hardware exists */
if ((Card >= ai_num_cards[DVX2502]) || (Card < 0))
return(-1);
dvx[Card].ScanRate = Rate & 0x0000FFFF;
dvx[Card].pdvx2502->samp_rate = dvx[Card].ScanRate;
return(0);
}
int dvx_RearmModeSet(int card, int mode)
{
/* make sure hardware exists */
@@ -672,7 +687,11 @@ LOCAL long dvx_driver_init(void)
/*
* set scan rate and enable external start
*/
#if 0
pDvxA16->samp_rate = DVX_DRATE; /* scan rate of 184 KHz */
#else
pDvxA16->samp_rate = dvx[i].ScanRate; /* Set scan rate */
#endif
dvx[i].csr_shadow |= CSR_M_ESTART; /* enable ext start (shadow csr) */
pDvxA16->csr = dvx[i].csr_shadow; /* enable external start */
dvx[i].mode = RUN_MODE; /* ready to aquire data */
@@ -904,12 +923,17 @@ int sramld(int card)
#endif
/* set scan rate and run it once */
#if 0
dvx[card].pdvx2502->samp_rate = DVX_DRATE;
#else
dvx[card].pdvx2502->samp_rate = dvx[card].ScanRate; /* Set scan rate */
#endif
dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_START;
taskDelay(sysClkRateGet()); /* let scan run */
dvx[card].pdvx2502->csr = dvx[card].csr_shadow; /* restore csr */
}
/*
* dvx_driver
*

View File

@@ -7,6 +7,9 @@
# Experimental Physics and Industrial Control System (EPICS)
#
# $Log$
# Revision 1.1 1995/08/17 20:22:09 jba
# Moved bldEnvData,blderrSymTbl, makeStatTbl to libCom dir
#
# Revision 1.3 1995/08/14 19:27:24 jhill
# extern => epicsShareExtern
#
@@ -34,7 +37,7 @@ TOOL=`basename $0`
# Start by creating a list of the ENV_PARAM declarations
PARAMS=`sed -n -e 's/;//' \
-e 's/^[ ]*epicsShareExtern[ ][ ]*ENV_PARAM[ ][ ]*//p' \
-e 's/^[ ]*epicsShareExtern[ ][ ]*ENV_PARAM[ ][ ]*//p' \
${SRC}`
# Create a new header file
@@ -85,7 +88,7 @@ done
# Now create an array pointing to all parameters
cat >>${OBJ} <<!EOF
ENV_PARAM* env_param_list[] = {
ENV_PARAM* env_param_list[EPICS_ENV_VARIABLE_COUNT+1] = {
!EOF
# Contents are the addresses of each parameter

View File

@@ -53,7 +53,7 @@ HOST_ARCH=$2
MAKE=$3
case $HOST_ARCH in
alpha | hp700)
alpha | hp700 | Linux)
# Use gcc if it can be found, or makedepend
GCC=`which gcc`

View File

@@ -73,6 +73,7 @@
#else
# include <sys/types.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#endif
#ifdef vxWorks
@@ -84,10 +85,6 @@
#include <envDefs.h>
#include <errMdef.h>
/*
* for VMS
*/
unsigned long inet_addr (char *);
/*+/subr**********************************************************************

View File

@@ -73,6 +73,7 @@
#else
# include <sys/types.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#endif
#ifdef vxWorks
@@ -84,10 +85,6 @@
#include <envDefs.h>
#include <errMdef.h>
/*
* for VMS
*/
unsigned long inet_addr (char *);
/*+/subr**********************************************************************

View File

@@ -51,6 +51,7 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
* .01 04-07-94 mrk Initial Implementation
*/
#include <stdio.h>
#ifdef vxWorks
#include <vxWorks.h>
#endif

View File

@@ -51,6 +51,7 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
* .01 04-07-94 mrk Initial Implementation
*/
#include <stdio.h>
#ifdef vxWorks
#include <vxWorks.h>
#endif

View File

@@ -45,6 +45,8 @@ SRCS.c += ../recSubArray.c
SRCS.c += ../recTimer.c
SRCS.c += ../recWait.c
SRCS.c += ../recWaitCa.c
SRCS.c += ../recDynLink.c
SRCS.c += ../recDynLinkTest.c
SRCS.c += ../recWaveform.c
# LIBOBJS += recAai.o
@@ -88,6 +90,8 @@ LIBOBJS += recSubArray.o
LIBOBJS += recTimer.o
LIBOBJS += recWait.o
LIBOBJS += recWaitCa.o
LIBOBJS += recDynLink.o
LIBOBJS += recDynLinkTest.o
LIBOBJS += recWaveform.o
LIBNAME = recSup

View File

@@ -257,7 +257,7 @@ static long get_units(paddr,units)
{
struct aaiRecord *paai=(struct aaiRecord *)paddr->precord;
strncpy(units,paai->egu,sizeof(paai->egu));
strncpy(units,paai->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -254,7 +254,7 @@ static long get_units(paddr,units)
{
struct aaoRecord *paao=(struct aaoRecord *)paddr->precord;
strncpy(units,paao->egu,sizeof(paao->egu));
strncpy(units,paao->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -280,7 +280,7 @@ static long get_units(paddr,units)
{
struct aiRecord *pai=(struct aiRecord *)paddr->precord;
strncpy(units,pai->egu,sizeof(pai->egu));
strncpy(units,pai->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -334,7 +334,7 @@ static long get_units(paddr,units)
{
struct aoRecord *pao=(struct aoRecord *)paddr->precord;
strncpy(units,pao->egu,sizeof(pao->egu));
strncpy(units,pao->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -237,7 +237,7 @@ static long get_units(paddr,units)
{
struct calcRecord *pcalc=(struct calcRecord *)paddr->precord;
strncpy(units,pcalc->egu,sizeof(pcalc->egu));
strncpy(units,pcalc->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -274,7 +274,7 @@ static long get_units(paddr,units)
{
struct compressRecord *pcompress=(struct compressRecord *)paddr->precord;
strncpy(units,pcompress->egu,sizeof(pcompress->egu));
strncpy(units,pcompress->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -161,7 +161,7 @@ static long get_units(paddr,units)
{
struct dfanoutRecord *pdfanout=(struct dfanoutRecord *)paddr->precord;
strncpy(units,pdfanout->egu,sizeof(pdfanout->egu));
strncpy(units,pdfanout->egu,DB_UNITS_SIZE);
return(0);
}

542
src/rec/recDynLink.c Normal file
View File

@@ -0,0 +1,542 @@
/*recDynLink.c*/
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
**********************************************************************/
#include <vxWorks.h>
#include <taskLib.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <rngLib.h>
#include <vxLib.h>
#include <semLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <taskwd.h>
#include <fast_lock.h>
#include <db_access.h>
#include <cadef.h>
#include <caerr.h>
#include <caeventmask.h>
#include <calink.h>
#include <tsDefs.h>
#include <task_params.h>
#include <recDynLink.h>
/*Definitions to map between old and new database access*/
/*because we are using CA must include db_access.h*/
/* new field types */
#define newDBF_STRING 0
#define newDBF_CHAR 1
#define newDBF_UCHAR 2
#define newDBF_SHORT 3
#define newDBF_USHORT 4
#define newDBF_LONG 5
#define newDBF_ULONG 6
#define newDBF_FLOAT 7
#define newDBF_DOUBLE 8
#define newDBF_ENUM 9
/* new data request buffer types */
#define newDBR_STRING newDBF_STRING
#define newDBR_CHAR newDBF_CHAR
#define newDBR_UCHAR newDBF_UCHAR
#define newDBR_SHORT newDBF_SHORT
#define newDBR_USHORT newDBF_USHORT
#define newDBR_LONG newDBF_LONG
#define newDBR_ULONG newDBF_ULONG
#define newDBR_FLOAT newDBF_FLOAT
#define newDBR_DOUBLE newDBF_DOUBLE
#define newDBR_ENUM newDBF_ENUM
#define VALID_newDB_REQ(x) ((x >= 0) && (x <= newDBR_ENUM))
static short mapOldToNew[DBF_DOUBLE+1] = {
newDBR_STRING,newDBR_SHORT,newDBR_FLOAT,newDBR_ENUM,
newDBR_CHAR,newDBR_LONG,newDBR_DOUBLE};
static short mapNewToOld[newDBR_ENUM+1] = {
DBF_STRING,DBF_CHAR,DBF_CHAR,DBF_SHORT,DBF_SHORT,
DBF_LONG,DBF_LONG,DBF_FLOAT,DBF_DOUBLE,DBF_ENUM};
extern int interruptAccept;
int recDynLinkQsize = 256;
LOCAL int inpTaskId=0;
LOCAL int outTaskId=0;
LOCAL RING_ID inpRingQ;;
LOCAL RING_ID outRingQ;;
LOCAL SEM_ID wakeUpSem;
typedef enum{cmdSearch,cmdClear,cmdPut} cmdType;
typedef enum{ioInput,ioOutput}ioType;
typedef enum{stateStarting,stateSearching,stateGetting,stateConnected}stateType;
typedef struct dynLinkPvt{
FAST_LOCK lock;
char *pvname;
chid chid;
evid evid;
recDynCallback searchCallback;
recDynCallback monitorCallback;
TS_STAMP timestamp;
short status;
short severity;
void *pbuffer;
size_t nRequest;
short dbrType;
double graphicLow,graphHigh;
double controlLow,controlHigh;
char units[MAX_UNITS_SIZE];
short precision;
ioType io;
stateType state;
short scalar;
} dynLinkPvt;
/*For cmdClear data is chid. For all other commands precDynLink*/
typedef struct {
union {
recDynLink *precDynLink;
dynLinkPvt *pdynLinkPvt;
}data;
cmdType cmd;
}ringBufCmd;
LOCAL void recDynLinkStartInput(void);
LOCAL void recDynLinkStartOutput(void);
LOCAL void connectCallback(struct connection_handler_args cha);
LOCAL void getCallback(struct event_handler_args eha);
LOCAL void monitorCallback(struct event_handler_args eha);
LOCAL void recDynLinkInp(void);
LOCAL void recDynLinkOut(void);
long recDynLinkAddInput(recDynLink *precDynLink,char *pvname,
short dbrType,int options,
recDynCallback searchCallback,recDynCallback monitorCallback)
{
dynLinkPvt *pdynLinkPvt;
struct db_addr dbaddr;
ringBufCmd cmd;
if(options&rdlDBONLY && db_name_to_addr(pvname,&dbaddr))return(-1);
if(!inpTaskId) recDynLinkStartInput();
if(precDynLink->pdynLinkPvt) recDynLinkClear(precDynLink);
pdynLinkPvt = (dynLinkPvt *)calloc(1,sizeof(dynLinkPvt));
if(!pdynLinkPvt) {
printf("recDynLinkAddInput can't allocate storage");
taskSuspend(0);
}
FASTLOCKINIT(&pdynLinkPvt->lock);
precDynLink->pdynLinkPvt = pdynLinkPvt;
pdynLinkPvt->pvname = pvname;
pdynLinkPvt->dbrType = dbrType;
pdynLinkPvt->searchCallback = searchCallback;
pdynLinkPvt->monitorCallback = monitorCallback;
pdynLinkPvt->io = ioInput;
pdynLinkPvt->scalar = (options&rdlSCALAR) ? TRUE : FALSE;
pdynLinkPvt->state = stateStarting;
cmd.data.precDynLink = precDynLink;
cmd.cmd = cmdSearch;
if(rngBufPut(inpRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd))
errMessage(0,"recDynLinkAddInput: rngBufPut error");
return(0);
}
long recDynLinkAddOutput(recDynLink *precDynLink,char *pvname,
short dbrType,int options,
recDynCallback searchCallback)
{
dynLinkPvt *pdynLinkPvt;
struct db_addr dbaddr;
ringBufCmd cmd;
if(options&rdlDBONLY && db_name_to_addr(pvname,&dbaddr))return(-1);
if(!outTaskId) recDynLinkStartOutput();
if(precDynLink->pdynLinkPvt) recDynLinkClear(precDynLink);
pdynLinkPvt = (dynLinkPvt *)calloc(1,sizeof(dynLinkPvt));
if(!pdynLinkPvt) {
printf("recDynLinkAddOutput can't allocate storage");
taskSuspend(0);
}
FASTLOCKINIT(&pdynLinkPvt->lock);
precDynLink->pdynLinkPvt = pdynLinkPvt;
pdynLinkPvt->pvname = pvname;
pdynLinkPvt->dbrType = dbrType;
pdynLinkPvt->searchCallback = searchCallback;
pdynLinkPvt->io = ioOutput;
pdynLinkPvt->scalar = (options&rdlSCALAR) ? TRUE : FALSE;
pdynLinkPvt->state = stateStarting;
cmd.data.precDynLink = precDynLink;
cmd.cmd = cmdSearch;
if(rngBufPut(outRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd))
errMessage(0,"recDynLinkAddInput: rngBufPut error");
semGive(wakeUpSem);
return(0);
}
long recDynLinkClear(recDynLink *precDynLink)
{
dynLinkPvt *pdynLinkPvt;
ringBufCmd cmd;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(!pdynLinkPvt) {
printf("recDynLinkClear. recDynLinkSearch was never called\n");
taskSuspend(0);
}
if(pdynLinkPvt->chid) ca_puser(pdynLinkPvt->chid) = NULL;
cmd.data.pdynLinkPvt = pdynLinkPvt;
cmd.cmd = cmdClear;
if(pdynLinkPvt->io==ioInput) {
if(rngBufPut(inpRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd))
errMessage(0,"recDynLinkClear: rngBufPut error");
} else {
if(rngBufPut(outRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd))
errMessage(0,"recDynLinkClear: rngBufPut error");
}
precDynLink->pdynLinkPvt = NULL;
return(0);
}
long recDynLinkConnectionStatus(recDynLink *precDynLink)
{
dynLinkPvt *pdynLinkPvt;
long status;
pdynLinkPvt = precDynLink->pdynLinkPvt;
status = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1;
return(status);
}
long recDynLinkGetNelem(recDynLink *precDynLink,size_t *nelem)
{
dynLinkPvt *pdynLinkPvt;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(ca_state(pdynLinkPvt->chid)!=cs_conn) return(-1);
*nelem = ca_element_count(pdynLinkPvt->chid);
return(0);
}
long recDynLinkGetControlLimits(recDynLink *precDynLink,
double *low,double *high)
{
dynLinkPvt *pdynLinkPvt;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(pdynLinkPvt->state!=stateConnected) return(-1);
if(low) *low = pdynLinkPvt->controlLow;
if(high) *high = pdynLinkPvt->controlHigh;
return(0);
}
long recDynLinkGetGraphicLimits(recDynLink *precDynLink,
double *low,double *high)
{
dynLinkPvt *pdynLinkPvt;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(pdynLinkPvt->state!=stateConnected) return(-1);
if(low) *low = pdynLinkPvt->graphicLow;
if(high) *high = pdynLinkPvt->graphHigh;
return(0);
}
long recDynLinkGetPrecision(recDynLink *precDynLink,int *prec)
{
dynLinkPvt *pdynLinkPvt;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(pdynLinkPvt->state!=stateConnected) return(-1);
if(prec) *prec = pdynLinkPvt->precision;
return(0);
}
long recDynLinkGetUnits(recDynLink *precDynLink,char *units,int maxlen)
{
dynLinkPvt *pdynLinkPvt;
int maxToCopy;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(pdynLinkPvt->state!=stateConnected) return(-1);
maxToCopy = MAX_UNITS_SIZE;
if(maxlen<maxToCopy) maxToCopy = maxlen;
strncpy(units,pdynLinkPvt->units,maxToCopy);
if(maxToCopy<maxlen) units[maxToCopy] = '\0';
return(0);
}
long recDynLinkGet(recDynLink *precDynLink,void *pbuffer,size_t *nRequest,
TS_STAMP *timestamp,short *status,short *severity)
{
dynLinkPvt *pdynLinkPvt;
long caStatus;
pdynLinkPvt = precDynLink->pdynLinkPvt;
caStatus = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1;
if(caStatus) goto all_done;
if(*nRequest > pdynLinkPvt->nRequest) {
*nRequest = pdynLinkPvt->nRequest;
}
FASTLOCK(&pdynLinkPvt->lock);
memcpy(pbuffer,pdynLinkPvt->pbuffer,
(*nRequest * dbr_size[mapNewToOld[pdynLinkPvt->dbrType]]));
if(timestamp) *timestamp = pdynLinkPvt->timestamp; /*array copy*/
if(status) *status = pdynLinkPvt->status;
if(severity) *severity = pdynLinkPvt->severity;
FASTUNLOCK(&pdynLinkPvt->lock);
all_done:
return(caStatus);
}
long recDynLinkPut(recDynLink *precDynLink,void *pbuffer,size_t nRequest)
{
dynLinkPvt *pdynLinkPvt;
long status;
ringBufCmd cmd;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(pdynLinkPvt->io!=ioOutput || pdynLinkPvt->state!=stateConnected) {
status = -1;
} else {
status = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1;
}
if(status) goto all_done;
if(pdynLinkPvt->scalar) nRequest = 1;
if(nRequest>ca_element_count(pdynLinkPvt->chid))
nRequest = ca_element_count(pdynLinkPvt->chid);
pdynLinkPvt->nRequest = nRequest;
memcpy(pdynLinkPvt->pbuffer,pbuffer,
(nRequest * dbr_size[mapNewToOld[pdynLinkPvt->dbrType]]));
cmd.data.precDynLink = precDynLink;
cmd.cmd = cmdPut;
if(rngBufPut(outRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd))
errMessage(0,"recDynLinkPut: rngBufPut error");
semGive(wakeUpSem);
all_done:
return(status);
}
LOCAL void recDynLinkStartInput(void)
{
if((inpRingQ = rngCreate(sizeof(ringBufCmd) * recDynLinkQsize)) == NULL) {
errMessage(0,"recDynLinkStart failed");
exit(1);
}
inpTaskId = taskSpawn("recDynINP",CA_CLIENT_PRI-1,VX_FP_TASK,
CA_CLIENT_STACK,(FUNCPTR)recDynLinkInp,0,0,0,0,0,0,0,0,0,0);
if(inpTaskId==ERROR) {
errMessage(0,"recDynLinkStartInput: taskSpawn Failure\n");
}
}
LOCAL void recDynLinkStartOutput(void)
{
if((wakeUpSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL)
errMessage(0,"semBcreate failed in recDynLinkStart");
if((outRingQ = rngCreate(sizeof(ringBufCmd) * recDynLinkQsize)) == NULL) {
errMessage(0,"recDynLinkStartOutput failed");
exit(1);
}
outTaskId = taskSpawn("recDynOUT",CA_CLIENT_PRI-1,VX_FP_TASK,
CA_CLIENT_STACK,(FUNCPTR)recDynLinkOut,0,0,0,0,0,0,0,0,0,0);
if(outTaskId==ERROR) {
errMessage(0,"recDynLinkStart: taskSpawn Failure\n");
}
}
LOCAL void connectCallback(struct connection_handler_args cha)
{
chid chid = cha.chid;
recDynLink *precDynLink;
dynLinkPvt *pdynLinkPvt;
precDynLink = (recDynLink *)ca_puser(cha.chid);
if(!precDynLink) return;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(ca_state(chid)==cs_conn) {
pdynLinkPvt->state = stateGetting;
SEVCHK(ca_get_callback(DBR_CTRL_DOUBLE,chid,getCallback,precDynLink),
"ca_get_callback");
} else {
if(pdynLinkPvt->searchCallback)
(pdynLinkPvt->searchCallback)(precDynLink);
}
}
LOCAL void getCallback(struct event_handler_args eha)
{
struct dbr_ctrl_double *pdata = (struct dbr_ctrl_double *)eha.dbr;
recDynLink *precDynLink;
dynLinkPvt *pdynLinkPvt;
size_t nRequest;
precDynLink = (recDynLink *)ca_puser(eha.chid);
if(!precDynLink) return;
pdynLinkPvt = precDynLink->pdynLinkPvt;
pdynLinkPvt -> graphicLow = pdata->lower_disp_limit;
pdynLinkPvt -> graphHigh = pdata->upper_disp_limit;
pdynLinkPvt -> controlLow = pdata->lower_ctrl_limit;
pdynLinkPvt -> controlHigh = pdata->upper_ctrl_limit;
pdynLinkPvt -> precision = pdata->precision;
strncpy(pdynLinkPvt->units,pdata->units,MAX_UNITS_SIZE);
if(pdynLinkPvt->scalar) {
pdynLinkPvt->nRequest = 1;
} else {
pdynLinkPvt->nRequest = ca_element_count(pdynLinkPvt->chid);
}
nRequest = pdynLinkPvt->nRequest;
pdynLinkPvt->pbuffer = calloc(nRequest,
dbr_size[mapNewToOld[pdynLinkPvt->dbrType]]);
if(pdynLinkPvt->io==ioInput) {
SEVCHK(ca_add_array_event(
dbf_type_to_DBR_TIME(mapNewToOld[pdynLinkPvt->dbrType]),
pdynLinkPvt->nRequest,
pdynLinkPvt->chid,monitorCallback,precDynLink,
0.0,0.0,0.0,
&pdynLinkPvt->evid),"ca_add_array_event");
}
pdynLinkPvt->state = stateConnected;
if(pdynLinkPvt->searchCallback) (pdynLinkPvt->searchCallback)(precDynLink);
}
LOCAL void monitorCallback(struct event_handler_args eha)
{
recDynLink *precDynLink;
dynLinkPvt *pdynLinkPvt;
long count = eha.count;
void *pbuffer = eha.dbr;
struct dbr_time_string *pdbr_time_string;
void *pdata;
short timeType;
precDynLink = (recDynLink *)ca_puser(eha.chid);
if(!precDynLink) return;
pdynLinkPvt = precDynLink->pdynLinkPvt;
if(pdynLinkPvt->pbuffer) {
FASTLOCK(&pdynLinkPvt->lock);
if(count>=pdynLinkPvt->nRequest)
count = pdynLinkPvt->nRequest;
pdbr_time_string = (struct dbr_time_string *)pbuffer;
timeType = dbf_type_to_DBR_TIME(mapNewToOld[pdynLinkPvt->dbrType]);
pdata = (void *)((char *)pbuffer + dbr_value_offset[timeType]);
pdynLinkPvt->timestamp = pdbr_time_string->stamp; /*array copy*/
pdynLinkPvt->status = pdbr_time_string->status;
pdynLinkPvt->severity = pdbr_time_string->severity;
memcpy(pdynLinkPvt->pbuffer,pdata,
(count * dbr_size[mapNewToOld[pdynLinkPvt->dbrType]]));
FASTUNLOCK(&pdynLinkPvt->lock);
}
if(pdynLinkPvt->monitorCallback)
(*pdynLinkPvt->monitorCallback)(precDynLink);
}
LOCAL void recDynLinkInp(void)
{
int status;
recDynLink *precDynLink;
dynLinkPvt *pdynLinkPvt;
int caStatus;
ringBufCmd cmd;
taskwdInsert(taskIdSelf(),NULL,NULL);
SEVCHK(ca_task_initialize(),"ca_task_initialize");
while(TRUE) {
while (rngNBytes(inpRingQ)>=sizeof(cmd) && interruptAccept){
if(rngBufGet(inpRingQ,(void *)&cmd,sizeof(cmd))
!=sizeof(cmd)) {
errMessage(0,"recDynLinkTask: rngBufGet error");
continue;
}
if(cmd.cmd==cmdClear) {
pdynLinkPvt = cmd.data.pdynLinkPvt;
if(pdynLinkPvt->chid)
SEVCHK(ca_clear_channel(pdynLinkPvt->chid),
"ca_clear_channel");
free(pdynLinkPvt->pbuffer);
free((void *)pdynLinkPvt);
continue;
}
precDynLink = cmd.data.precDynLink;
pdynLinkPvt = precDynLink->pdynLinkPvt;
switch(cmd.cmd) {
case(cmdSearch) :
SEVCHK(ca_search_and_connect(pdynLinkPvt->pvname,
&pdynLinkPvt->chid, connectCallback,precDynLink),
"ca_search_and_connect");
break;
default:
epicsPrintf("Logic error statement in recDynLinkTask\n");
}
}
status = ca_pend_event(.1);
if(status!=ECA_NORMAL && status!=ECA_TIMEOUT)
SEVCHK(status,"ca_pend_event");
}
}
LOCAL void recDynLinkOut(void)
{
int status;
recDynLink *precDynLink;
dynLinkPvt *pdynLinkPvt;
ringBufCmd cmd;
int caStatus;
taskwdInsert(taskIdSelf(),NULL,NULL);
SEVCHK(ca_task_initialize(),"ca_task_initialize");
while(TRUE) {
semTake(wakeUpSem,sysClkRateGet());
while (rngNBytes(outRingQ)>=sizeof(cmd) && interruptAccept){
if(rngBufGet(outRingQ,(void *)&cmd,sizeof(cmd))
!=sizeof(cmd)) {
errMessage(0,"recDynLinkTask: rngBufGet error");
continue;
}
if(cmd.cmd==cmdClear) {
pdynLinkPvt = cmd.data.pdynLinkPvt;
if(pdynLinkPvt->chid)
SEVCHK(ca_clear_channel(pdynLinkPvt->chid),
"ca_clear_channel");
free(pdynLinkPvt->pbuffer);
free((void *)pdynLinkPvt);
continue;
}
precDynLink = cmd.data.precDynLink;
pdynLinkPvt = precDynLink->pdynLinkPvt;
switch(cmd.cmd) {
case(cmdSearch) :
SEVCHK(ca_search_and_connect(pdynLinkPvt->pvname,
&pdynLinkPvt->chid, connectCallback,precDynLink),
"ca_search_and_connect");
break;
case(cmdPut) :
caStatus = ca_array_put(
mapNewToOld[pdynLinkPvt->dbrType],
pdynLinkPvt->nRequest,pdynLinkPvt->chid,
pdynLinkPvt->pbuffer);
if(caStatus!=ECA_NORMAL) {
epicsPrintf("recDynLinkTask pv=%s CA Error %s\n",
pdynLinkPvt->pvname,ca_message(caStatus));
}
break;
default:
epicsPrintf("Logic error statement in recDynLinkTask\n");
}
}
status = ca_pend_event(.00001);
if(status!=ECA_NORMAL && status!=ECA_TIMEOUT)
SEVCHK(status,"ca_pend_event");
}
}

51
src/rec/recDynLink.h Normal file
View File

@@ -0,0 +1,51 @@
/*recDynLink.c*/
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
*******************************************************************/
#ifndef INCrecDynLinkh
#define INCrecDynLinkh
#include <tsDefs.h>
typedef struct recDynLink{
void *puserPvt;
void *pdynLinkPvt;
} recDynLink;
typedef void (*recDynCallback)(recDynLink *);
#define rdlDBONLY 0x1
#define rdlSCALAR 0x2
long recDynLinkAddInput(recDynLink *precDynLink,char *pvname,
short dbrType,int options,
recDynCallback searchCallback,recDynCallback monitorCallback);
long recDynLinkAddOutput(recDynLink *precDynLink,char *pvname,
short dbrType,int options,
recDynCallback searchCallback);
long recDynLinkClear(recDynLink *precDynLink);
/*The following routine returns (0,-1) for (connected,not connected)*/
long recDynLinkConnectionStatus(recDynLink *precDynLink);
/*thye following routine returns (0,-1) if (connected,not connected)*/
long recDynLinkGetNelem(recDynLink *precDynLink,size_t *nelem);
/*The following 4 routines return (0,-1) if data (is, is not) yet available*/
/*searchCallback is not called until this info is available*/
long recDynLinkGetControlLimits(recDynLink *precDynLink,
double *low,double *high);
long recDynLinkGetGraphicLimits(recDynLink *precDynLink,
double *low,double *high);
long recDynLinkGetPrecision(recDynLink *precDynLink,int *prec);
long recDynLinkGetUnits(recDynLink *precDynLink,char *units,int maxlen);
/*get only valid mfor rdlINPUT. put only valid for rdlOUTPUT*/
long recDynLinkGet(recDynLink *precDynLink,
void *pbuffer, size_t *nRequest,
TS_STAMP *timestamp,short *status,short *severity);
long recDynLinkPut(recDynLink *precDynLink,void *pbuffer,size_t nRequest);
#endif /*INCrecDynLinkh*/

191
src/rec/recDynLinkTest.c Normal file
View File

@@ -0,0 +1,191 @@
/*recDynLinkTest.c */
/*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
This software was developed under a United States Government license
described on the COPYRIGHT_UniversityOfChicago file included as part
of this distribution.
***********************************************************************/
#include <vxWorks.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <dbDefs.h>
#include <tsDefs.h>
#include <recDynLink.h>
#include <dbAccess.h>
/*The remainder of this source module is test code */
typedef struct userPvt {
char *pvname;
double *pbuffer;
size_t nRequest;
}userPvt;
LOCAL void mymonitorCallback(recDynLink *precDynLink)
{
userPvt *puserPvt;
long status;
size_t nRequest;
TS_STAMP timestamp;
short AlarmStatus,AlarmSeverity;
int i;
char timeStr[40];
puserPvt = (userPvt *)precDynLink->puserPvt;
printf("mymonitorCallback: %s\n",puserPvt->pvname);
if(recDynLinkConnectionStatus(precDynLink)!=0) {
printf(" not connected\n");
return;
}
nRequest = puserPvt->nRequest;
status = recDynLinkGet(precDynLink,puserPvt->pbuffer,&nRequest,
&timestamp,&AlarmStatus,&AlarmSeverity);
if(status) {
printf("recDynLinkGet returned illegal status\n");
return;
}
tsStampToText(&timestamp,TS_TEXT_MMDDYY,timeStr);
printf("date %s status %hd severity %hd ",
timeStr,AlarmStatus,AlarmSeverity);
for(i=0; i<puserPvt->nRequest; i++) {
printf(" %f",puserPvt->pbuffer[i]);
}
printf("\n");
}
LOCAL void mysearchCallback(recDynLink *precDynLink)
{
userPvt *puserPvt;
size_t nelem;
double controlLow,controlHigh;
double graphicLow,graphicHigh;
int prec;
char units[20];
long status;
puserPvt = (userPvt *)precDynLink->puserPvt;
printf("mysearchCallback: %s ",puserPvt->pvname);
if(recDynLinkConnectionStatus(precDynLink)==0) {
printf("connected\n");
status = recDynLinkGetNelem(precDynLink,&nelem);
if(status) {
printf("recDynLinkGetNelem failed\n");
}else{
printf("nelem = %u\n",nelem);
}
status=recDynLinkGetControlLimits(precDynLink,&controlLow,&controlHigh);
if(status) {
printf("recDynLinkGetControlLimits failed\n");
}else{
printf("controlLow %f controlHigh %f\n",controlLow,controlHigh);
}
status=recDynLinkGetGraphicLimits(precDynLink,&graphicLow,&graphicHigh);
if(status) {
printf("recDynLinkGetGraphicLimits failed\n");
}else{
printf("graphicLow %f graphicHigh %f\n",graphicLow,graphicHigh);
}
status = recDynLinkGetPrecision(precDynLink,&prec);
if(status) {
printf("recDynLinkGetPrecision failed\n");
}else{
printf("prec = %d\n",prec);
}
status = recDynLinkGetUnits(precDynLink,units,20);
if(status) {
printf("recDynLinkGetUnits failed\n");
}else{
printf("units = %s\n",units);
}
} else {
printf(" not connected\n");
}
}
LOCAL recDynLink getDynlink = {NULL,NULL};
LOCAL recDynLink putDynlink = {NULL,NULL};
int recDynTestInput(char *pvname,int nRequest)
{
userPvt *puserPvt= getDynlink.puserPvt;
long status;
int options=0;
if(puserPvt) {
recDynLinkClear(&getDynlink);
free(puserPvt->pbuffer);
free(getDynlink.puserPvt);
getDynlink.puserPvt = NULL;
}
getDynlink.puserPvt = puserPvt = (userPvt *)calloc(1,sizeof(userPvt));
puserPvt->pbuffer = calloc(nRequest,sizeof(double));
puserPvt->nRequest = nRequest;
puserPvt->pvname = pvname;
if(nRequest==1) options=rdlSCALAR;;
status = recDynLinkAddInput(&getDynlink,pvname,
DBR_DOUBLE,options,
mysearchCallback,mymonitorCallback);
if(status) return(status);
return(status);
}
int recDynTestNewOutput(char *pvname,int nRequest)
{
userPvt *puserPvt= putDynlink.puserPvt;
long status;
int options=0;
if(puserPvt) {
recDynLinkClear(&putDynlink);
free(puserPvt->pbuffer);
free(putDynlink.puserPvt);
putDynlink.puserPvt = NULL;
}
putDynlink.puserPvt = puserPvt = (userPvt *)calloc(1,sizeof(userPvt));
puserPvt->pbuffer = calloc(nRequest,sizeof(double));
puserPvt->nRequest = nRequest;
puserPvt->pvname = pvname;
if(nRequest==1) options=rdlSCALAR;;
status = recDynLinkAddOutput(&putDynlink,pvname,
DBR_DOUBLE,options,mysearchCallback);
return(status);
}
int recDynTestOutput(int startValue)
{
userPvt *puserPvt= putDynlink.puserPvt;
long status;
int i;
for(i=0; i<puserPvt->nRequest; i++) puserPvt->pbuffer[i] = startValue + i;
status = recDynLinkPut(&putDynlink,puserPvt->pbuffer,puserPvt->nRequest);
return(status);
}
int recDynTestClearInput(void)
{
userPvt *puserPvt= getDynlink.puserPvt;
recDynLinkClear(&getDynlink);
free(puserPvt->pbuffer);
free(getDynlink.puserPvt);
getDynlink.puserPvt = NULL;
return(0);
}
int recDynTestClearOutput(void)
{
userPvt *puserPvt= putDynlink.puserPvt;
recDynLinkClear(&putDynlink);
free(puserPvt->pbuffer);
free(putDynlink.puserPvt);
putDynlink.puserPvt = NULL;
return(0);
}

View File

@@ -201,7 +201,7 @@ static long get_units(paddr,units)
{
struct gsubRecord *psub=(struct gsubRecord *)paddr->precord;
strncpy(units,psub->egu,sizeof(psub->egu));
strncpy(units,psub->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -203,7 +203,7 @@ static long get_units(paddr,units)
{
struct longinRecord *plongin=(struct longinRecord *)paddr->precord;
strncpy(units,plongin->egu,sizeof(plongin->egu));
strncpy(units,plongin->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -241,7 +241,7 @@ static long get_units(paddr,units)
{
struct longoutRecord *plongout=(struct longoutRecord *)paddr->precord;
strncpy(units,plongout->egu,sizeof(plongout->egu));
strncpy(units,plongout->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -173,7 +173,7 @@ static long get_units(paddr,units)
{
struct palRecord *ppal=(struct palRecord *)paddr->precord;
strncpy(units,ppal->egu,sizeof(ppal->egu));
strncpy(units,ppal->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -177,7 +177,7 @@ static long get_units(paddr,units)
{
struct pidRecord *ppid=(struct pidRecord *)paddr->precord;
strncpy(units,ppid->egu,sizeof(ppid->egu));
strncpy(units,ppid->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -199,7 +199,7 @@ static long get_units(paddr,units)
{
struct selRecord *psel=(struct selRecord *)paddr->precord;
strncpy(units,psel->egu,sizeof(psel->egu));
strncpy(units,psel->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -295,7 +295,7 @@ static long get_units(paddr,units)
{
struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord;
strncpy(units,psm->egu,sizeof(psm->egu));
strncpy(units,psm->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -219,7 +219,7 @@ static long get_units(paddr,units)
{
struct subRecord *psub=(struct subRecord *)paddr->precord;
strncpy(units,psub->egu,sizeof(psub->egu));
strncpy(units,psub->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -248,7 +248,7 @@ static long get_units(paddr,units)
{
struct subArrayRecord *psa=(struct subArrayRecord *)paddr->precord;
strncpy(units,psa->egu,sizeof(psa->egu));
strncpy(units,psa->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -303,7 +303,7 @@ static long get_units(paddr,units)
{
struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord;
strncpy(units,pwf->egu,sizeof(pwf->egu));
strncpy(units,pwf->egu,DB_UNITS_SIZE);
return(0);
}

View File

@@ -1580,7 +1580,7 @@ struct client *client
int status;
unsigned sid;
unsigned long count;
int type;
ca_uint16_t type;
/* Exit quickly if channel not on this node */
status = db_name_to_addr(
@@ -1643,7 +1643,7 @@ struct client *client
}
sid = pchannel->sid;
count = tmp_addr.no_elements;
type = tmp_addr.field_type;
type = (ca_uint16_t) tmp_addr.field_type;
}
SEND_LOCK(client);

View File

@@ -100,7 +100,7 @@ int cast_server(void)
struct sockaddr_in new_recv_addr;
int recv_addr_size;
unsigned nchars;
short port;
unsigned short port;
taskwdInsert((int)taskIdCurrent,NULL,NULL);

View File

@@ -80,7 +80,7 @@ int rsrv_online_notify_task()
int status;
int sock;
int true = TRUE;
short port;
unsigned short port;
taskwdInsert(taskIdSelf(),NULL,NULL);

View File

@@ -174,7 +174,7 @@ char get; /* T: get F: monitor */
GLBLTYPE int CASDEBUG;
GLBLTYPE int IOC_sock;
GLBLTYPE int IOC_cast_sock;
GLBLTYPE int ca_server_port;
GLBLTYPE unsigned short ca_server_port;
GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST rsrv_free_clientQ; /* locked by clientQlock */
GLBLTYPE ELLLIST rsrv_free_addrq;

View File

@@ -82,7 +82,7 @@ Expr *ssp; /* Parent state set */
printf("\n/* Action function for state \"%s\" in state set \"%s\" */\n",
sp->value, ssp->value);
/* action function declaration with ss_ptr as parameter */
printf("static A_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("static void A_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
@@ -122,7 +122,7 @@ Expr *ssp;
printf("\n/* Event function for state \"%s\" in state set \"%s\" */\n",
sp->value, ssp->value);
printf("static E_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("static int E_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
@@ -184,7 +184,7 @@ Expr *ssp;
printf("\n/* Delay function for state \"%s\" in state set \"%s\" */\n",
sp->value, ssp->value);
printf("static D_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("static void D_%s_%s(sprog, ss_ptr, var_ptr)\n", ssp->value, sp->value);
printf("SPROG\t*sprog;\n");
printf("SSCB\t*ss_ptr;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
@@ -507,7 +507,7 @@ gen_exit_handler()
Expr *ep;
printf("/* Exit handler */\n");
printf("static exit_handler(sprog, var_ptr)\n");
printf("static void exit_handler(sprog, var_ptr)\n");
printf("SPROG\t*sprog;\n");
printf("struct UserVar\t*var_ptr;\n{\n");
for (ep = exit_code_list; ep != 0; ep = ep->next)

View File

@@ -1,6 +1,12 @@
/*
* $Log$
* Revision 1.14 1995/08/30 15:38:39 jbk
* *** empty log message ***
*
* Revision 1.13 1995/08/18 13:19:31 mrk
* Made changes for ansi c
*
* Revision 1.12 1995/08/17 20:35:09 jbk
* fixed all the -pendantic errors (pain)
*
@@ -99,7 +105,8 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
*/
#define MAKE_DEBUG TSdriverDebug
#define TS_DRIVER
#define TS_DRIVER 1
#define TS_ALLOW_FORCE 1
#include <vxWorks.h>
#include <vme.h>
@@ -213,6 +220,9 @@ TSinfo TSdata = { TS_master_dead, TS_async_slave, TS_async_none,
extern char* sysBootLine;
int TSdirectTimeVar = 0; /* aother way to indicate direct time */
int TSgoodTimeStamps = 0; /* a way to force use of accurate time stamps */
static WDOG_ID wd;
static long correction_factor = 0;
static long correction_count = 0;
@@ -383,8 +393,13 @@ long TSgetTimeStamp(int event_number,struct timespec* sp)
switch(event_number)
{
case 0:
*sp = TSdata.event_table[0]; /* one tick watch dog maintains */
break;
#ifdef TS_ALLOW_FORCE
if(TSgoodTimeStamps==0)
#endif
{
*sp = TSdata.event_table[0]; /* one tick watch dog maintains */
break;
}
case -1:
{
struct timespec ts;
@@ -494,6 +509,8 @@ long TSinit(void)
TSregisterErrorHandler = TSregisterErrorHandlerError;
TSforceSync = TSforceSoftSync;
TSgetTime = TSgetCurrentTime;
TSdriverInit = TSdriverInitError;
TSdirectTime = TSdirectTimeError;
TSdata.sync_event=ER_EVENT_RESET_TICK;
}
@@ -518,7 +535,7 @@ long TSinit(void)
else
TSdata.has_event_system = 1;
if(TSdirectTime()>0) TSdata.has_direct_time=1;
if(TSdirectTime()>0 || TSdirectTimeVar>0) TSdata.has_direct_time=1;
/* allocate the event table */
TSdata.event_table=(struct timespec*)malloc(