Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
297f0b8c31 | ||
|
|
cc20412693 | ||
|
|
7021cd3589 | ||
|
|
b7acf453c2 | ||
|
|
c9abc2c82e | ||
|
|
a7484494c4 | ||
|
|
52cfbe92bf | ||
|
|
75f0fb2b0c | ||
|
|
ed36723d6c | ||
|
|
f7a5da9139 | ||
|
|
254c5b1620 | ||
|
|
c6aab85d79 | ||
|
|
d54724fce1 | ||
|
|
60c0acab3c | ||
|
|
69f33b9e23 | ||
|
|
9191863094 | ||
|
|
1beb157ab0 | ||
|
|
41ae285075 | ||
|
|
222063ac53 | ||
|
|
3342ca120f | ||
|
|
13b785e594 | ||
|
|
6931273fef | ||
|
|
8d52177933 | ||
|
|
b64fa8bd87 | ||
|
|
34ce2ab6ac | ||
|
|
43ef20b90c | ||
|
|
818bc0d475 | ||
|
|
ca2f9aff52 | ||
|
|
64a93df872 | ||
|
|
ecc03e9ad9 | ||
|
|
db1b46e5f9 | ||
|
|
d87295397e | ||
|
|
7277c336f7 | ||
|
|
30ad5b1149 | ||
|
|
c6bcd1a10b | ||
|
|
f3cf369071 | ||
|
|
adffe02a2d | ||
|
|
e635080cef | ||
|
|
be85da6a3a | ||
|
|
c16006f34d | ||
|
|
72491d8829 | ||
|
|
cb78c5adb8 | ||
|
|
1a2cd5953d | ||
|
|
5da79a5f56 | ||
|
|
9f2d9587f0 | ||
|
|
74e405969a |
45
COPYRIGHT_UniversityOfChicago
Normal file
45
COPYRIGHT_UniversityOfChicago
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
|
||||
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
|
||||
AND IN ALL SOURCE LISTINGS OF THE CODE.
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
Argonne National Laboratory (ANL), with facilities in the States of
|
||||
Illinois and Idaho, is owned by the United States Government, and
|
||||
operated by the University of Chicago under provision of a contract
|
||||
with the Department of Energy.
|
||||
|
||||
Portions of this material resulted from work developed under a U.S.
|
||||
Government contract and are subject to the following license: For
|
||||
a period of five years from March 30, 1993, the Government is
|
||||
granted for itself and others acting on its behalf a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, and perform
|
||||
publicly and display publicly. With the approval of DOE, this
|
||||
period may be renewed for two additional five year periods.
|
||||
Following the expiration of this period or periods, the Government
|
||||
is granted for itself and others acting on its behalf, a paid-up,
|
||||
nonexclusive, irrevocable worldwide license in this computer
|
||||
software to reproduce, prepare derivative works, distribute copies
|
||||
to the public, perform publicly and display publicly, and to permit
|
||||
others to do so.
|
||||
|
||||
*****************************************************************
|
||||
DISCLAIMER
|
||||
*****************************************************************
|
||||
|
||||
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
|
||||
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
|
||||
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
|
||||
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
||||
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
|
||||
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
|
||||
OWNED RIGHTS.
|
||||
|
||||
*****************************************************************
|
||||
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
|
||||
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
15
MakeRelease
15
MakeRelease
@@ -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.$$;
|
||||
|
||||
|
||||
10
SkeletonCOPYRIGHT_UniversityOfChicago
Normal file
10
SkeletonCOPYRIGHT_UniversityOfChicago
Normal file
@@ -0,0 +1,10 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
@@ -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;
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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;
|
||||
|
||||
158
src/ca/iocinf.c
158
src/ca/iocinf.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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!!
|
||||
*
|
||||
|
||||
@@ -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)))
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -622,14 +622,16 @@ int db_post_single_event(struct event_block *pevent)
|
||||
*
|
||||
*/
|
||||
int db_post_events(
|
||||
struct dbCommon *precord,
|
||||
union native_value *pvalue,
|
||||
unsigned int select
|
||||
void *prec,
|
||||
void *pval,
|
||||
unsigned int select
|
||||
)
|
||||
{
|
||||
struct event_block *event;
|
||||
struct event_que *ev_que;
|
||||
unsigned int putix;
|
||||
struct dbCommon *precord = (struct dbCommon *)prec;
|
||||
union native_value *pvalue = (union native_value *)pval;
|
||||
struct event_block *event;
|
||||
struct event_que *ev_que;
|
||||
unsigned int putix;
|
||||
|
||||
if (precord->mlis.count == 0) return OK; /* no monitors set */
|
||||
|
||||
|
||||
@@ -83,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <ellLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <dbAccess.h>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
986
src/dbtools/BSlib.c
Normal file
@@ -0,0 +1,986 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "BSlib.h"
|
||||
|
||||
#ifdef linux
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <in.h>
|
||||
#include <ioctl.h>
|
||||
#include <inetLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <selectLib.h>
|
||||
#else
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef SOLARIS
|
||||
#define BSD_COMP
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
|
||||
|
||||
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* server mode functions */
|
||||
|
||||
#ifndef vxWorks /* server mode functions */
|
||||
static char* filename=(char*)NULL;
|
||||
|
||||
/* ----------------------------- */
|
||||
/* signal catcher for the server */
|
||||
/* ----------------------------- */
|
||||
static void catch_sig(int sig)
|
||||
{
|
||||
fprintf(stderr,"\nbdt server exiting\n");
|
||||
unlink(filename);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* -------------------------------- */
|
||||
/* child reaper for the server mode */
|
||||
/* -------------------------------- */
|
||||
static void get_child(int sig)
|
||||
{
|
||||
#ifdef SOLARIS
|
||||
while(waitpid(-1,(int*)NULL,WNOHANG)>0);
|
||||
#else
|
||||
while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0);
|
||||
#endif
|
||||
|
||||
#if defined linux || defined SOLARIS
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* Clear the signals for a process */
|
||||
/* ------------------------------- */
|
||||
int BSserverClearSignals()
|
||||
{
|
||||
signal(SIGCHLD,SIG_DFL);
|
||||
signal(SIGHUP,SIG_DFL);
|
||||
signal(SIGINT,SIG_DFL);
|
||||
signal(SIGTERM,SIG_DFL);
|
||||
signal(SIGQUIT,SIG_DFL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
/* Make a unix process into a generic background process */
|
||||
/* ----------------------------------------------------- */
|
||||
int BSmakeServer(char** argv)
|
||||
{
|
||||
FILE* fd;
|
||||
|
||||
if(filename) return -1;
|
||||
|
||||
/* set up signal handling for the server */
|
||||
signal(SIGCHLD,get_child); /* for reaping children */
|
||||
signal(SIGHUP,catch_sig);
|
||||
signal(SIGINT,catch_sig);
|
||||
signal(SIGTERM,catch_sig);
|
||||
signal(SIGQUIT,catch_sig);
|
||||
|
||||
/* disconnect from parent */
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("Cannot fork");
|
||||
return -1;
|
||||
case 0: /* child */
|
||||
#if defined linux || defined SOLARIS
|
||||
setpgrp();
|
||||
#else
|
||||
setpgrp(0,0);
|
||||
#endif
|
||||
setsid();
|
||||
break;
|
||||
default: /* parent goes away */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* save process ID */
|
||||
filename=(char*)malloc(strlen(argv[0])+10);
|
||||
sprintf(filename,"%s.%d",argv[0],getpid());
|
||||
fd=fopen(filename,"w");
|
||||
fprintf(fd,"%d",getpid());
|
||||
fprintf(stderr,"\npv server pid: %d\n",getpid());
|
||||
fclose(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* server mode functions */
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
/* open a bulk data socket to a server given the server IP address */
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
BS* BSipOpen(char* address, int Port)
|
||||
{
|
||||
struct hostent* pHostent;
|
||||
unsigned long addr;
|
||||
BSDATA info;
|
||||
struct sockaddr_in* tsin;
|
||||
|
||||
tsin=(struct sockaddr_in*)&(info.sin);
|
||||
|
||||
#ifndef vxWorks
|
||||
/* Deal with the name -vs- IP number issue. */
|
||||
if (isdigit(address[0]))
|
||||
{
|
||||
#endif
|
||||
addr=inet_addr(address);
|
||||
#ifndef vxWorks
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pHostent=gethostbyname(address))==NULL) return NULL;
|
||||
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
tsin->sin_port=htons(Port);
|
||||
tsin->sin_family=AF_INET;
|
||||
memcpy((char*)&(tsin->sin_addr),(char*)&addr,sizeof(addr));
|
||||
|
||||
return BSipOpenData(&info);
|
||||
}
|
||||
|
||||
BS* BSipOpenData(BSDATA* info)
|
||||
{
|
||||
struct sockaddr_in tsin;
|
||||
int osoc;
|
||||
BS* bdt;
|
||||
|
||||
tsin.sin_port=0;
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((osoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
|
||||
{
|
||||
perror("BSipOpen: create socket failed");
|
||||
return (BS*)NULL;
|
||||
}
|
||||
|
||||
if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BSipOpen: local address bind failed");
|
||||
return (BS*)NULL;
|
||||
}
|
||||
|
||||
if(connect(osoc,(struct sockaddr*)&(info->sin),sizeof(info->sin))<0)
|
||||
{
|
||||
perror("BSipOpen: connect failed");
|
||||
close(osoc);
|
||||
return (BS*)NULL;
|
||||
}
|
||||
|
||||
bdt=(BS*)malloc(sizeof(BS));
|
||||
bdt->soc=osoc;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BSidle;
|
||||
|
||||
#ifndef vxWorks
|
||||
{
|
||||
int j;
|
||||
j = fcntl(bdt->soc, F_GETFL, 0);
|
||||
fcntl(bdt->soc, F_SETFL, j|O_NDELAY);
|
||||
}
|
||||
#endif
|
||||
/* now connected to the bulk data socket on the IOC */
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* write size bytes from buffer to socket */
|
||||
/* -------------------------------------- */
|
||||
int BSwrite(int soc,void* buffer,int size)
|
||||
{
|
||||
int rc;
|
||||
int total;
|
||||
unsigned char* data;
|
||||
fd_set fds;
|
||||
struct timeval to;
|
||||
|
||||
data=(unsigned char*)buffer;
|
||||
total=size;
|
||||
|
||||
to.tv_sec = 5;
|
||||
to.tv_usec = 0;
|
||||
|
||||
do
|
||||
{
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc, &fds);
|
||||
if(select(FD_SETSIZE,NULL,&fds,NULL,&to) != 1)
|
||||
{
|
||||
printf("BSwrite: timeout waiting to write data\n");
|
||||
return -1;
|
||||
}
|
||||
/* send block of data */
|
||||
if((rc=send(soc,(char*)&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno == EINTR)
|
||||
rc = 0;
|
||||
else
|
||||
perror("BSwrite: Send to remote failed");
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* send a message header down a BS socket */
|
||||
/* --------------------------------------- */
|
||||
int BSsendHeader(BS* bdt,unsigned short verb,int size)
|
||||
{
|
||||
BSmsgHead buf;
|
||||
|
||||
if(bdt->state!=BSidle)
|
||||
{
|
||||
fprintf(stderr,"BSsendHeader: Interface not idle\n");
|
||||
bdt->state=BSbad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf.verb=htons(verb);
|
||||
buf.size=htonl((unsigned long)size);
|
||||
|
||||
if(BSwrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BSsendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
if(BSwrite(bdt->soc,&buf.size, sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BSsendHeader: write to remote failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't wait for response if data must go out */
|
||||
if(size)
|
||||
{
|
||||
bdt->remaining_send=size;
|
||||
bdt->state=BSsData;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------- */
|
||||
/* send a message data chunk down a BS socket */
|
||||
/* ------------------------------------------- */
|
||||
int BSsendData(BS* bdt,void* buffer,int size)
|
||||
{
|
||||
int len;
|
||||
int remaining;
|
||||
int rc;
|
||||
|
||||
if(bdt->state!=BSsData)
|
||||
{
|
||||
fprintf(stderr,"BSsendData: Interface not in send data mode\n");
|
||||
bdt->state=BSbad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
remaining=bdt->remaining_send-size;
|
||||
|
||||
if(remaining<0)
|
||||
{
|
||||
fprintf(stderr,"WARNING -- BSsendData: To much data to send\n");
|
||||
len=bdt->remaining_send;
|
||||
}
|
||||
else
|
||||
len=size;
|
||||
|
||||
if (BSwrite(bdt->soc, buffer, len) < 0)
|
||||
return -1;
|
||||
|
||||
bdt->remaining_send-=len;
|
||||
|
||||
if(bdt->remaining_send<0)
|
||||
{
|
||||
fprintf(stderr,"BSsendData: To much data Sent\n");
|
||||
bdt->remaining_send=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_send==0)
|
||||
bdt->state=BSidle;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int BSflushOutput(BS* bdt)
|
||||
{
|
||||
#ifdef vxWorks
|
||||
ioctl(bdt->soc, FIOWFLUSH, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* Read exactly size bytes from remote */
|
||||
/* ------------------------------------- */
|
||||
int BSread(int soc,void* buffer,int size)
|
||||
{
|
||||
int rc,total;
|
||||
unsigned char* data;
|
||||
fd_set fds;
|
||||
struct timeval to;
|
||||
|
||||
to.tv_sec = 5;
|
||||
to.tv_usec = 0;
|
||||
|
||||
data=(unsigned char*)buffer;
|
||||
total=size;
|
||||
|
||||
do
|
||||
{
|
||||
#if 1
|
||||
/* wait for data chunk */
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc, &fds);
|
||||
if (select(soc+1, &fds, NULL, NULL, &to) != 1)
|
||||
{
|
||||
printf("BSread: timeout waiting for data\n");
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
if((rc=recv(soc,(char*)&data[size-total],total,0))<0)
|
||||
{
|
||||
if(errno==EINTR)
|
||||
{
|
||||
printf("BSread: EINTR");
|
||||
rc=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("BSread: Receive data chunk failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
total-=rc;
|
||||
}
|
||||
while(rc>0 && total>0);
|
||||
|
||||
return (rc<=0)?-1:0;
|
||||
}
|
||||
|
||||
/* ------------------------------------- */
|
||||
/* wait for a message header from remote */
|
||||
/* ------------------------------------- */
|
||||
int BSreceiveHeader(BS* bdt,int* verb,int* size)
|
||||
{
|
||||
BSmsgHead buf;
|
||||
|
||||
/* can only receive header when in the idle state */
|
||||
if (bdt->state == BSeof)
|
||||
return -1;
|
||||
|
||||
if(bdt->state != BSidle)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveHeader: Interface not idle\n");
|
||||
bdt->state=BSbad;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSread(bdt->soc,&buf.verb,sizeof(buf.verb))<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(BSread(bdt->soc,&buf.size,sizeof(buf.size))<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveHeader: Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy message data to user */
|
||||
*verb=ntohs(buf.verb);
|
||||
*size=ntohl(buf.size);
|
||||
|
||||
if(*size)
|
||||
bdt->state=BSrData;
|
||||
|
||||
bdt->remaining_recv=*size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Wait for a chunk of data from remote.
|
||||
User can continually call this with a maximum size until it return 0.
|
||||
------------------------------------------------------------------------ */
|
||||
int BSreceiveData(BS* bdt,void* buffer,int size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* can only receive data when in the receive data state */
|
||||
switch(bdt->state)
|
||||
{
|
||||
case BSrData: break;
|
||||
case BSidle: return 0;
|
||||
default:
|
||||
fprintf(stderr,"BSreceiveData: bad receive state\n");
|
||||
bdt->state=BSbad;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bdt->remaining_recv < size)
|
||||
size = bdt->remaining_recv;
|
||||
|
||||
if(BSread(bdt->soc,buffer,size)<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveData: Read failed\n");
|
||||
bdt->state = BSeof;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bdt->remaining_recv-=size;
|
||||
|
||||
if(bdt->remaining_recv<0)
|
||||
{
|
||||
fprintf(stderr,"BSreceiveData: To much data received\n");
|
||||
bdt->remaining_recv=0;
|
||||
}
|
||||
|
||||
if(bdt->remaining_recv==0)
|
||||
bdt->state=BSidle;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* -------------------- */
|
||||
/* close the connection */
|
||||
/* -------------------- */
|
||||
int BSclose(BS* bdt)
|
||||
{
|
||||
int verb,size,done;
|
||||
|
||||
/* send a close message out */
|
||||
if(BSsendHeader(bdt,BS_Close,0)<0)
|
||||
{
|
||||
fprintf(stderr,"BSclose: Cannot send close message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
done=0;
|
||||
|
||||
do
|
||||
{
|
||||
/* check response */
|
||||
if(BSreceiveHeader(bdt,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"BSclose: Close message response error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(verb)
|
||||
{
|
||||
case BS_Ok:
|
||||
done=1;
|
||||
break;
|
||||
case BS_Error:
|
||||
fprintf(stderr,"BSclose: Close rejected\n");
|
||||
return -1;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
while(done==0);
|
||||
|
||||
BSfreeBS(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for UDP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BSopenListenerUDP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
tsin.sin_port=htons(Port);
|
||||
tsin.sin_family=AF_INET;
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((nsoc=socket(AF_INET,SOCK_DGRAM,BS_UDP))<0)
|
||||
{
|
||||
perror("BSopenListenerUDP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BSopenListenerUDP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* make a listener socket for TCP - simple */
|
||||
/* --------------------------------------- */
|
||||
int BSopenListenerTCP(int Port)
|
||||
{
|
||||
int nsoc;
|
||||
struct sockaddr_in tsin;
|
||||
|
||||
memset ((void *)&tsin, 0, sizeof(struct sockaddr_in));
|
||||
tsin.sin_port=htons(Port);
|
||||
tsin.sin_family=htons(AF_INET);
|
||||
tsin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if((nsoc=socket(AF_INET,SOCK_STREAM,BS_TCP))<0)
|
||||
{
|
||||
perror("BSopenListenerTCP: open socket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0)
|
||||
{
|
||||
perror("BSopenListenerTCP: local bind failed");
|
||||
close(nsoc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen(nsoc,5);
|
||||
return nsoc;
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* make BS from a socket - simple */
|
||||
/* ------------------------------- */
|
||||
BS* BSmakeBS(int soc)
|
||||
{
|
||||
BS* bdt;
|
||||
bdt=(BS*)malloc(sizeof(BS));
|
||||
bdt->soc=soc;
|
||||
bdt->remaining_send=0;
|
||||
bdt->remaining_recv=0;
|
||||
bdt->state=BSidle;
|
||||
return bdt;
|
||||
}
|
||||
|
||||
/* --------------------------- */
|
||||
/* free a BS and close socket */
|
||||
/* --------------------------- */
|
||||
int BSfreeBS(BS* bdt)
|
||||
{
|
||||
close(bdt->soc);
|
||||
free(bdt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Next three function adjust the fields of the BSDATA structure.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
int BSgetAddressPort(BSDATA* info, char* ip_addr, int* dest_port)
|
||||
{
|
||||
char* name;
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
|
||||
|
||||
*dest_port=sin->sin_port;
|
||||
name=inet_ntoa(sin->sin_addr);
|
||||
strcpy(ip_addr,name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSsetAddressPort(BSDATA* info, char* ip_addr, int dest_port)
|
||||
{
|
||||
BSsetPort(info, dest_port);
|
||||
return BSsetAddress(info, ip_addr);
|
||||
}
|
||||
|
||||
int BSsetPort(BSDATA* info, int dest_port)
|
||||
{
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
|
||||
sin->sin_family=AF_INET;
|
||||
sin->sin_port=htons(dest_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSsetAddress(BSDATA* info, char* ip_addr)
|
||||
{
|
||||
struct hostent *pHostent;
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&(info->sin);
|
||||
unsigned long addr;
|
||||
|
||||
#ifndef vxWorks
|
||||
/* Deal with the name -vs- IP number issue. */
|
||||
if (isdigit(ip_addr[0]))
|
||||
{
|
||||
#endif
|
||||
if((addr=inet_addr(ip_addr))==-1) return -1;
|
||||
#ifndef vxWorks
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pHostent=gethostbyname(ip_addr))==NULL) return -1;
|
||||
memcpy((char*)&addr,pHostent->h_addr,sizeof(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
sin->sin_family=AF_INET;
|
||||
memcpy((char*)&(sin->sin_addr),(char*)&addr,sizeof(addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/*
|
||||
All this function does is send a broadcast message and return the
|
||||
addressing info to the caller of a responder to the broadcast.
|
||||
|
||||
arguments:
|
||||
soc - broadcast socket to use for sending data
|
||||
trys - number of times to send if no response
|
||||
o_info - outgoing BSDATA, address/port info
|
||||
i_info - incoming BSDATA, address/port where response came from
|
||||
omsg/osize - outgoing message and size
|
||||
imsg/isize - incoming message and buffer size
|
||||
|
||||
Returns the number of bytes read.
|
||||
*/
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
|
||||
void* omsg,int osize,void* imsg,int isize)
|
||||
{
|
||||
int i;
|
||||
int rc=0;
|
||||
|
||||
for(i=0;rc==0 && i<trys;i++)
|
||||
{
|
||||
/* send out the message */
|
||||
rc=BSwriteUDP(soc,o_info,omsg,osize);
|
||||
if(rc<0) return rc;
|
||||
|
||||
/* wait for a response */
|
||||
rc=BSreadUDP(soc,i_info,1,imsg,isize);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int BSbroadcast(int soc,BSDATA* o_info, void* omsg,int osize)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* send out the message */
|
||||
rc=BSwriteUDP(soc,o_info,omsg,osize);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*
|
||||
This function waits for a message and sends out an ACK when it gets one.
|
||||
addressing info to the caller of a responder to the broadcast.
|
||||
|
||||
Lots of arguments:
|
||||
|
||||
soc - The socket to send the message down.
|
||||
info - The socket information telling where the data read came from
|
||||
(returned to the user).
|
||||
tout - Timeout for read in seconds. 0=no wait, -1=wait forever.
|
||||
buf - Buffer to populate with read data.
|
||||
size - Size of the buf.
|
||||
|
||||
returns the length the read message, 0 is timeout, -1 is error
|
||||
*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size)
|
||||
{
|
||||
int mlen,rc;
|
||||
fd_set fds;
|
||||
struct timeval to;
|
||||
int error=0;
|
||||
|
||||
do
|
||||
{
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc, &fds);
|
||||
|
||||
if(tout==-1)
|
||||
rc=select(FD_SETSIZE,&fds,NULL,NULL,NULL);
|
||||
else
|
||||
{
|
||||
to.tv_sec=tout;
|
||||
to.tv_usec=0;
|
||||
rc=select(FD_SETSIZE,&fds,NULL,NULL,&to);
|
||||
}
|
||||
|
||||
switch(rc)
|
||||
{
|
||||
case -1: /* bad */
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR: break;
|
||||
default: error=-1; break;
|
||||
}
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
break;
|
||||
default: /* data ready */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(rc<0 && error==0);
|
||||
|
||||
error=0;
|
||||
|
||||
if(rc>0)
|
||||
{
|
||||
error=0;
|
||||
do
|
||||
{
|
||||
info->len=sizeof(info->sin);
|
||||
mlen=recvfrom(soc,(char*)buf,size,0, &info->sin,&info->len);
|
||||
|
||||
if(mlen<0)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR: break;
|
||||
default: error=-1; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(mlen<0 && error==0);
|
||||
|
||||
if(mlen<0)
|
||||
rc=-1;
|
||||
else
|
||||
rc=mlen;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Write a chuck of data to a UDP socket at an internet address
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSwriteDataUDP(int soc,int dest_port,char* ip_addr,void* buf,int size)
|
||||
{
|
||||
BSDATA data;
|
||||
|
||||
BSsetAddress(&data,ip_addr);
|
||||
BSsetPort(&data,dest_port);
|
||||
|
||||
return BSwriteUDP(soc,&data,buf,size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Write a chunk of data to a UDP socket using BSDATA.
|
||||
Arguments:
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize)
|
||||
{
|
||||
int mlen;
|
||||
|
||||
mlen=sendto(soc,(char*)obuf,osize,0,&info->sin,sizeof(info->sin));
|
||||
|
||||
return mlen;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Write/Read a chuck of data to a UDP socket using BSDATA.
|
||||
Arguments:
|
||||
soc - socket to send message down and read from
|
||||
info - address/port to send message to
|
||||
obuf/osize - outgoing message and size of it.
|
||||
ibuf/isize - incoming message and size of the buffer.
|
||||
|
||||
Returns the number of bytes read, -1 for error.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize)
|
||||
{
|
||||
int done,i,mlen,flen;
|
||||
struct sockaddr fromsin;
|
||||
fd_set fds;
|
||||
struct timeval tout;
|
||||
|
||||
done=0;
|
||||
mlen=0;
|
||||
|
||||
for(i=0;i<BS_RETRY_COUNT && done==0;i++)
|
||||
{
|
||||
mlen=sendto(soc,(char*)obuf,osize,0,&(info->sin),sizeof(info->sin));
|
||||
if(mlen<0)
|
||||
{
|
||||
printf("send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tout.tv_sec=0;
|
||||
tout.tv_usec=200000;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(soc,&fds);
|
||||
|
||||
switch(select(FD_SETSIZE,&fds,(fd_set*)0,(fd_set*)0,&tout))
|
||||
{
|
||||
case 0: /* timeout */ break;
|
||||
case -1: /* error */
|
||||
printf("select failed\n");
|
||||
return -1;
|
||||
default: /* data ready */
|
||||
flen=sizeof(fromsin);
|
||||
mlen=recvfrom(soc,(char*)ibuf,isize,0,&fromsin,&flen);
|
||||
if(mlen<0) return -1;
|
||||
done=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i>=BS_RETRY_COUNT) return 0;
|
||||
|
||||
return mlen;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
Open a broadcast socket and set port to a default.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSipBroadcastOpen(BSDATA* info, int default_dest_port)
|
||||
{
|
||||
struct sockaddr_in* sin;
|
||||
int soc;
|
||||
|
||||
sin=(struct sockaddr_in*)&(info->sin);
|
||||
|
||||
if( (soc=BSgetBroadcastSocket(0,sin)) <0) return -1;
|
||||
|
||||
sin->sin_port=htons(default_dest_port);
|
||||
|
||||
return soc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
BSgetBroadcastSocket() - return a broadcast socket for a port, return
|
||||
a sockaddr also.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin)
|
||||
{
|
||||
int on=1;
|
||||
int soc;
|
||||
BS bs;
|
||||
|
||||
sin->sin_port=htons(port);
|
||||
sin->sin_family=AF_INET;
|
||||
sin->sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
|
||||
if( (soc=socket(AF_INET,SOCK_DGRAM,BS_UDP)) < 0 )
|
||||
{
|
||||
perror("socket create failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
setsockopt(soc,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on));
|
||||
|
||||
if( bind(soc,(struct sockaddr*)sin,sizeof(struct sockaddr_in)) < 0 )
|
||||
{
|
||||
perror("socket bind failed");
|
||||
close(soc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( BSgetBroadcastAddr(soc,(struct sockaddr*)sin) < 0 )
|
||||
return -1;
|
||||
|
||||
return soc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*
|
||||
BSgetBroadcastAddr() - Determine the broadcast address, this is
|
||||
directly from the Sun Network Programmer's guide.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static long BSgetBroadcastAddr(int soc, struct sockaddr* sin)
|
||||
{
|
||||
struct ifconf ifc;
|
||||
struct ifreq* ifr;
|
||||
struct ifreq* save;
|
||||
char buf[BUFSIZ];
|
||||
int tot,i;
|
||||
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if(ioctl(soc,SIOCGIFCONF,(int)&ifc) < 0)
|
||||
{ perror("ioctl SIOCGIFCONF failed"); return -1; }
|
||||
|
||||
ifr = ifc.ifc_req;
|
||||
tot = ifc.ifc_len/sizeof(struct ifreq);
|
||||
save=(struct ifreq*)NULL;
|
||||
i=0;
|
||||
|
||||
do
|
||||
{
|
||||
if(ifr[i].ifr_addr.sa_family==AF_INET)
|
||||
{
|
||||
if(ioctl(soc,SIOCGIFFLAGS,(int)&ifr[i])<0)
|
||||
{ perror("ioctl SIOCGIFFLAGS failed"); return -1; }
|
||||
|
||||
if( (ifr[i].ifr_flags&IFF_UP) &&
|
||||
!(ifr[i].ifr_flags&IFF_LOOPBACK) &&
|
||||
(ifr[i].ifr_flags&IFF_BROADCAST))
|
||||
{ save=&ifr[i]; }
|
||||
}
|
||||
} while( !save && ++i<tot );
|
||||
|
||||
if(save)
|
||||
{
|
||||
if(ioctl(soc,SIOCGIFBRDADDR,(int)save)<0)
|
||||
{ perror("ioctl SIOCGIFBRDADDR failed"); return -1; }
|
||||
|
||||
memcpy((char*)sin,(char*)&save->ifr_broadaddr,
|
||||
sizeof(save->ifr_broadaddr));
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
188
src/dbtools/BSlib.h
Normal file
188
src/dbtools/BSlib.h
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef ___BS_H
|
||||
#define ___BS_H
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jim Kowalkowski
|
||||
Date: 9/1/95
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* got from protocols(5) (cheated) or /etc/protocols */
|
||||
#define BS_UDP 17
|
||||
#define BS_TCP 6
|
||||
|
||||
/* server ports - in the user reserved area - above 50000 */
|
||||
#define BS_UDP_PORT 50296
|
||||
#define BS_TCP_PORT 50297
|
||||
|
||||
/* message types */
|
||||
#define BS_Ok 0
|
||||
#define BS_Error 1
|
||||
#define BS_Close 2
|
||||
#define BS_Ping 3
|
||||
#define BS_Done 4
|
||||
|
||||
#define BS_LAST_VERB 4
|
||||
#define BS_RETRY_COUNT 3
|
||||
|
||||
/* protocol states */
|
||||
typedef enum { BSidle,BSunbound,BSsData,BSrData,BSbad,BSeof } BSstate;
|
||||
|
||||
struct bs
|
||||
{
|
||||
int soc;
|
||||
int remaining_send;
|
||||
int remaining_recv;
|
||||
BSstate state;
|
||||
};
|
||||
typedef struct bs BS;
|
||||
|
||||
struct bs_udp_data
|
||||
{
|
||||
struct sockaddr sin;
|
||||
int len;
|
||||
};
|
||||
typedef struct bs_udp_data BSDATA;
|
||||
|
||||
struct BSmsgHead
|
||||
{
|
||||
unsigned short verb;
|
||||
unsigned long size;
|
||||
};
|
||||
typedef struct BSmsgHead BSmsgHead;
|
||||
|
||||
typedef unsigned long BS_ULONG;
|
||||
|
||||
#define BSgetSocket(BS) (BS->soc)
|
||||
#define BSgetResidualWrite(BS) (BS->remaining_send)
|
||||
#define BSgetResidualRead(BS) (BS->remaining_recv)
|
||||
#define BSgetProtoState(BS) (BS->state)
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Server functions:
|
||||
|
||||
BSopenListenerTCP:
|
||||
Open a socket locally bound to the bulk data transfer TCP server port.
|
||||
Set the socket up as a listener. Return the open socket.
|
||||
|
||||
BSopenListenerUDP:
|
||||
Open a socket locally bound to the bulk data transfer UDP server port.
|
||||
Return the open socket.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
int BSopenListenerTCP(int Port);
|
||||
int BSopenListenerUDP(int Port);
|
||||
int BSopenTCP(BSDATA*);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Utilities functions:
|
||||
|
||||
BSmakeServer:
|
||||
Available under unix only. Put process in the background, disassociate
|
||||
process from controlling terminal and parent process, and prepare
|
||||
signals for reaping children spawned by the process.
|
||||
|
||||
BSserverClearSignals:
|
||||
Clear the signal handlers for a process, set them to default.
|
||||
|
||||
BSmakeBS:
|
||||
Allocate and initialize a BS from a socket.
|
||||
|
||||
BSfreeBS:
|
||||
Close the open socket and free the memory for the BS.
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef vxWorks
|
||||
int BSmakeServer(char** argv);
|
||||
int BSserverClearSignals();
|
||||
#endif
|
||||
|
||||
BS* BSmakeBS(int socket); /* make a BS from a socket */
|
||||
int BSfreeBS(BS* bdt); /* free a BS */
|
||||
|
||||
int BSgetBroadcastSocket(int port, struct sockaddr_in* sin);
|
||||
int BSipBroadcastOpen(BSDATA* info, int default_dest_port);
|
||||
int BSgetAddressPort(BSDATA* info,char* ip_addr, int* dest_port);
|
||||
int BSsetAddressPort(BSDATA* info,char* ip_addr, int dest_port);
|
||||
int BSsetAddress(BSDATA* info,char* ip_addr);
|
||||
int BSsetPort(BSDATA* info,int dest_port);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
UDP functions:
|
||||
------------------------------------------------------------------------ */
|
||||
int BStransUDP(int soc,BSDATA* info,void* obuf,int osize,void* ibuf,int isize);
|
||||
int BSwriteUDP(int soc,BSDATA* info,void* obuf,int osize);
|
||||
int BSwriteDataUDP(int soc,int dest_port, char* ip_addr,void* obuf,int osize);
|
||||
int BSreadUDP(int soc,BSDATA* info,BS_ULONG tout,void* buf,int size);
|
||||
int BSbroadcast(int soc,BSDATA* info,void* buf,int size);
|
||||
int BSbroadcastTrans(int soc,int trys,BSDATA* o_info,BSDATA* i_info,
|
||||
void* obuf,int osize,void* ibuf,int isize);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Client functions:
|
||||
|
||||
BSipOpen:
|
||||
Open a connection to an bulk data transfer given the IP address of the
|
||||
machine where the server exists. The returned BS is returned unbound,
|
||||
a connect must be issued before data transactions can take place.
|
||||
|
||||
BSclose:
|
||||
Completely close a connection to a server and free the BS.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
BS* BSipOpen(char* address, int port);
|
||||
BS* BSipOpenData(BSDATA* info);
|
||||
int BSclose(BS* bdt);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Client and Server shared functions:
|
||||
|
||||
BSsendHeader:
|
||||
Send a message header out to a connect BS with command and message body
|
||||
size information.
|
||||
|
||||
BSsendData:
|
||||
Send a portion or all the message body out a connected BS. A header
|
||||
must have previously been sent with length information. The interface
|
||||
will only allow the amount of data specified in the header to be sent.
|
||||
|
||||
BSwrite:
|
||||
This call will block until all the data specified in the size parameter
|
||||
are sent down the socket.
|
||||
|
||||
BSread:
|
||||
This call will block until all the data specified in the size parameter
|
||||
is read from the socket.
|
||||
|
||||
BSreceiveHeader:
|
||||
Wait until a message header appears at the BS, return the action and
|
||||
remaining message body size.
|
||||
|
||||
BSreceiveData:
|
||||
Wait for a chunk or the entire body of a message to appear at the BS.
|
||||
Put the data into the buffer for a maximum size. Return the amount of
|
||||
data actually received, or zero if there is no data remaining for the
|
||||
current message.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
int BSsendHeader(BS* bdt, unsigned short verb, int size);
|
||||
int BSsendData(BS* bdt, void* buffer, int size);
|
||||
int BSreceiveHeader(BS* bdt, int* verb, int* size);
|
||||
int BSreceiveData(BS* bdt, void* buffer, int size);
|
||||
int BSread(int socket, void* buffer, int size);
|
||||
int BSwrite(int socket, void* buffer, int size);
|
||||
int BSflushOutput(BS* bdt);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,29 +2,45 @@ EPICS = ../../../..
|
||||
include Target.include
|
||||
include $(EPICS)/config/CONFIG_BASE
|
||||
|
||||
# USR_CFLAGS = -v
|
||||
|
||||
LEX = $(ELEX)
|
||||
YACC = $(EYACC)
|
||||
YACCOPT = -l
|
||||
LEXOPT = -L
|
||||
|
||||
SRCS.c = ../dbVarSub.c dbLoadTemplate_lex.c dbLoadTemplate.c \
|
||||
dbLoadRecords_lex.c dbLoadRecords.c
|
||||
dbLoadRecords_lex.c dbLoadRecords.c \
|
||||
../BSlib.c ../PVSserver.c ../rdbapplist.c ../rdbls.o
|
||||
|
||||
OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
VAR_OBJS = dbVarSub.o dbLoadTemplate.o dbLoadRecords.o
|
||||
OBJS = $(VAR_OBJS) BSlib.o PVSserver.o rdbapplist.o rdbls.o
|
||||
|
||||
PROD = subtool dbLoadTemplate
|
||||
PROD = subtool dbLoadTemplate rdbls rdbapplist
|
||||
TARGETS = PVSserver
|
||||
|
||||
include $(EPICS)/config/RULES.Unix
|
||||
|
||||
dbLoadTemplate.o: dbLoadTemplate_lex.c
|
||||
dbLoadRecords.o: dbLoadRecords_lex.c
|
||||
|
||||
subtool: dbLoadTemplate.c dbLoadTemplate_lex.c dbVarSub.o
|
||||
$(RM) $@
|
||||
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o subtool dbLoadTemplate.c dbVarSub.o -s
|
||||
PVSserver: PVSserver.o BSlib.o
|
||||
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
dbLoadTemplate: $(OBJS)
|
||||
$(LINK.c) -o $@ $(OBJS) $(LDLIBS) -lDb
|
||||
rdbls: rdbls.o BSlib.o
|
||||
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
rdbapplist: rdbapplist.o BSlib.o
|
||||
$(LINK.c) $(ARCH_DEP_LDLIBS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
subtool.o: dbLoadTemplate.c dbLoadTemplate_lex.c
|
||||
$(COMPILE.c) $(CFLAGS) -DSUB_TOOL -o $@ $<
|
||||
|
||||
subtool: subtool.o dbVarSub.o
|
||||
$(LINK.c) $(CFLAGS) -DSUB_TOOL -o $@ $^ -s
|
||||
|
||||
dbLoadTemplate: $(VAR_OBJS)
|
||||
$(LINK.c) -o $@ $^ $(LDLIBS) -lDb
|
||||
|
||||
clean::
|
||||
@$(RM) dbLoadTemplate_lex.c dbLoadTemplate.c dbLoadRecords_lex.c \
|
||||
|
||||
@@ -8,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
31
src/dbtools/PVS.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef __PVS_H
|
||||
#define __PVS_H
|
||||
|
||||
#include "BSlib.h"
|
||||
|
||||
#define PVS_RETRY_COUNT 4
|
||||
#define PVS_TRANSFER_SIZE 1024
|
||||
#define PVS_UDP 17
|
||||
#define PVS_TCP 6
|
||||
#define PVS_UDP_PORT 50298
|
||||
#define PVS_TCP_PORT 50299
|
||||
#define PVS_UDP_CPORT 50300
|
||||
|
||||
#define PVS_Data (BS_LAST_VERB+1)
|
||||
#define PVS_Alive (BS_LAST_VERB+2)
|
||||
#define PVS_RecList (BS_LAST_VERB+3)
|
||||
#define PVS_AppList (BS_LAST_VERB+4)
|
||||
#define PVS_RecDump (BS_LAST_VERB+5)
|
||||
|
||||
#define PVS_LAST_VERB PVS_RecDump
|
||||
|
||||
struct pvs_info_packet
|
||||
{
|
||||
unsigned short cmd;
|
||||
char text[90];
|
||||
};
|
||||
typedef struct pvs_info_packet PVS_INFO_PACKET;
|
||||
|
||||
#define PVS_SET_CMD(pvs_info,command) (pvs_info)->cmd=htons(command)
|
||||
|
||||
#endif
|
||||
263
src/dbtools/PVSserver.c
Normal file
263
src/dbtools/PVSserver.c
Normal file
@@ -0,0 +1,263 @@
|
||||
|
||||
/* only runable on work station now */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct PVSnode
|
||||
{
|
||||
BSDATA info;
|
||||
int alive;
|
||||
struct PVSnode* next;
|
||||
};
|
||||
typedef struct PVSnode PVSNODE;
|
||||
|
||||
static PVSNODE* ioc_list = (PVSNODE*)NULL;
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname);
|
||||
|
||||
#ifndef PVS_SERVER_PROG
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
BSDATA info;
|
||||
int serv;
|
||||
int rc;
|
||||
|
||||
if(argc<4)
|
||||
{
|
||||
fprintf(stderr,"usage: %s IOC-name server-number [server-name]\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
serv=atoi(argv[2]);
|
||||
BSsetAddress(&info,argv[1]);
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rc=read_pvs(&info,serv,argv[3]);
|
||||
else
|
||||
rc=read_pvs(&info,serv,(char*)NULL);
|
||||
|
||||
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
int soc,mlen;
|
||||
unsigned short buf,in_buf,ping;
|
||||
BSDATA info;
|
||||
PVSNODE* node;
|
||||
|
||||
if(BSmakeServer(argv)<0)
|
||||
{
|
||||
fprintf(stderr,"Cannot make into a server\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((soc=BSopenListenerUDP(PVS_UDP_PORT))<0)
|
||||
{
|
||||
fprintf(stderr,"Open of UDP listener socket failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf=htons(BS_Ok); /* always sends this out */
|
||||
ping=htons(BS_Ping); /* always sends this out */
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* wait forever until a message comes in */
|
||||
|
||||
mlen=BSreadUDP(soc,&info,7,&in_buf,sizeof(in_buf));
|
||||
|
||||
/* check for errors */
|
||||
switch(mlen)
|
||||
{
|
||||
case 0: /* timeout */
|
||||
printf("Why did a timeout occur?\n");
|
||||
/* send out a ping to each of the IOCs in the ioc_list */
|
||||
for(node=ioc_list;node;node=node->next)
|
||||
{
|
||||
mlen=BStransUDP(soc,&(node->info),&ping,sizeof(ping),
|
||||
&in_buf,sizeof(in_buf));
|
||||
|
||||
/* check for errors */
|
||||
switch(mlen)
|
||||
{
|
||||
case 0: /* timeout */
|
||||
printf("IOC dead\n");
|
||||
node->alive=0;
|
||||
break;
|
||||
case -1: /* error */
|
||||
printf("Communications failed\n");
|
||||
break;
|
||||
default: /* ok */
|
||||
if(node->alive==0)
|
||||
{
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("fork failure");
|
||||
break;
|
||||
case 0: /* child */
|
||||
close(soc);
|
||||
BSserverClearSignals();
|
||||
sleep(1);
|
||||
if(read_pvs(&(node->info))==0)
|
||||
node->alive=1;
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case -1: /* error */
|
||||
fprintf(stderr,"Communications failure\n");
|
||||
break;
|
||||
default: /* ok */
|
||||
if(BSwriteUDP(soc,&info,&buf,sizeof(buf))<0)
|
||||
fprintf(stderr,"respone send failed\n");
|
||||
else
|
||||
{
|
||||
node=(PVSNODE*)malloc(sizeof(PVSNODE));
|
||||
node->alive=1;
|
||||
node->info=info;
|
||||
BSsetPort(&(node->info),PVS_UDP_CPORT);
|
||||
node->next=ioc_list;
|
||||
ioc_list=node;
|
||||
|
||||
switch(fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
perror("fork failure");
|
||||
break;
|
||||
case 0: /* child */
|
||||
close(soc);
|
||||
BSserverClearSignals();
|
||||
sleep(1);
|
||||
return read_pvs(&info,PVS_RecList,NULL);
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(soc);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname)
|
||||
{
|
||||
BS* bs;
|
||||
int verb,size,done,len,i,port,rsize;
|
||||
char* buffer;
|
||||
char ip_from[40];
|
||||
FILE* fd;
|
||||
|
||||
BSgetAddressPort(info,ip_from,&port);
|
||||
|
||||
/* printf("IOC %s starting\n",ip_from); */
|
||||
|
||||
/* verify ioc not already added */
|
||||
if(access(ip_from,F_OK)==0)
|
||||
{
|
||||
/* delete the existing file for this IOC */
|
||||
unlink(ip_from);
|
||||
}
|
||||
|
||||
done=0;
|
||||
BSsetPort(info,PVS_TCP_PORT);
|
||||
|
||||
if((bs=BSipOpenData(info))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of socket to IOC failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rsize=strlen(sname)+1;
|
||||
else
|
||||
rsize=0;
|
||||
|
||||
if(BSsendHeader(bs,serv,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"Command send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rsize>0)
|
||||
{
|
||||
if(BSsendData(bs,sname,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"send of command name failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PVS_SERVER_PROG
|
||||
if((fd=fopen(ip_from,"w"))==(FILE*)NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of name file failed\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
fd=stdout;
|
||||
#endif
|
||||
|
||||
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
|
||||
|
||||
while(done==0)
|
||||
{
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"Receive header failed\n");
|
||||
done=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_Data: /* read a block of names */
|
||||
if((len=BSreceiveData(bs,buffer,size))<0)
|
||||
{
|
||||
fprintf(stderr,"Receive data failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
if(buffer[i]==' ') buffer[i]='\n';
|
||||
}
|
||||
buffer[len]='\n';
|
||||
buffer[len+1]='\0';
|
||||
|
||||
fputs(buffer,fd);
|
||||
}
|
||||
break;
|
||||
case BS_Done: /* transfers complete */
|
||||
BSclose(bs);
|
||||
done=-1;
|
||||
break;
|
||||
default:
|
||||
if(size>0) done=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PVS_SERVER_PROG
|
||||
fclose(fd);
|
||||
#endif
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
361
src/dbtools/PVSvx.c
Normal file
361
src/dbtools/PVSvx.c
Normal file
@@ -0,0 +1,361 @@
|
||||
|
||||
/* This file not really set up to run under Unix yet, just under vxWorks. */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <taskLib.h>
|
||||
#include <sysSymTbl.h>
|
||||
#include <sysLib.h>
|
||||
#include <symLib.h>
|
||||
#include <dbStaticLib.h>
|
||||
|
||||
extern struct dbBase *pdbBase;
|
||||
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static void PVSserver(int want_annouce,char* name);
|
||||
static int PVSannouce(int want_annouce,char* name);
|
||||
static void handle_requests(BS* bs);
|
||||
static void handle_reclist(BS* bs);
|
||||
static void handle_applist(BS* bs);
|
||||
static void handle_recdump(BS* bs);
|
||||
static void handle_spylist(BS* bs);
|
||||
static void handle_tasklist(BS* bs);
|
||||
void PVS_test_server(BS* bs);
|
||||
|
||||
static char* names = (char*)NULL;
|
||||
static char* buffer = (char*)NULL;
|
||||
|
||||
#ifdef vxWorks
|
||||
int PVSstart(int want_annouce, char* name)
|
||||
#else
|
||||
int main(int argc,char** argv)
|
||||
#endif
|
||||
{
|
||||
#ifndef vxWorks
|
||||
char* name;
|
||||
int want_annouce;
|
||||
#endif
|
||||
|
||||
#ifndef vxWorks
|
||||
if(argc<3)
|
||||
{
|
||||
fprintf(stderr,"bad args\n");
|
||||
fprintf(stderr," usage: %s a_flag host_name\n",
|
||||
argv[0]);
|
||||
fprintf(stderr," where\n");
|
||||
fprintf(stderr," a_flag=0(want),1(don't want) to annouce boot\n");
|
||||
fprintf(stderr," host_name=PV master host (if one exists)\n");
|
||||
return -1;
|
||||
}
|
||||
name=argv[2];
|
||||
if(sscanf(argv[1],"%d",&want_annouce)<1)
|
||||
{
|
||||
fprintf(stderr,"bad a_flag\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
taskSpawn("PVS",150,VX_FP_TASK|VX_STDIO,5000,
|
||||
(FUNCPTR)PVSserver,want_annouce,(int)name,0,0,0,0,0,0,0,0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PVSannouce(int want_annouce,char* name)
|
||||
{
|
||||
int soc,mlen;
|
||||
PVS_INFO_PACKET buf,in_buf;
|
||||
BSDATA info,in_info;
|
||||
|
||||
if(want_annouce==0 && name)
|
||||
{
|
||||
if((soc=BSopenListenerUDP(0))<0)
|
||||
{
|
||||
printf("Open of UDP socket failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSsetAddressPort(&info,name,PVS_UDP_PORT)<0)
|
||||
{
|
||||
printf("Set send port failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PVS_SET_CMD(&buf,PVS_Alive);
|
||||
mlen=BStransUDP(soc,&info,&buf,sizeof(buf),&in_buf,sizeof(in_buf));
|
||||
|
||||
/* check for errors */
|
||||
switch(mlen)
|
||||
{
|
||||
case 0: /* timeout */
|
||||
printf("No server running on host\n");
|
||||
break;
|
||||
case -1: /* error */
|
||||
printf("Communications failed\n");
|
||||
break;
|
||||
default: /* ok */
|
||||
break;
|
||||
}
|
||||
|
||||
close(soc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PVSserver(int want_annouce,char* name)
|
||||
{
|
||||
fd_set fds,rfds;
|
||||
int tsoc,usoc,nsoc,len,s;
|
||||
struct sockaddr stemp;
|
||||
int stemp_len;
|
||||
PVS_INFO_PACKET buf;
|
||||
BSDATA info;
|
||||
BS* bs;
|
||||
|
||||
bs=(BS*)NULL;
|
||||
buffer=(char*)malloc(100); /* just make the buffer */
|
||||
names=(char*)malloc(PVS_TRANSFER_SIZE);
|
||||
|
||||
if((tsoc=BSopenListenerTCP(PVS_TCP_PORT))<0)
|
||||
{
|
||||
printf("PVSserver: Open of TCP listener socket failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if((usoc=BSopenListenerUDP(PVS_UDP_CPORT))<0)
|
||||
{
|
||||
printf("PVSserver: Open of UDP listener socket failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(tsoc,&fds);
|
||||
FD_SET(usoc,&fds);
|
||||
|
||||
PVSannouce(want_annouce,name);
|
||||
|
||||
while(1)
|
||||
{
|
||||
rfds=fds;
|
||||
if(select(FD_SETSIZE,&rfds,(fd_set*)NULL,(fd_set*)NULL,
|
||||
(struct timeval*)NULL)<0)
|
||||
{
|
||||
printf("PVSserver: Select failure\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(FD_ISSET(tsoc,&rfds))
|
||||
{
|
||||
/* handle the request here - single threaded server */
|
||||
|
||||
stemp_len=sizeof(stemp);
|
||||
if((nsoc=accept(tsoc,&stemp,&stemp_len))<0)
|
||||
printf("PVSserver: Bad accept\n");
|
||||
else
|
||||
{
|
||||
bs=BSmakeBS(nsoc);
|
||||
handle_requests(bs);
|
||||
BSfreeBS(bs);
|
||||
}
|
||||
}
|
||||
if(FD_ISSET(usoc,&rfds))
|
||||
{
|
||||
/* only pings will come in here for now */
|
||||
len=BSreadUDP(usoc,&info,0,&buf,sizeof(buf));
|
||||
if(len<=0)
|
||||
printf("PVSserver: UDP listener read failure\n");
|
||||
else
|
||||
{
|
||||
if(BSwriteUDP(usoc,&info,&buf,sizeof(buf))<0)
|
||||
printf("PVSserver: UDP listener ping write failure\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_reclist(BS* bs)
|
||||
{
|
||||
DBENTRY db;
|
||||
long rc;
|
||||
char* n;
|
||||
unsigned long names_len;
|
||||
int s;
|
||||
|
||||
dbInitEntry(pdbBase,&db);
|
||||
names_len=0;
|
||||
|
||||
for(rc=dbFirstRecdes(&db);rc==0;rc=dbNextRecdes(&db))
|
||||
{
|
||||
for(rc=dbFirstRecord(&db);rc==0;rc=dbNextRecord(&db))
|
||||
{
|
||||
/* collect the names util we excede the max */
|
||||
n=dbGetRecordName(&db);
|
||||
s=strlen(n);
|
||||
if((names_len+s)>PVS_TRANSFER_SIZE)
|
||||
{
|
||||
names[names_len++]='\0';
|
||||
if(BSsendHeader(bs,PVS_Data,names_len)<0)
|
||||
printf("PVSserver: data cmd failed\n");
|
||||
else
|
||||
{
|
||||
if(BSsendData(bs,names,names_len)<0)
|
||||
printf("PVSserver: data send failed\n");
|
||||
}
|
||||
names_len=0;
|
||||
}
|
||||
memcpy(&names[names_len],n,s);
|
||||
names_len+=s;
|
||||
names[names_len++]=' ';
|
||||
}
|
||||
}
|
||||
if(names_len>0)
|
||||
{
|
||||
names[names_len++]='\0';
|
||||
if(BSsendHeader(bs,PVS_Data,names_len)<0)
|
||||
printf("PVSserver: data cmd failed\n");
|
||||
else
|
||||
{
|
||||
if(BSsendData(bs,names,names_len)<0)
|
||||
printf("PVSserver: data send failed\n");
|
||||
}
|
||||
}
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
static void handle_requests(BS* bs)
|
||||
{
|
||||
int verb,size,notdone,len;
|
||||
void (*func)(BS*);
|
||||
SYM_TYPE stype;
|
||||
|
||||
notdone=1;
|
||||
while(notdone)
|
||||
{
|
||||
/* at this point I should be getting a command */
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
printf("PVSserver: receive header failed\n");
|
||||
notdone=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_RecList: handle_reclist(bs); break;
|
||||
case PVS_AppList: handle_applist(bs); break;
|
||||
case PVS_RecDump: handle_recdump(bs); break;
|
||||
case BS_Close:
|
||||
BSsendHeader(bs,BS_Ok,0);
|
||||
notdone=0;
|
||||
break;
|
||||
case PVS_Data: break;
|
||||
case PVS_Alive: break;
|
||||
case BS_Ok: break;
|
||||
case BS_Error: break;
|
||||
case BS_Ping: break;
|
||||
case BS_Done: break;
|
||||
default:
|
||||
/* custom service */
|
||||
if(size>0)
|
||||
{
|
||||
/* this should be the name of the service */
|
||||
/* look up the symbol name in buffer and call as
|
||||
subroutine, passing it the BS */
|
||||
|
||||
len=BSreceiveData(bs,&buffer[1],size);
|
||||
switch(len)
|
||||
{
|
||||
case 0: /* timeout */ notdone=0; break;
|
||||
case -1: /* error */ notdone=0; break;
|
||||
default:
|
||||
buffer[0]='_';
|
||||
|
||||
if(strncmp(buffer,"_PVS",4)==0)
|
||||
{
|
||||
if(symFindByName(sysSymTbl,buffer,
|
||||
(char**)&func,&stype)==ERROR)
|
||||
func=(void (*)(BS*))NULL;
|
||||
|
||||
if(func)
|
||||
func(bs);
|
||||
else
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
else
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("PVSserver: unknown command received\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
struct dbnode
|
||||
{
|
||||
char* name;
|
||||
struct dbnode* next;
|
||||
};
|
||||
typedef struct dbnode DBNODE;
|
||||
|
||||
extern DBNODE* DbApplList;
|
||||
|
||||
void handle_applist(BS* bs)
|
||||
{
|
||||
DBNODE* n;
|
||||
int size,len;
|
||||
|
||||
len=0;
|
||||
for(n=DbApplList;n;n=n->next)
|
||||
{
|
||||
len=strlen(n->name)+1;
|
||||
|
||||
if(BSsendHeader(bs,PVS_Data,len)<0)
|
||||
printf("PVSserver: data cmd failed\n");
|
||||
else
|
||||
{
|
||||
if(BSsendData(bs,n->name,len)<0)
|
||||
printf("PVSserver: data send failed\n");
|
||||
}
|
||||
}
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
void handle_recdump(BS* bs)
|
||||
{
|
||||
printf("RecDump server invoked\n");
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
void PVS_test_server(BS* bs)
|
||||
{
|
||||
printf("PVS_test_server invoked\n");
|
||||
BSsendHeader(bs,BS_Done,0);
|
||||
}
|
||||
|
||||
void handle_spylist(BS* bs)
|
||||
{
|
||||
printf("PVS spy list server invoked\n");
|
||||
}
|
||||
|
||||
void handle_tasklist(BS* bs)
|
||||
{
|
||||
printf("PVS task list server invoked\n");
|
||||
}
|
||||
@@ -49,6 +49,17 @@ static char subst_buffer[VAR_MAX_SUB_SIZE];
|
||||
static int subst_used;
|
||||
static int line_num;
|
||||
|
||||
struct db_app_node
|
||||
{
|
||||
char* name;
|
||||
struct db_app_node* next;
|
||||
};
|
||||
typedef struct db_app_node DB_APP_NODE;
|
||||
|
||||
DB_APP_NODE* DbApplList=(DB_APP_NODE*)NULL;
|
||||
static DB_APP_NODE* DbCurrentListHead=(DB_APP_NODE*)NULL;
|
||||
static DB_APP_NODE* DbCurrentListTail=(DB_APP_NODE*)NULL;
|
||||
|
||||
static int yyerror();
|
||||
static void sub_pvname(char*,char*);
|
||||
|
||||
@@ -65,8 +76,9 @@ extern struct dbBase *pdbBase;
|
||||
%token <Str> WORD VALUE
|
||||
%token <Str> FIELD
|
||||
%left O_BRACE C_BRACE O_PAREN C_PAREN
|
||||
%left DATABASE CONTAINER RECORD
|
||||
%left NOWHERE
|
||||
%left DATABASE RECORD
|
||||
%left NOWHERE
|
||||
%token APPL
|
||||
|
||||
%union
|
||||
{
|
||||
@@ -105,18 +117,39 @@ n_body: O_BRACE records C_BRACE
|
||||
;
|
||||
|
||||
db_components: /* null */
|
||||
| db_components container
|
||||
| db_components applic
|
||||
| db_components record
|
||||
;
|
||||
|
||||
container: CONTAINER c_head c_body
|
||||
;
|
||||
applic: APPL O_PAREN VALUE C_PAREN
|
||||
{
|
||||
DB_APP_NODE* an=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE*));
|
||||
|
||||
c_head: O_PAREN WORD C_PAREN
|
||||
{ free($2); }
|
||||
;
|
||||
if(subst_used)
|
||||
{
|
||||
strcpy(subst_buffer,$<Str>3);
|
||||
if(dbDoSubst(subst_buffer,sizeof(subst_buffer),NULL)!=0)
|
||||
fprintf(stderr,"dbDoSubst failed\n");
|
||||
#ifdef vxWorks
|
||||
an->name=strdup(subst_buffer);
|
||||
free($3);
|
||||
#else
|
||||
printf("\napplication(\"%s\")\n",subst_buffer);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef vxWorks
|
||||
an->name=$<Str>3;
|
||||
#else
|
||||
printf("\napplication(\"%s\")\n",$<Str>3);
|
||||
#endif
|
||||
}
|
||||
if(DbCurrentListHead==(DB_APP_NODE*)NULL) DbCurrentListTail=an;
|
||||
|
||||
c_body: O_BRACE db_components C_BRACE
|
||||
an->next=DbCurrentListHead;
|
||||
DbCurrentListHead=an;
|
||||
}
|
||||
;
|
||||
|
||||
records: /* null */
|
||||
@@ -190,13 +223,24 @@ field: FIELD O_PAREN WORD COMMA VALUE C_PAREN
|
||||
static int yyerror(str)
|
||||
char *str;
|
||||
{ fprintf(stderr,"db file parse, Error line %d : %s\n",line_num, yytext); }
|
||||
|
||||
#ifdef vxWorks
|
||||
static char* strdup(char* x)
|
||||
{
|
||||
char* c;
|
||||
c=(char*)malloc(strlen(x)+1);
|
||||
strcpy(c,x);
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
int dbLoadRecords(char* pfilename, char* pattern)
|
||||
{
|
||||
FILE* fp;
|
||||
long status;
|
||||
DB_APP_NODE* an;
|
||||
|
||||
#ifdef vxWorks
|
||||
if(pdbBase==NULL)
|
||||
@@ -243,6 +287,21 @@ int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
if(subst_used) dbFreeSubst();
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(DbCurrentListHead==(DB_APP_NODE*)NULL)
|
||||
{
|
||||
/* set up a default list to put on the master application list */
|
||||
DbCurrentListHead=(DB_APP_NODE*)malloc(sizeof(DB_APP_NODE));
|
||||
DbCurrentListTail=DbCurrentListHead;
|
||||
DbCurrentListHead->name=strdup(pfilename);
|
||||
DbCurrentListHead->next=(DB_APP_NODE*)NULL;
|
||||
}
|
||||
|
||||
DbCurrentListTail->next=DbApplList;
|
||||
DbApplList=DbCurrentListHead;
|
||||
DbCurrentListHead=(DB_APP_NODE*)NULL;
|
||||
DbCurrentListTail=(DB_APP_NODE*)NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -276,3 +335,14 @@ static void sub_pvname(char* type, char* name)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef vxWorks
|
||||
int dbAppList()
|
||||
{
|
||||
DB_APP_NODE* an;
|
||||
|
||||
for(an=DbApplList;an;an=an->next)
|
||||
printf("%s\n",an->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,9 +12,9 @@ value [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
"field" { return(FIELD); }
|
||||
"grecord" { return(RECORD); }
|
||||
"record" { return(RECORD); }
|
||||
"container" { return(CONTAINER); }
|
||||
"database" { return(DATABASE); }
|
||||
"nowhere" { return(NOWHERE); }
|
||||
"application" { return(APPL); }
|
||||
|
||||
\"{value}*\" { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(VALUE); }
|
||||
|
||||
|
||||
@@ -276,9 +276,11 @@ sub_pat: WORD EQUALS WORD
|
||||
|
||||
#include "dbLoadTemplate_lex.c"
|
||||
|
||||
static int yyerror(str)
|
||||
char *str;
|
||||
{ fprintf(stderr,"templ file parse, Error line %d : %s\n",line_num, yytext); }
|
||||
static int yyerror(char* str)
|
||||
{
|
||||
fprintf(stderr,"Substitution file parse error\n");
|
||||
fprintf(stderr,"line %d:%s\n",line_num,yytext);
|
||||
}
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
|
||||
116
src/dbtools/rdbapplist.c
Normal file
116
src/dbtools/rdbapplist.c
Normal file
@@ -0,0 +1,116 @@
|
||||
|
||||
/* only runable on work station now */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname);
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
BSDATA info;
|
||||
int rc;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSsetAddress(&info,argv[1])<0)
|
||||
{
|
||||
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc=read_pvs(&info,PVS_AppList,(char*)NULL);
|
||||
|
||||
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname)
|
||||
{
|
||||
BS* bs;
|
||||
int verb,size,done,len,i,port,rsize;
|
||||
char* buffer;
|
||||
char ip_from[40];
|
||||
FILE* fd;
|
||||
|
||||
BSgetAddressPort(info,ip_from,&port);
|
||||
|
||||
/* verify ioc not already added */
|
||||
if(access(ip_from,F_OK)==0)
|
||||
{
|
||||
/* delete the existing file for this IOC */
|
||||
unlink(ip_from);
|
||||
}
|
||||
|
||||
done=0;
|
||||
BSsetPort(info,PVS_TCP_PORT);
|
||||
|
||||
if((bs=BSipOpenData(info))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of socket to IOC failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rsize=strlen(sname)+1;
|
||||
else
|
||||
rsize=0;
|
||||
|
||||
if(BSsendHeader(bs,serv,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"Command send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rsize>0)
|
||||
{
|
||||
if(BSsendData(bs,sname,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"send of command name failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fd=stdout;
|
||||
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
|
||||
|
||||
while(done==0)
|
||||
{
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"Receive header failed\n");
|
||||
done=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_Data: /* read a block of names */
|
||||
if((len=BSreceiveData(bs,buffer,size))<0)
|
||||
fprintf(stderr,"Receive data failed\n");
|
||||
else
|
||||
fputs(buffer,fd);
|
||||
fputc('\n',fd);
|
||||
break;
|
||||
case BS_Done: /* transfers complete */
|
||||
BSclose(bs);
|
||||
done=-1;
|
||||
break;
|
||||
default:
|
||||
if(size>0) done=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
128
src/dbtools/rdbls.c
Normal file
128
src/dbtools/rdbls.c
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
/* only runable on work station now */
|
||||
|
||||
#include "PVS.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname);
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
BSDATA info;
|
||||
int rc;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
fprintf(stderr,"usage: %s IOC-ip-address\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(BSsetAddress(&info,argv[1])<0)
|
||||
{
|
||||
fprintf(stderr,"Cannot determine address for %s\n",argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc=read_pvs(&info,PVS_RecList,(char*)NULL);
|
||||
|
||||
if(rc<0) fprintf(stderr,"read of data failed horribly\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_pvs(BSDATA* info,int serv,char* sname)
|
||||
{
|
||||
BS* bs;
|
||||
int verb,size,done,len,i,port,rsize;
|
||||
char* buffer;
|
||||
char ip_from[40];
|
||||
FILE* fd;
|
||||
|
||||
BSgetAddressPort(info,ip_from,&port);
|
||||
|
||||
/* printf("IOC %s starting\n",ip_from); */
|
||||
|
||||
/* verify ioc not already added */
|
||||
if(access(ip_from,F_OK)==0)
|
||||
{
|
||||
/* delete the existing file for this IOC */
|
||||
unlink(ip_from);
|
||||
}
|
||||
|
||||
done=0;
|
||||
BSsetPort(info,PVS_TCP_PORT);
|
||||
|
||||
if((bs=BSipOpenData(info))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Open of socket to IOC failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(serv>PVS_LAST_VERB)
|
||||
rsize=strlen(sname)+1;
|
||||
else
|
||||
rsize=0;
|
||||
|
||||
if(BSsendHeader(bs,serv,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"Command send failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rsize>0)
|
||||
{
|
||||
if(BSsendData(bs,sname,rsize)<0)
|
||||
{
|
||||
fprintf(stderr,"send of command name failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fd=stdout;
|
||||
buffer=(char*)malloc(PVS_TRANSFER_SIZE+2);
|
||||
|
||||
while(done==0)
|
||||
{
|
||||
if(BSreceiveHeader(bs,&verb,&size)<0)
|
||||
{
|
||||
fprintf(stderr,"Receive header failed\n");
|
||||
done=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(verb)
|
||||
{
|
||||
case PVS_Data: /* read a block of names */
|
||||
if((len=BSreceiveData(bs,buffer,size))<0)
|
||||
{
|
||||
fprintf(stderr,"Receive data failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
if(buffer[i]==' ') buffer[i]='\n';
|
||||
}
|
||||
buffer[len]='\n';
|
||||
buffer[len+1]='\0';
|
||||
|
||||
fputs(buffer,fd);
|
||||
}
|
||||
break;
|
||||
case BS_Done: /* transfers complete */
|
||||
BSclose(bs);
|
||||
done=-1;
|
||||
break;
|
||||
default:
|
||||
if(size>0) done=-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
5
src/libCom/env/envSubr.c
vendored
5
src/libCom/env/envSubr.c
vendored
@@ -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**********************************************************************
|
||||
|
||||
@@ -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**********************************************************************
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
542
src/rec/recDynLink.c
Normal 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
51
src/rec/recDynLink.h
Normal 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
191
src/rec/recDynLinkTest.c
Normal 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,
|
||||
×tamp,&AlarmStatus,&AlarmSeverity);
|
||||
if(status) {
|
||||
printf("recDynLinkGet returned illegal status\n");
|
||||
return;
|
||||
}
|
||||
tsStampToText(×tamp,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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user