Initial revision
This commit is contained in:
1469
src/ca/access.c
Normal file
1469
src/ca/access.c
Normal file
File diff suppressed because it is too large
Load Diff
185
src/ca/acctst.c
Normal file
185
src/ca/acctst.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
A CA test/debug routine
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* System includes */
|
||||||
|
#include <vxWorks.h>
|
||||||
|
#ifdef vxWorks
|
||||||
|
#include <taskLib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <caerr.h>
|
||||||
|
#include <db_access.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define CA_TEST_CHNL "AI_T2000"
|
||||||
|
*/
|
||||||
|
#define CA_TEST_CHNL "AI_T2000.DESC"
|
||||||
|
#define CA_TEST_CHNL4 "AI_DOGGY"
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM 1
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
spacctst()
|
||||||
|
{
|
||||||
|
int acctst();
|
||||||
|
|
||||||
|
return taskSpawn("acctst",200,VX_FP_TASK,20000,acctst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
acctst()
|
||||||
|
#else
|
||||||
|
main()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
chid chix1;
|
||||||
|
chid chix2;
|
||||||
|
chid chix3;
|
||||||
|
chid chix4;
|
||||||
|
void ca_test_event();
|
||||||
|
void null_event();
|
||||||
|
struct dbr_gr_float *ptr;
|
||||||
|
float delay = .003;
|
||||||
|
|
||||||
|
long status;
|
||||||
|
long pid;
|
||||||
|
long i,j;
|
||||||
|
float delta = 1.0;
|
||||||
|
long monix;
|
||||||
|
char string[41];
|
||||||
|
float value;
|
||||||
|
float *pfloat;
|
||||||
|
struct dbr_ctrl_float *pctrl;
|
||||||
|
char pstring[NUM][MAX_STRING_SIZE];
|
||||||
|
void write_event();
|
||||||
|
|
||||||
|
|
||||||
|
SEVCHK(ca_task_initialize(),"Unable to initialize");
|
||||||
|
|
||||||
|
printf("begin\n");
|
||||||
|
# ifdef VMS
|
||||||
|
lib$init_timer();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
ptr = (struct dbr_gr_float *)
|
||||||
|
malloc(dbr_size[DBR_GR_FLOAT] + dbr_value_size[DBR_GR_FLOAT]*(NUM-1));
|
||||||
|
for(i=0;i<2;i++){
|
||||||
|
status = ca_array_build( CA_TEST_CHNL, /* channel ASCII name */
|
||||||
|
DBR_GR_FLOAT, /* fetch external type */
|
||||||
|
NUM, /* array element cnt */
|
||||||
|
&chix3, /* ptr to chid */
|
||||||
|
ptr /* pointer to recv buf */
|
||||||
|
);
|
||||||
|
SEVCHK(status, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SEVCHK(ca_search(CA_TEST_CHNL4,&chix4),NULL);
|
||||||
|
SEVCHK(ca_search(CA_TEST_CHNL,&chix2),NULL);
|
||||||
|
|
||||||
|
for(i=0;i<1;i++)
|
||||||
|
SEVCHK(ca_search(CA_TEST_CHNL,&chix1),NULL);
|
||||||
|
|
||||||
|
status = ca_pend_io(1.0);
|
||||||
|
|
||||||
|
if(INVALID_DB_REQ(chix1->type))
|
||||||
|
printf("Failed to locate %s\n",CA_TEST_CHNL);
|
||||||
|
if(INVALID_DB_REQ(chix2->type))
|
||||||
|
printf("Failed to locate %s\n",CA_TEST_CHNL);
|
||||||
|
if(INVALID_DB_REQ(chix3->type))
|
||||||
|
printf("Failed to locate %s\n",CA_TEST_CHNL);
|
||||||
|
if(INVALID_DB_REQ(chix4->type))
|
||||||
|
printf("Failed to locate %s\n",CA_TEST_CHNL4);
|
||||||
|
/*
|
||||||
|
SEVCHK(status,NULL);
|
||||||
|
if(status == ECA_TIMEOUT)
|
||||||
|
exit();
|
||||||
|
*/
|
||||||
|
|
||||||
|
# ifdef VMS
|
||||||
|
lib$show_timer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pfloat = &ptr->value;
|
||||||
|
for(i=0;i<NUM;i++)
|
||||||
|
printf("Value Returned from build %f\n",pfloat[i]);
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
lib$init_timer();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if(VALID_DB_REQ(chix4->type)){
|
||||||
|
ca_add_event(DBR_FLOAT, chix4, ca_test_event, 0xaaaaaaaa, &monix);
|
||||||
|
ca_clear_event(monix);
|
||||||
|
}
|
||||||
|
if(VALID_DB_REQ(chix4->type)){
|
||||||
|
ca_add_event(DBR_FLOAT, chix4, ca_test_event, 0xaaaaaaaa, &monix);
|
||||||
|
ca_clear_event(monix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(VALID_DB_REQ(chix3->type)){
|
||||||
|
ca_add_event(DBR_FLOAT, chix3, ca_test_event, 0xaaaaaaaa, &monix);
|
||||||
|
ca_add_event(DBR_FLOAT, chix3, write_event, 0xaaaaaaaa, &monix);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfloat = (float *) malloc(sizeof(float)*NUM);
|
||||||
|
|
||||||
|
|
||||||
|
if(VALID_DB_REQ(chix1->type))
|
||||||
|
if(pfloat)
|
||||||
|
for(i=0;i<NUM;i++){
|
||||||
|
for(j=0;j<NUM;j++)
|
||||||
|
sprintf(&pstring[j][0],"%d",j+100);
|
||||||
|
SEVCHK(ca_array_put(DBR_STRING,NUM,chix1,pstring),NULL)
|
||||||
|
SEVCHK(ca_array_get(DBR_FLOAT,NUM,chix1,pfloat),NULL)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
abort();
|
||||||
|
|
||||||
|
ca_pend_io(4.0);
|
||||||
|
|
||||||
|
# ifdef VMS
|
||||||
|
lib$show_timer();
|
||||||
|
# endif
|
||||||
|
for(i=0;i<NUM;i++)
|
||||||
|
printf("Value Returned from put/get %f\n",pfloat[i]);
|
||||||
|
|
||||||
|
|
||||||
|
printf("-- Put/Gets done- waiting for Events --\n");
|
||||||
|
ca_pend_event(30.0);
|
||||||
|
|
||||||
|
free(ptr);
|
||||||
|
free(pfloat);
|
||||||
|
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void null_event()
|
||||||
|
{
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void write_event(args)
|
||||||
|
struct event_handler_args args;
|
||||||
|
{
|
||||||
|
float a = *(float *) args.dbr;
|
||||||
|
|
||||||
|
a += 10.1;
|
||||||
|
|
||||||
|
SEVCHK(ca_rput(args.chid, &a),"write fail in event");
|
||||||
|
SEVCHK(ca_flush_io(),NULL);
|
||||||
|
}
|
||||||
|
|
139
src/ca/catime.c
Normal file
139
src/ca/catime.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
CA performance test
|
||||||
|
|
||||||
|
History
|
||||||
|
joh 09-12-89 Initial release
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
# ifdef VMS
|
||||||
|
lib$init_timer();
|
||||||
|
# endif
|
||||||
|
# ifdef VMS
|
||||||
|
lib$show_timer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* System includes */
|
||||||
|
#include <vxWorks.h>
|
||||||
|
#ifdef vxWorks
|
||||||
|
#include <taskLib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <caerr.h>
|
||||||
|
#include <db_access.h>
|
||||||
|
|
||||||
|
#define CA_TEST_CHNL "AI_2000"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
spcatime()
|
||||||
|
{
|
||||||
|
int acctst();
|
||||||
|
|
||||||
|
return taskSpawn("acctst",200,VX_FP_TASK,20000,acctst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NUM 1
|
||||||
|
|
||||||
|
catime()
|
||||||
|
{
|
||||||
|
chid ai_1;
|
||||||
|
|
||||||
|
long status;
|
||||||
|
long i,j;
|
||||||
|
void *ptr;
|
||||||
|
int ca_array_put();
|
||||||
|
int ca_array_get();
|
||||||
|
|
||||||
|
|
||||||
|
SEVCHK(ca_task_initialize(),"Unable to initialize");
|
||||||
|
|
||||||
|
|
||||||
|
SEVCHK(ca_search(CA_TEST_CHNL,&ai_1),NULL);
|
||||||
|
status = ca_pend_io(5.0);
|
||||||
|
SEVCHK(status,NULL);
|
||||||
|
if(status == ECA_TIMEOUT)
|
||||||
|
exit();
|
||||||
|
|
||||||
|
ptr = (void *) malloc(NUM*sizeof(union db_access_val)+NUM*MAX_STRING_SIZE);
|
||||||
|
if(!ptr)
|
||||||
|
exit();
|
||||||
|
|
||||||
|
printf("channel name %s native type %d native count %d\n",ai_1+1,ai_1->type,ai_1->count);
|
||||||
|
|
||||||
|
|
||||||
|
for(i=0;i<NUM;i++)
|
||||||
|
((float *)ptr)[i]=1.0;
|
||||||
|
test(ai_1, "DBR_FLOAT", DBR_FLOAT, NUM, ptr);
|
||||||
|
|
||||||
|
for(i=0;i<NUM;i++)
|
||||||
|
strcpy((char *)ptr+(MAX_STRING_SIZE*i),"1.0");
|
||||||
|
test(ai_1, "DBR_STRING", DBR_STRING, NUM, ptr);
|
||||||
|
|
||||||
|
for(i=0;i<NUM;i++)
|
||||||
|
((int *)ptr)[i]=1;
|
||||||
|
test(ai_1, "DBR_INT", DBR_INT, NUM, ptr);
|
||||||
|
|
||||||
|
free(ptr);
|
||||||
|
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test(chix, name, type, count, ptr)
|
||||||
|
chid chix;
|
||||||
|
int type,count;
|
||||||
|
void *ptr;
|
||||||
|
{
|
||||||
|
int test_put(), test_get(), test_wait();
|
||||||
|
|
||||||
|
printf("%s\n",name);
|
||||||
|
timex(test_put,chix, name, type, count, ptr);
|
||||||
|
timex(test_get,chix, name, type, count, ptr);
|
||||||
|
|
||||||
|
timexN(test_wait,chix, name, type, count, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_put(chix, name, type, count, ptr)
|
||||||
|
chid chix;
|
||||||
|
int type,count;
|
||||||
|
void *ptr;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i< 10000;i++){
|
||||||
|
SEVCHK(ca_array_put(type,count,chix,ptr),NULL);
|
||||||
|
}
|
||||||
|
SEVCHK(ca_flush_io(),NULL);
|
||||||
|
}
|
||||||
|
test_get(chix, name, type, count, ptr)
|
||||||
|
chid chix;
|
||||||
|
int type,count;
|
||||||
|
void *ptr;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i< 10000;i++){
|
||||||
|
SEVCHK(ca_array_get(type,count,chix,ptr),NULL);
|
||||||
|
}
|
||||||
|
SEVCHK(ca_pend_io(0.0),NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_wait(chix, name, type, count, ptr)
|
||||||
|
chid chix;
|
||||||
|
int type,count;
|
||||||
|
void *ptr;
|
||||||
|
{
|
||||||
|
|
||||||
|
SEVCHK(ca_array_get(type,count,chix,ptr),NULL);
|
||||||
|
SEVCHK(ca_pend_io(0.0),NULL);
|
||||||
|
}
|
||||||
|
|
87
src/ca/conn.c
Normal file
87
src/ca/conn.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* L O S A L A M O S */
|
||||||
|
/* Los Alamos National Laboratory */
|
||||||
|
/* Los Alamos, New Mexico 87545 */
|
||||||
|
/* */
|
||||||
|
/* Copyright, 1986, The Regents of the University of California. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* History */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* Date Programmer Comments */
|
||||||
|
/* ---- ---------- -------- */
|
||||||
|
/* 6/89 Jeff Hill Init Release */
|
||||||
|
/* */
|
||||||
|
/*_begin */
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Title: IOC connection automation */
|
||||||
|
/* File: atcs:[ca]access.c */
|
||||||
|
/* Environment: VMS, UNIX, VRTX */
|
||||||
|
/* Equipment: VAX, SUN, VME */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/*_end */
|
||||||
|
|
||||||
|
#include <vxWorks.h>
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <db_access.h>
|
||||||
|
#include <iocmsg.h>
|
||||||
|
#include <iocinf.h>
|
||||||
|
|
||||||
|
|
||||||
|
chid_retry(silent)
|
||||||
|
char silent;
|
||||||
|
{
|
||||||
|
register chid chix;
|
||||||
|
register unsigned int retry_cnt = 0;
|
||||||
|
char string[100];
|
||||||
|
void send_msg();
|
||||||
|
|
||||||
|
if(!chidlist_pend.count)
|
||||||
|
return ECA_NORMAL;
|
||||||
|
|
||||||
|
LOCK;
|
||||||
|
chix = (chid) &chidlist_pend;
|
||||||
|
while(chix = (chid) chix->node.next){
|
||||||
|
build_msg(chix,TRUE);
|
||||||
|
retry_cnt++;
|
||||||
|
if(!silent)
|
||||||
|
ca_signal(ECA_CHIDNOTFND, chix+1);
|
||||||
|
}
|
||||||
|
send_msg();
|
||||||
|
printf("Sent ");
|
||||||
|
UNLOCK;
|
||||||
|
|
||||||
|
if(retry_cnt && !silent){
|
||||||
|
sprintf(string, "%d channels outstanding", retry_cnt);
|
||||||
|
ca_signal(ECA_CHIDRETRY, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ECA_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Locks must be applied while in this routine
|
||||||
|
*/
|
||||||
|
mark_chids_disconnected(iocix)
|
||||||
|
register unsigned iocix;
|
||||||
|
{
|
||||||
|
register chid chix;
|
||||||
|
register chid nextchix;
|
||||||
|
|
||||||
|
nextchix = (chid) &chidlist_conn.node;
|
||||||
|
while(chix = nextchix){
|
||||||
|
nextchix = (chid) chix->node.next;
|
||||||
|
if(chix->iocix == iocix){
|
||||||
|
lstDelete(&chidlist_conn, chix);
|
||||||
|
lstAdd(&chidlist_pend, chix);
|
||||||
|
chix->type = TYPENOTCONN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
502
src/ca/convert.c
Normal file
502
src/ca/convert.c
Normal file
@ -0,0 +1,502 @@
|
|||||||
|
#include <db_access.h>
|
||||||
|
#include <net_convert.h>
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
# define memcpy(D,S,N) bcopy(S,D,N)
|
||||||
|
# define memset(D,V,N) bfill(D,N,V)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_sts_string(s,d)
|
||||||
|
** struct dbr_sts_string *s pointer to source struct
|
||||||
|
** struct dbr_sts_string *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** converts fields of struct in VAX format to IEEE format
|
||||||
|
** or
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX
|
||||||
|
** format;
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_sts_string(s,d,encode,num)
|
||||||
|
struct dbr_sts_string *s; /* source */
|
||||||
|
struct dbr_sts_string *d; /* destination */
|
||||||
|
int encode; /* do VAX to IEEE */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
|
||||||
|
/* convert ieee to vax format or vax to ieee */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
if (num == 1) /* if single value */
|
||||||
|
strcpy(d->value,s->value);
|
||||||
|
else
|
||||||
|
memcpy(d->value,s->value,(MAX_STRING_SIZE * num));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_sts_int(s,d)
|
||||||
|
** struct dbr_sts_int *s pointer to source struct
|
||||||
|
** struct dbr_sts_int *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** converts fields ofstruct in VAX format to ieee format
|
||||||
|
** or
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX
|
||||||
|
** format
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_sts_int(s,d,encode,num)
|
||||||
|
struct dbr_sts_int *s; /* source */
|
||||||
|
struct dbr_sts_int *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
short *sval_ptr,*dval_ptr; /* ptrs to source, destination */
|
||||||
|
|
||||||
|
/* convert vax to ieee or ieee to vax format -- same code*/
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
|
||||||
|
if (num == 1) /* single value */
|
||||||
|
d->value = ntohs(s->value);
|
||||||
|
else /* array chan-- multiple pts */
|
||||||
|
{
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0; i < num; i++){
|
||||||
|
*dval_ptr = ntohs(*sval_ptr);
|
||||||
|
sval_ptr++;
|
||||||
|
dval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_sts_float(s,d)
|
||||||
|
** struct dbr_sts_float *s pointer to source struct
|
||||||
|
** struct dbr_sts_float *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** if encode
|
||||||
|
** converts struct in VAX format to ieee format
|
||||||
|
** else
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX
|
||||||
|
** format;
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_sts_float(s,d,encode,num)
|
||||||
|
struct dbr_sts_float *s; /* source */
|
||||||
|
struct dbr_sts_float *d; /* destination */
|
||||||
|
int encode; /* it true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
float *sval_ptr,*dval_ptr;
|
||||||
|
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
|
||||||
|
if(encode) /* vax to ieee convert */
|
||||||
|
if(num == 1){
|
||||||
|
htonf(&s->value, &d->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
htonf(sval_ptr,dval_ptr);
|
||||||
|
sval_ptr++;
|
||||||
|
dval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else /* ieee to vax convert */
|
||||||
|
if(num == 1){
|
||||||
|
ntohf(&s->value,&d->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
ntohf(sval_ptr,dval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_sts_enum(s,d)
|
||||||
|
** struct dbr_sts_enum *s pointer to source struct
|
||||||
|
** struct dbr_sts_enum *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX format
|
||||||
|
** or
|
||||||
|
** converts fields of struct in VAX format to fields with IEEE format
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_sts_enum(s,d,encode,num)
|
||||||
|
struct dbr_sts_enum *s; /* source */
|
||||||
|
struct dbr_sts_enum *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
short *dval_ptr,*sval_ptr;
|
||||||
|
|
||||||
|
/* convert vax to ieee or ieee to vax --same code */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
if (num == 1)
|
||||||
|
d->value = ntohs(s->value);
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0; i < num; i++){
|
||||||
|
*dval_ptr = ntohs(*sval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_gr_int(s,d)
|
||||||
|
** struct dbr_gr_int *s pointer to source struct
|
||||||
|
** struct dbr_gr_int *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX format
|
||||||
|
** or
|
||||||
|
** converts fields of struct in VAX format to fields with IEEE format
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_gr_int(s,d,encode,num)
|
||||||
|
struct dbr_gr_int *s; /* source */
|
||||||
|
struct dbr_gr_int *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
short *sval_ptr,*dval_ptr;
|
||||||
|
|
||||||
|
/* convert ieee to vax or vax to ieee -- same code */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
strcpy(d->units,s->units);
|
||||||
|
|
||||||
|
d->upper_disp_limit = ntohs(s->upper_disp_limit);
|
||||||
|
d->lower_disp_limit = ntohs(s->lower_disp_limit);
|
||||||
|
d->upper_alarm_limit = ntohs(s->upper_alarm_limit);
|
||||||
|
d->upper_warning_limit = ntohs(s->upper_warning_limit);
|
||||||
|
d->lower_alarm_limit = ntohs(s->lower_alarm_limit);
|
||||||
|
d->lower_warning_limit = ntohs(s->lower_warning_limit);
|
||||||
|
|
||||||
|
if (num == 1)
|
||||||
|
d->value = ntohs(s->value);
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
*dval_ptr = ntohs(*sval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_gr_float(s,d)
|
||||||
|
** struct dbr_gr_float *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** if encode
|
||||||
|
** converts struct in VAX format to ieee format
|
||||||
|
** else
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX
|
||||||
|
** format;
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_gr_float(s,d,encode,num)
|
||||||
|
struct dbr_gr_float *s; /* source */
|
||||||
|
struct dbr_gr_float *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
float *sval_ptr,*dval_ptr;
|
||||||
|
|
||||||
|
/* these are same for vax to ieee or ieee to vax */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
d->precision = ntohs(s->precision);
|
||||||
|
strcpy(d->units,s->units);
|
||||||
|
|
||||||
|
if (encode) /* vax to ieee convert */
|
||||||
|
{
|
||||||
|
if (num == 1){
|
||||||
|
htonf(&s->value, &d->value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
htonf(sval_ptr,dval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
htonf(&s->upper_disp_limit,&d->upper_disp_limit);
|
||||||
|
htonf(&s->lower_disp_limit, &d->lower_disp_limit);
|
||||||
|
htonf(&s->upper_alarm_limit, &d->upper_alarm_limit);
|
||||||
|
htonf(&s->upper_warning_limit, &d->upper_warning_limit);
|
||||||
|
htonf(&s->lower_alarm_limit, &d->lower_alarm_limit);
|
||||||
|
htonf(&s->lower_warning_limit, &d->lower_warning_limit);
|
||||||
|
}
|
||||||
|
else /* ieee to vax convert */
|
||||||
|
{
|
||||||
|
if (num == 1){
|
||||||
|
ntohf(&s->value, &d->value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
ntohf(sval_ptr,dval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ntohf(&s->upper_disp_limit,&d->upper_disp_limit);
|
||||||
|
ntohf(&s->lower_disp_limit, &d->lower_disp_limit);
|
||||||
|
ntohf(&s->upper_alarm_limit, &d->upper_alarm_limit);
|
||||||
|
ntohf(&s->upper_warning_limit, &d->upper_warning_limit);
|
||||||
|
ntohf(&s->lower_alarm_limit, &d->lower_alarm_limit);
|
||||||
|
ntohf(&s->lower_warning_limit, &d->lower_warning_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_ctrl_int(s,d)
|
||||||
|
** struct dbr_gr_int *s pointer to source struct
|
||||||
|
** struct dbr_gr_int *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX format
|
||||||
|
** or
|
||||||
|
** converts fields of struct in VAX format to fields with IEEE format
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_ctrl_int(s,d,encode,num)
|
||||||
|
struct dbr_ctrl_int *s; /* source */
|
||||||
|
struct dbr_ctrl_int *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
short *sval_ptr,*dval_ptr;
|
||||||
|
|
||||||
|
/* vax to ieee or ieee to vax -- same code */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
strcpy(d->units,s->units);
|
||||||
|
|
||||||
|
d->upper_disp_limit = ntohs(s->upper_disp_limit);
|
||||||
|
d->lower_disp_limit = ntohs(s->lower_disp_limit);
|
||||||
|
d->upper_alarm_limit = ntohs(s->upper_alarm_limit);
|
||||||
|
d->upper_warning_limit = ntohs(s->upper_warning_limit);
|
||||||
|
d->lower_alarm_limit = ntohs(s->lower_alarm_limit);
|
||||||
|
d->lower_warning_limit = ntohs(s->lower_warning_limit);
|
||||||
|
d->lower_ctrl_limit = ntohs(s->lower_ctrl_limit);
|
||||||
|
d->upper_ctrl_limit = ntohs(s->upper_ctrl_limit);
|
||||||
|
|
||||||
|
if (num == 1)
|
||||||
|
d->value = ntohs(s->value);
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
*dval_ptr = ntohs(*sval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_ctrl_float(s,d)
|
||||||
|
** struct dbr_ctrl_float *s pointer to source struct
|
||||||
|
** struct dbr_ctrl_float *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** if encode
|
||||||
|
** converts struct in VAX format to ieee format
|
||||||
|
** else
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX
|
||||||
|
** format;
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_ctrl_float(s,d,encode,num)
|
||||||
|
struct dbr_ctrl_float *s; /* source */
|
||||||
|
struct dbr_ctrl_float *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
float *sval_ptr,*dval_ptr;
|
||||||
|
|
||||||
|
/* these are the same for ieee to vaax or vax to ieee */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
d->precision = ntohs(s->precision);
|
||||||
|
strcpy(d->units,s->units);
|
||||||
|
if (encode) /* vax to ieee convert */
|
||||||
|
{
|
||||||
|
if (num == 1){
|
||||||
|
htonf(&s->value, &d->value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
htonf(sval_ptr,dval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
htonf(&s->upper_disp_limit,&d->upper_disp_limit);
|
||||||
|
htonf(&s->lower_disp_limit, &d->lower_disp_limit);
|
||||||
|
htonf(&s->upper_alarm_limit, &d->upper_alarm_limit);
|
||||||
|
htonf(&s->upper_warning_limit, &d->upper_warning_limit);
|
||||||
|
htonf(&s->lower_alarm_limit, &d->lower_alarm_limit);
|
||||||
|
htonf(&s->lower_warning_limit, &d->lower_warning_limit);
|
||||||
|
htonf(&s->lower_ctrl_limit, &d->lower_ctrl_limit);
|
||||||
|
htonf(&s->upper_ctrl_limit, &d->upper_ctrl_limit);
|
||||||
|
}
|
||||||
|
else /* ieee to vax convert */
|
||||||
|
{
|
||||||
|
if (num == 1){
|
||||||
|
ntohf(&s->value, &d->value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0;i < num; i++){
|
||||||
|
ntohf(sval_ptr,dval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ntohf(&s->lower_disp_limit, &d->lower_disp_limit);
|
||||||
|
ntohf(&s->upper_alarm_limit, &d->upper_alarm_limit);
|
||||||
|
ntohf(&s->upper_warning_limit, &d->upper_warning_limit);
|
||||||
|
ntohf(&s->lower_alarm_limit, &d->lower_alarm_limit);
|
||||||
|
ntohf(&s->lower_warning_limit, &d->lower_warning_limit);
|
||||||
|
ntohf(&s->lower_ctrl_limit, &d->lower_ctrl_limit);
|
||||||
|
ntohf(&s->upper_ctrl_limit, &d->upper_ctrl_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** cvrt_ctrl_enum(s,d)
|
||||||
|
** struct dbr_ctrl_enum *s pointer to source struct
|
||||||
|
** struct dbr_ctrl_enum *d pointer to destination struct
|
||||||
|
** int encode; boolean, if true vax to ieee
|
||||||
|
** else ieee to vax
|
||||||
|
**
|
||||||
|
** if encode
|
||||||
|
** converts struct in VAX format to ieee format
|
||||||
|
** else
|
||||||
|
** converts fields of struct in IEEE format to fields with VAX
|
||||||
|
** format;
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
cvrt_ctrl_enum(s,d,encode,num)
|
||||||
|
struct dbr_ctrl_enum *s; /* source */
|
||||||
|
struct dbr_ctrl_enum *d; /* destination */
|
||||||
|
int encode; /* if true, vax to ieee */
|
||||||
|
int num; /* number of values */
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
short *sval_ptr,*dval_ptr;
|
||||||
|
|
||||||
|
/* vax to ieee or ieee to vax -- same code */
|
||||||
|
d->status = ntohs(s->status);
|
||||||
|
d->severity = ntohs(s->severity);
|
||||||
|
d->no_str = ntohs(s->no_str);
|
||||||
|
memcpy(d->strs,s->strs,sizeof(s->strs));
|
||||||
|
|
||||||
|
if (num == 1) /* single value */
|
||||||
|
d->value = ntohs(s->value);
|
||||||
|
else /* array chan-- multiple pts */
|
||||||
|
{
|
||||||
|
sval_ptr = &(s->value);
|
||||||
|
dval_ptr = &(d->value);
|
||||||
|
for (i = 0; i < num; i++){
|
||||||
|
*dval_ptr = ntohs(*sval_ptr);
|
||||||
|
dval_ptr++;
|
||||||
|
sval_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
84
src/ca/flow_control.c
Normal file
84
src/ca/flow_control.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* L O S A L A M O S */
|
||||||
|
/* Los Alamos National Laboratory */
|
||||||
|
/* Los Alamos, New Mexico 87545 */
|
||||||
|
/* */
|
||||||
|
/* Copyright, 1986, The Regents of the University of California. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* History */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* Date Programmer Comments */
|
||||||
|
/* ---- ---------- -------- */
|
||||||
|
/* 6/89 Jeff Hill Init Release */
|
||||||
|
/* */
|
||||||
|
/*_begin */
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Title: IOC network flow control module */
|
||||||
|
/* File: atcs:[ca]flow_control.c */
|
||||||
|
/* Environment: VMS. UNIX, VRTX */
|
||||||
|
/* Equipment: VAX, SUN, VME */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Purpose */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* ioc flow control module */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Special comments */
|
||||||
|
/* ------- -------- */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/*_end */
|
||||||
|
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <vxWorks.h>
|
||||||
|
#include <socket.h>
|
||||||
|
#include <ioctl.h>
|
||||||
|
#ifdef vxWorks
|
||||||
|
#include <ioLib.h>
|
||||||
|
#endif
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <iocmsg.h>
|
||||||
|
#include <iocinf.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Keep track of how many times messages have come with out a break in between
|
||||||
|
*/
|
||||||
|
flow_control(piiu)
|
||||||
|
struct ioc_in_use *piiu;
|
||||||
|
{
|
||||||
|
unsigned nbytes;
|
||||||
|
register int status;
|
||||||
|
register int busy = piiu->client_busy;
|
||||||
|
|
||||||
|
status = socket_ioctl( piiu->sock_chan,
|
||||||
|
FIONREAD,
|
||||||
|
&nbytes);
|
||||||
|
if(status < 0)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if(nbytes){
|
||||||
|
piiu->contiguous_msg_count++;
|
||||||
|
if(!busy)
|
||||||
|
if(piiu->contiguous_msg_count > MAX_CONTIGUOUS_MSG_COUNT){
|
||||||
|
piiu->client_busy = TRUE;
|
||||||
|
ca_busy_message(piiu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
piiu->contiguous_msg_count=0;
|
||||||
|
if(busy){
|
||||||
|
ca_ready_message(piiu);
|
||||||
|
piiu->client_busy = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
857
src/ca/iocinf.c
Normal file
857
src/ca/iocinf.c
Normal file
@ -0,0 +1,857 @@
|
|||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* L O S A L A M O S */
|
||||||
|
/* Los Alamos National Laboratory */
|
||||||
|
/* Los Alamos, New Mexico 87545 */
|
||||||
|
/* */
|
||||||
|
/* Copyright, 1986, The Regents of the University of California. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* History */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* Date Programmer Comments */
|
||||||
|
/* ---- ---------- -------- */
|
||||||
|
/* 8/87 Jeff Hill Init Release */
|
||||||
|
/* */
|
||||||
|
/*_begin */
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Title: IOC socket interface module */
|
||||||
|
/* File: atcs:[ca]iocinf.c */
|
||||||
|
/* Environment: VMS. UNIX, VRTX */
|
||||||
|
/* Equipment: VAX, SUN, VME */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Purpose */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* ioc socket interface module */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Special comments */
|
||||||
|
/* ------- -------- */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/*_end */
|
||||||
|
|
||||||
|
|
||||||
|
/* Allocate storage for global variables in this module */
|
||||||
|
#define GLBLSOURCE
|
||||||
|
#ifdef VMS
|
||||||
|
#include <iodef.h>
|
||||||
|
#include <inetiodef.h>
|
||||||
|
#include <stsdef.h>
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <vxWorks.h>
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
#include <ioLib.h>
|
||||||
|
#include <taskParams.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <socket.h>
|
||||||
|
#include <in.h>
|
||||||
|
#include <ioctl.h>
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <net_convert.h>
|
||||||
|
#include <iocmsg.h>
|
||||||
|
#include <iocinf.h>
|
||||||
|
|
||||||
|
/* For older versions of berkley UNIX types.h and vxWorks types.h */
|
||||||
|
/* 64 times sizeof(fd_mask) is the maximum channels on a vax JH */
|
||||||
|
/* Yuk - can a maximum channel be determined at run time ? */
|
||||||
|
/*
|
||||||
|
typedef long fd_mask;
|
||||||
|
typedef struct fd_set {
|
||||||
|
fd_mask fds_bits[64];
|
||||||
|
} fd_set;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NBBY
|
||||||
|
# define NBBY 8 /* number of bits per byte */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NFDBITS
|
||||||
|
#define NFDBITS (sizeof(int) * NBBY) /* bits per mask */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_SET
|
||||||
|
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_ISSET
|
||||||
|
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLR
|
||||||
|
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* my version is faster since it is in line */
|
||||||
|
#define FD_ZERO(p)\
|
||||||
|
{\
|
||||||
|
register int i;\
|
||||||
|
for(i=0;i<NELEMENTS((p)->fds_bits);i++)\
|
||||||
|
(p)->fds_bits[i]=0;\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 50 mS delay for TCP to finish transmitting */
|
||||||
|
/* select wakes you if message is only partly here */
|
||||||
|
/* so this wait free's up the processor until it completely arrives */
|
||||||
|
#define DELAYVAL 0.050 /* 50 mS */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
# define SYSFREQ 10000000 /* 10 MHz */
|
||||||
|
# define TCPDELAY\
|
||||||
|
{float delay = DELAYVAL; static int ef=NULL;\
|
||||||
|
int status; int systim[2]={-SYSFREQ*DELAYVAL,~0};\
|
||||||
|
if(!ef)ef= lib$get_ef(&ef);\
|
||||||
|
status = sys$setimr(ef,systim,NULL,MYTIMERID,NULL);\
|
||||||
|
if(~status&STS$M_SUCCESS)lib$signal(status);\
|
||||||
|
status = sys$waitfr(ef);\
|
||||||
|
if(~status&STS$M_SUCCESS)lib$signal(status);\
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
/*
|
||||||
|
###############
|
||||||
|
insert sysClkRateGet() here ??? -slows it down but works on all systems ??
|
||||||
|
###############
|
||||||
|
*/
|
||||||
|
# define SYSFREQ 60 /* 60 Hz */
|
||||||
|
# define TCPDELAY taskDelay((unsigned int)DELAYVAL*SYSFREQ);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UNIX
|
||||||
|
# define SYSFREQ 1000000 /* 1 MHz */
|
||||||
|
/*
|
||||||
|
# define TCPDELAY if(usleep((unsigned int)DELAYVAL*SYSFREQ))abort();
|
||||||
|
*/
|
||||||
|
# define TCPDELAY {if(select(0,NULL,NULL,NULL,&tcpdelayval)<0)abort();}
|
||||||
|
static struct timeval tcpdelayval = {0,(unsigned int)DELAYVAL*SYSFREQ};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct timeval notimeout = {0,0};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
LOCK should be on while in this routine
|
||||||
|
*/
|
||||||
|
alloc_ioc(net_addr, net_proto, iocix)
|
||||||
|
struct in_addr net_addr;
|
||||||
|
int net_proto;
|
||||||
|
unsigned short *iocix;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int status;
|
||||||
|
int sock;
|
||||||
|
int true = TRUE;
|
||||||
|
struct sockaddr_in src;
|
||||||
|
struct sockaddr_in *local_addr();
|
||||||
|
struct ioc_in_use *piiu;
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* IOC allready allocated ? */
|
||||||
|
/**********************************************************************/
|
||||||
|
for(i=0;i<nxtiiu;i++)
|
||||||
|
if( (net_addr.s_addr == iiu[i].sock_addr.sin_addr.s_addr)
|
||||||
|
&&
|
||||||
|
(net_proto == iiu[i].sock_proto)){
|
||||||
|
*iocix = i;
|
||||||
|
return ECA_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* allocate and initialize an IOC info block for unallocated IOC */
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
/* is there an IOC In Use block available to allocate */
|
||||||
|
if(nxtiiu>=MAXIIU)
|
||||||
|
return ECA_MAXIOC;
|
||||||
|
|
||||||
|
piiu = &iiu[nxtiiu];
|
||||||
|
|
||||||
|
/* set network address block */
|
||||||
|
piiu->sock_addr.sin_addr = net_addr;
|
||||||
|
|
||||||
|
/* set socket domain */
|
||||||
|
piiu->sock_addr.sin_family = AF_INET;
|
||||||
|
|
||||||
|
piiu->sock_proto = net_proto;
|
||||||
|
|
||||||
|
|
||||||
|
switch(net_proto)
|
||||||
|
{
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
/* set the port */
|
||||||
|
piiu->sock_addr.sin_port = htons(SERVER_NUM);
|
||||||
|
|
||||||
|
/* allocate a socket */
|
||||||
|
sock = socket( AF_INET, /* domain */
|
||||||
|
SOCK_STREAM, /* type */
|
||||||
|
0); /* deflt proto */
|
||||||
|
if(sock == ERROR)
|
||||||
|
return ECA_SOCK;
|
||||||
|
|
||||||
|
piiu->sock_chan = sock;
|
||||||
|
|
||||||
|
/* set TCP buffer sizes only if BSD 4.3 sockets */
|
||||||
|
/* temporarily turned off */
|
||||||
|
# ifdef ZEBRA
|
||||||
|
|
||||||
|
i = (MAX_MSG_SIZE+sizeof(int)) * 2;
|
||||||
|
status = setsockopt( sock,
|
||||||
|
SOL_SOCKET,
|
||||||
|
SO_SNDBUF,
|
||||||
|
&i,
|
||||||
|
sizeof(i));
|
||||||
|
if(status == -1){
|
||||||
|
socket_close(sock);
|
||||||
|
return ECA_ALLOCMEM;
|
||||||
|
}
|
||||||
|
status = setsockopt( sock,
|
||||||
|
SOL_SOCKET,
|
||||||
|
SO_RCVBUF,
|
||||||
|
&i,
|
||||||
|
sizeof(i));
|
||||||
|
if(status == -1){
|
||||||
|
socket_close(sock);
|
||||||
|
return ECA_ALLOCMEM;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
piiu->max_msg = MAX_TCP;
|
||||||
|
|
||||||
|
|
||||||
|
/* connect */
|
||||||
|
status = connect(
|
||||||
|
sock,
|
||||||
|
&iiu[nxtiiu].sock_addr,
|
||||||
|
sizeof(iiu[nxtiiu].sock_addr));
|
||||||
|
if(status == -1){
|
||||||
|
socket_close(sock);
|
||||||
|
return ECA_CONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
place the broadcast addr/port in the stream so the
|
||||||
|
ioc will know where this is coming from.
|
||||||
|
*/
|
||||||
|
i = sizeof(src);
|
||||||
|
status = getsockname( iiu[BROADCAST_IIU].sock_chan,
|
||||||
|
&src,
|
||||||
|
&i);
|
||||||
|
if(status == ERROR){
|
||||||
|
printf("alloc_ioc: cant get my name %d\n",MYERRNO);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
src.sin_addr.s_addr =
|
||||||
|
(local_addr(iiu[BROADCAST_IIU].sock_chan))->sin_addr.s_addr;
|
||||||
|
status = send( piiu->sock_chan,
|
||||||
|
&src,
|
||||||
|
sizeof(src),
|
||||||
|
0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
/* set the port */
|
||||||
|
piiu->sock_addr.sin_port = htons(SERVER_NUM);
|
||||||
|
|
||||||
|
/* allocate a socket */
|
||||||
|
sock = socket( AF_INET, /* domain */
|
||||||
|
SOCK_DGRAM, /* type */
|
||||||
|
0); /* deflt proto */
|
||||||
|
if(sock == ERROR)
|
||||||
|
return ECA_SOCK;
|
||||||
|
|
||||||
|
piiu->sock_chan = sock;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following only needed on BSD 4.3 machines
|
||||||
|
*/
|
||||||
|
status = setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&true,sizeof(true));
|
||||||
|
if(status<0){
|
||||||
|
printf("%d\n",MYERRNO);
|
||||||
|
socket_close(sock);
|
||||||
|
return ECA_CONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memset(&src,0,sizeof(src));
|
||||||
|
src.sin_family = AF_INET;
|
||||||
|
src.sin_addr.s_addr = INADDR_ANY; /* let TCP pick lcl addr */
|
||||||
|
src.sin_port = 0; /* let TCP pick lcl port */
|
||||||
|
|
||||||
|
status = bind(sock, &src, sizeof(src));
|
||||||
|
if(status<0){
|
||||||
|
printf("%d\n",MYERRNO);
|
||||||
|
SEVCHK(ECA_INTERNAL,"bind failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
piiu->max_msg = MAX_UDP - sizeof(iiu[nxtiiu].send->stk);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("alloc_ioc: ukn protocol\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set non blocking IO for UNIX to prevent dead locks */
|
||||||
|
# ifdef UNIX
|
||||||
|
status = socket_ioctl( piiu->sock_chan,
|
||||||
|
FIONBIO,
|
||||||
|
&true);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* setup send_msg(), recv_msg() buffers */
|
||||||
|
if(! (piiu->send = (struct buffer *) malloc(sizeof(struct buffer))) ){
|
||||||
|
socket_close(sock);
|
||||||
|
return ECA_ALLOCMEM;
|
||||||
|
}
|
||||||
|
piiu->send->stk = 0;
|
||||||
|
if(! (piiu->recv = (struct buffer *) malloc(sizeof(struct buffer))) ){
|
||||||
|
socket_close(sock);
|
||||||
|
return ECA_ALLOCMEM;
|
||||||
|
}
|
||||||
|
piiu->recv->stk = 0;
|
||||||
|
|
||||||
|
/* Set up recv thread for VMS */
|
||||||
|
# ifdef VMS
|
||||||
|
{
|
||||||
|
void recv_msg_ast();
|
||||||
|
status = sys$qio( NULL,
|
||||||
|
sock,
|
||||||
|
IO$_RECEIVE,
|
||||||
|
&piiu->iosb,
|
||||||
|
recv_msg_ast,
|
||||||
|
nxtiiu,
|
||||||
|
piiu->recv->buf,
|
||||||
|
sizeof(piiu->recv->buf),
|
||||||
|
NULL,
|
||||||
|
&piiu->recvfrom,
|
||||||
|
sizeof(piiu->recvfrom),
|
||||||
|
NULL);
|
||||||
|
if(status != SS$_NORMAL){
|
||||||
|
lib$signal(status);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# ifdef vxWorks
|
||||||
|
{
|
||||||
|
void recv_task();
|
||||||
|
int pri;
|
||||||
|
char name[15];
|
||||||
|
|
||||||
|
status == taskPriorityGet(VXTASKIDSELF, &pri);
|
||||||
|
if(status<0)
|
||||||
|
SEVCHK(ECA_INTERNAL,NULL);
|
||||||
|
|
||||||
|
name[0]=NULL;
|
||||||
|
strncat(name,"RD ", sizeof(name)-1);
|
||||||
|
strncat(name, taskName(VXTHISTASKID), sizeof(name)-1);
|
||||||
|
|
||||||
|
status = taskSpawn( name,
|
||||||
|
pri-1,
|
||||||
|
VX_FP_TASK,
|
||||||
|
4096,
|
||||||
|
recv_task,
|
||||||
|
(unsigned) nxtiiu,
|
||||||
|
taskIdSelf());
|
||||||
|
if(status<0)
|
||||||
|
SEVCHK(ECA_INTERNAL,NULL);
|
||||||
|
|
||||||
|
iiu[nxtiiu].recv_tid = status;
|
||||||
|
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
*iocix = nxtiiu++;
|
||||||
|
|
||||||
|
return ECA_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOTE: Wallangong select cant be called in an AST with a timeout
|
||||||
|
since they use timer ASTs to implement thier timeout.
|
||||||
|
|
||||||
|
NOTE: Wallangong select does not return early if IO is present prior
|
||||||
|
to the timeout expiring.
|
||||||
|
|
||||||
|
LOCK should be on while in this routine
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
send_msg()
|
||||||
|
{
|
||||||
|
unsigned cnt;
|
||||||
|
void *pmsg;
|
||||||
|
unsigned iocix;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Note: this routine must not be called at AST level */
|
||||||
|
/**********************************************************************/
|
||||||
|
for(iocix=0;iocix<nxtiiu;iocix++)
|
||||||
|
if(iiu[iocix].send->stk){
|
||||||
|
|
||||||
|
/* don't allow UDP recieve messages to que up under UNIX */
|
||||||
|
# ifdef UNIX
|
||||||
|
{
|
||||||
|
void recv_msg_select();
|
||||||
|
/* test for recieve allready in progress and NOOP if so */
|
||||||
|
if(!post_msg_active)
|
||||||
|
recv_msg_select(¬imeout);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
cnt = iiu[iocix].send->stk + sizeof(iiu[iocix].send->stk);
|
||||||
|
iiu[iocix].send->stk = htonl(cnt); /* convert for 68000 */
|
||||||
|
pmsg = iiu[iocix].send; /* byte cnt then buf */
|
||||||
|
|
||||||
|
while(TRUE){
|
||||||
|
status = sendto( iiu[iocix].sock_chan,
|
||||||
|
pmsg,
|
||||||
|
cnt,
|
||||||
|
0,
|
||||||
|
&iiu[iocix].sock_addr,
|
||||||
|
sizeof(iiu[iocix].sock_addr));
|
||||||
|
if(status == cnt)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(status>=0){
|
||||||
|
if(status>cnt)
|
||||||
|
SEVCHK(ECA_INTERNAL,"more sent than requested");
|
||||||
|
cnt = cnt-status;
|
||||||
|
pmsg = (void *) (status+(char *)pmsg);
|
||||||
|
}
|
||||||
|
else if(MYERRNO == EWOULDBLOCK){
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(MYERRNO != EPIPE){
|
||||||
|
printf("send_msg(): unexpected error on socket send() %d\n",MYERRNO);
|
||||||
|
}
|
||||||
|
SEVCHK(ECA_DISCONN, host_from_addr(iiu[iocix].sock_addr.sin_addr))
|
||||||
|
mark_chids_disconnected(iocix);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ensure we do not accumulate extra recv messages (for TCP)
|
||||||
|
*/
|
||||||
|
# ifdef UNIX
|
||||||
|
{
|
||||||
|
void recv_msg_select();
|
||||||
|
recv_msg_select(¬imeout);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
TCPDELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset send stack */
|
||||||
|
iiu[iocix].send->stk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Recieve incomming messages
|
||||||
|
1) Wait no longer than timeout
|
||||||
|
2) Return early if nothing outstanding
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifdef UNIX
|
||||||
|
void
|
||||||
|
recv_msg_select(ptimeout)
|
||||||
|
struct timeval *ptimeout;
|
||||||
|
{
|
||||||
|
unsigned iocix;
|
||||||
|
long status;
|
||||||
|
void recv_msg();
|
||||||
|
|
||||||
|
for(iocix=0; iocix<nxtiiu; iocix++)
|
||||||
|
FD_SET(iiu[iocix].sock_chan, &readch);
|
||||||
|
|
||||||
|
status = select( sizeof(fd_set)*NBBY,
|
||||||
|
&readch,
|
||||||
|
&writech,
|
||||||
|
&execch,
|
||||||
|
ptimeout);
|
||||||
|
|
||||||
|
while(status > 0){
|
||||||
|
|
||||||
|
for(iocix=0; iocix<nxtiiu; iocix++){
|
||||||
|
if(!FD_ISSET(iiu[iocix].sock_chan,&readch))
|
||||||
|
continue;
|
||||||
|
recv_msg(iocix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure that nothing is left pending */
|
||||||
|
for(iocix=0;iocix<nxtiiu;iocix++)
|
||||||
|
FD_SET(iiu[iocix].sock_chan,&readch);
|
||||||
|
|
||||||
|
status = select( sizeof(fd_set)*NBBY,
|
||||||
|
&readch,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
¬imeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(status<0){
|
||||||
|
if(MYERRNO == EINTR)
|
||||||
|
return;
|
||||||
|
else{
|
||||||
|
char text[255];
|
||||||
|
sprintf(text,"Error Returned From Select: %d",MYERRNO);
|
||||||
|
SEVCHK(ECA_INTERNAL,text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
recv_msg(iocix)
|
||||||
|
unsigned iocix;
|
||||||
|
{
|
||||||
|
struct ioc_in_use *piiu = &iiu[iocix];
|
||||||
|
void tcp_recv_msg();
|
||||||
|
void udp_recv_msg();
|
||||||
|
|
||||||
|
switch(piiu->sock_proto){
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
tcp_recv_msg(iocix);
|
||||||
|
flow_control(piiu);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
udp_recv_msg(iocix);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("send_msg: ukn protocol\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
tcp_recv_msg(iocix)
|
||||||
|
unsigned iocix;
|
||||||
|
{
|
||||||
|
struct ioc_in_use *piiu = &iiu[iocix];
|
||||||
|
unsigned long byte_cnt;
|
||||||
|
unsigned long byte_sum;
|
||||||
|
int status;
|
||||||
|
int timeoutcnt;
|
||||||
|
struct buffer *rcvb = piiu->recv;
|
||||||
|
int sock = piiu->sock_chan;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while(TRUE){
|
||||||
|
status = recv( sock,
|
||||||
|
&rcvb->stk,
|
||||||
|
sizeof(rcvb->stk),
|
||||||
|
0);
|
||||||
|
if(status == sizeof(rcvb->stk))
|
||||||
|
break;
|
||||||
|
if( status > 0)
|
||||||
|
SEVCHK(ECA_INTERNAL,"partial recv on request of only 4 bytes");
|
||||||
|
|
||||||
|
if( status < 0){
|
||||||
|
if(MYERRNO != EWOULDBLOCK){
|
||||||
|
if(MYERRNO != EPIPE && MYERRNO != ECONNRESET)
|
||||||
|
printf("unexpected recv error 1 = %d\n",MYERRNO);
|
||||||
|
|
||||||
|
SEVCHK(ECA_DISCONN, host_from_addr(piiu->sock_addr.sin_addr));
|
||||||
|
mark_chids_disconnected(iocix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try again on status of 0 or -1 and EWOULDBLOCK */
|
||||||
|
TCPDELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* switch from 68000 to VAX byte order */
|
||||||
|
byte_cnt = (unsigned long) ntohl(rcvb->stk) - sizeof(rcvb->stk);
|
||||||
|
if(byte_cnt>MAX_MSG_SIZE){
|
||||||
|
printf("recv_msg(): message overflow %u\n",byte_cnt-MAX_MSG_SIZE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
timeoutcnt = byte_cnt + 3000;
|
||||||
|
for(byte_sum = 0; byte_sum < byte_cnt; byte_sum += status){
|
||||||
|
|
||||||
|
# ifdef DEBUG
|
||||||
|
if(byte_sum)
|
||||||
|
printf( "recv_msg(): Warning- reading %d leftover bytes \n",
|
||||||
|
byte_cnt-byte_sum);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
status = recv( sock,
|
||||||
|
&rcvb->buf[byte_sum],
|
||||||
|
byte_cnt - byte_sum,
|
||||||
|
0);
|
||||||
|
if(status < 0){
|
||||||
|
if(MYERRNO != EWOULDBLOCK){
|
||||||
|
if(MYERRNO != EPIPE && MYERRNO != ECONNRESET)
|
||||||
|
printf("unexpected recv error 2 = %d\n",MYERRNO);
|
||||||
|
|
||||||
|
SEVCHK(ECA_DISCONN, host_from_addr(piiu->sock_addr.sin_addr));
|
||||||
|
mark_chids_disconnected(iocix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
if(--timeoutcnt < 0){
|
||||||
|
printf("recv_msg(): TCP message bdy wait timed out\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait for TCP/IP to complete the message transfer */
|
||||||
|
TCPDELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* post message to the user */
|
||||||
|
post_msg(rcvb->buf, byte_cnt, piiu->sock_addr.sin_addr, piiu);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
udp_recv_msg(iocix)
|
||||||
|
unsigned iocix;
|
||||||
|
{
|
||||||
|
struct ioc_in_use *piiu = &iiu[iocix];
|
||||||
|
unsigned long byte_cnt;
|
||||||
|
int status;
|
||||||
|
struct buffer *rcvb = piiu->recv;
|
||||||
|
int sock = piiu->sock_chan;
|
||||||
|
struct sockaddr_in reply;
|
||||||
|
int reply_size = sizeof(reply);
|
||||||
|
char *ptr;
|
||||||
|
unsigned nchars;
|
||||||
|
|
||||||
|
|
||||||
|
rcvb->stk =0;
|
||||||
|
do{
|
||||||
|
|
||||||
|
status = recvfrom(
|
||||||
|
sock,
|
||||||
|
&rcvb->buf[rcvb->stk],
|
||||||
|
MAX_UDP,
|
||||||
|
0,
|
||||||
|
&reply,
|
||||||
|
&reply_size);
|
||||||
|
if(status < sizeof(int)){
|
||||||
|
/* op would block which is ok to ignore till ready later */
|
||||||
|
if(MYERRNO == EWOULDBLOCK)
|
||||||
|
break;
|
||||||
|
SEVCHK(ECA_INTERNAL,"unexpected udp recv error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* switch from 68000 to VAX byte order */
|
||||||
|
byte_cnt = (unsigned long) ntohl(*(int *)&rcvb->buf[rcvb->stk]);
|
||||||
|
# ifdef DEBUG
|
||||||
|
printf("recieved a udp reply of %d bytes\n",byte_cnt);
|
||||||
|
# endif
|
||||||
|
if(byte_cnt != status){
|
||||||
|
printf("recv_cast(): corrupt broadcast reply %d\n",MYERRNO);
|
||||||
|
printf("recv_cast(): header %d actual %d\n",byte_cnt,status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rcvb->stk += byte_cnt;
|
||||||
|
|
||||||
|
*(struct in_addr *) &rcvb->buf[rcvb->stk] = reply.sin_addr;
|
||||||
|
rcvb->stk += sizeof(reply.sin_addr);
|
||||||
|
|
||||||
|
if(rcvb->stk + MAX_UDP > MAX_MSG_SIZE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
More comming ?
|
||||||
|
*/
|
||||||
|
status = socket_ioctl( sock,
|
||||||
|
FIONREAD,
|
||||||
|
&nchars);
|
||||||
|
if(status<0)
|
||||||
|
SEVCHK(ECA_INTERNAL,"unexpected udp ioctl err\n");
|
||||||
|
|
||||||
|
}while(nchars);
|
||||||
|
|
||||||
|
for( ptr = rcvb->buf;
|
||||||
|
ptr < &rcvb->buf[rcvb->stk];
|
||||||
|
ptr += byte_cnt + sizeof(reply.sin_addr)){
|
||||||
|
byte_cnt = (unsigned long) ntohl(*(int *)ptr);
|
||||||
|
|
||||||
|
/* post message to the user */
|
||||||
|
post_msg( ptr + sizeof(int),
|
||||||
|
byte_cnt - sizeof(int),
|
||||||
|
*(struct in_addr *)(ptr+byte_cnt),
|
||||||
|
piiu);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
void
|
||||||
|
recv_task(iocix,moms_tid)
|
||||||
|
unsigned iocix;
|
||||||
|
int moms_tid;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = taskVarAdd(VXTHISTASKID, &ca_static);
|
||||||
|
if(status == ERROR)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
ca_static = (struct ca_static *) taskVarGet(moms_tid, &ca_static);
|
||||||
|
if(ca_static == (struct ca_static*)ERROR)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
while(TRUE)
|
||||||
|
recv_msg(iocix);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
void
|
||||||
|
recv_msg_ast(iocix)
|
||||||
|
int iocix;
|
||||||
|
{
|
||||||
|
struct ioc_in_use *piiu = &iiu[iocix];
|
||||||
|
short io_status = piiu->iosb.status;
|
||||||
|
int io_count = piiu->iosb.count;
|
||||||
|
struct sockaddr_in *paddr;
|
||||||
|
char *pbuf;
|
||||||
|
unsigned int *pcount= (unsigned int *) piiu->recv->buf;
|
||||||
|
int bufsize;
|
||||||
|
|
||||||
|
unsigned long byte_cnt;
|
||||||
|
|
||||||
|
if(io_status != SS$_NORMAL){
|
||||||
|
if(io_status == SS$_CANCEL)
|
||||||
|
return;
|
||||||
|
lib$signal(io_status);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/*
|
||||||
|
NOTE: The following is a bug fix since WIN has returned
|
||||||
|
the address structure missaligned by 16 bits
|
||||||
|
|
||||||
|
the fix is reliable since this structure happens
|
||||||
|
to be padded with zeros at the end by more than 16 bits
|
||||||
|
*/
|
||||||
|
if(piiu->sock_proto == IPPROTO_TCP)
|
||||||
|
paddr = (struct sockaddr_in *) &piiu->sock_addr;
|
||||||
|
else
|
||||||
|
#ifdef WINTCP
|
||||||
|
paddr = (struct sockaddr_in *) ((char *)&piiu->recvfrom+sizeof(short));
|
||||||
|
#else
|
||||||
|
paddr = (struct sockaddr_in *) (char *)&piiu->recvfrom;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
piiu->recv->stk += io_count;
|
||||||
|
io_count = piiu->recv->stk;
|
||||||
|
|
||||||
|
while(TRUE){
|
||||||
|
pbuf = (char *) (pcount+1);
|
||||||
|
|
||||||
|
/* switch from 68000 to VAX byte order */
|
||||||
|
byte_cnt = (unsigned long) ntohl(*pcount);
|
||||||
|
if(byte_cnt>MAX_MSG_SIZE || byte_cnt<sizeof(*pcount)){
|
||||||
|
printf("recv_msg_ast(): msg over/underflow %u\n",byte_cnt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(io_count == byte_cnt){
|
||||||
|
post_msg(pbuf, byte_cnt-sizeof(*pcount), paddr->sin_addr, piiu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(io_count > byte_cnt)
|
||||||
|
post_msg(pbuf, byte_cnt-sizeof(*pcount), paddr->sin_addr, piiu);
|
||||||
|
else{
|
||||||
|
if(pcount != &piiu->recv->buf){
|
||||||
|
memcpy(piiu->recv->buf, pcount, io_count);
|
||||||
|
piiu->recv->stk = io_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufsize = sizeof(piiu->recv->buf) - piiu->recv->stk;
|
||||||
|
io_status = sys$qio( NULL,
|
||||||
|
piiu->sock_chan,
|
||||||
|
IO$_RECEIVE,
|
||||||
|
&piiu->iosb,
|
||||||
|
recv_msg_ast,
|
||||||
|
iocix,
|
||||||
|
&piiu->recv->buf[piiu->recv->stk],
|
||||||
|
bufsize,
|
||||||
|
NULL,
|
||||||
|
&piiu->recvfrom,
|
||||||
|
sizeof(piiu->recvfrom),
|
||||||
|
NULL);
|
||||||
|
if(io_status != SS$_NORMAL)
|
||||||
|
lib$signal(io_status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
io_count -= byte_cnt;
|
||||||
|
pcount = (int *) (byte_cnt + (char *)pcount);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(piiu->sock_proto == IPPROTO_TCP)
|
||||||
|
flow_control(piiu);
|
||||||
|
|
||||||
|
piiu->recv->stk = 0;
|
||||||
|
io_status = sys$qio( NULL,
|
||||||
|
piiu->sock_chan,
|
||||||
|
IO$_RECEIVE,
|
||||||
|
&piiu->iosb,
|
||||||
|
recv_msg_ast,
|
||||||
|
iocix,
|
||||||
|
piiu->recv->buf,
|
||||||
|
sizeof(piiu->recv->buf),
|
||||||
|
NULL,
|
||||||
|
&piiu->recvfrom,
|
||||||
|
sizeof(piiu->recvfrom),
|
||||||
|
NULL);
|
||||||
|
if(io_status != SS$_NORMAL)
|
||||||
|
lib$signal(io_status);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
317
src/ca/iocinf.h
Normal file
317
src/ca/iocinf.h
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* L O S A L A M O S */
|
||||||
|
/* Los Alamos National Laboratory */
|
||||||
|
/* Los Alamos, New Mexico 87545 */
|
||||||
|
/* */
|
||||||
|
/* Copyright, 1986, The Regents of the University of California. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* History */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* Date Programmer Comments */
|
||||||
|
/* ---- ---------- -------- */
|
||||||
|
/* 8/87 Jeff Hill Init Release */
|
||||||
|
/* 1/90 Jeff Hill fd_set in the UNIX version only */
|
||||||
|
/* */
|
||||||
|
/*_begin */
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Title: channel access TCPIP interface include file */
|
||||||
|
/* File: atcs:[ca]iocinf.h */
|
||||||
|
/* Environment: VMS, UNIX, VRTX */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Purpose */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* ioc interface include */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Special comments */
|
||||||
|
/* ------- -------- */
|
||||||
|
/* Use GLBLTYPE to define externals so we can change the all at */
|
||||||
|
/* once from VAX globals to generic externals */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/*_end */
|
||||||
|
|
||||||
|
#ifndef INClstLibh
|
||||||
|
#include <lstLib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _TYPES_
|
||||||
|
# include <types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IN_HEADER__
|
||||||
|
#include <in.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
#include <fast_lock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
# include <ssdef>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
/************************************************************************/
|
||||||
|
/* Provided to enforce one thread at a time code sections */
|
||||||
|
/* independent of a particular operating system */
|
||||||
|
/************************************************************************/
|
||||||
|
/* note: the following must allways be used together */
|
||||||
|
/* provided for data structure mutal exclusive lock out */
|
||||||
|
/* in the VMS AST environment. */
|
||||||
|
# define LOCK\
|
||||||
|
{register long astenblwas;\
|
||||||
|
astenblwas = sys$setast(FALSE);
|
||||||
|
# define UNLOCK\
|
||||||
|
if(astenblwas == SS$_WASSET)sys$setast(TRUE);}
|
||||||
|
#else
|
||||||
|
# ifdef vxWorks
|
||||||
|
# define LOCK FASTLOCK(&client_lock);
|
||||||
|
# define UNLOCK FASTUNLOCK(&client_lock);
|
||||||
|
# else
|
||||||
|
# define LOCK
|
||||||
|
# define UNLOCK
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IODONESUB\
|
||||||
|
{\
|
||||||
|
register struct pending_io_event *pioe;\
|
||||||
|
LOCK;\
|
||||||
|
if(ioeventlist.count)\
|
||||||
|
while(pioe = (struct pending_io_event *) lstGet(&ioeventlist)){\
|
||||||
|
(*pioe->io_done_sub)(pioe->io_done_arg);\
|
||||||
|
if(free(pioe))abort();\
|
||||||
|
}\
|
||||||
|
UNLOCK;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VALID_MSG(PIIU) (piiu->read_seq == piiu->cur_read_seq)
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
# define SETPENDRECV {pndrecvcnt++;}
|
||||||
|
# define CLRPENDRECV\
|
||||||
|
{if(--pndrecvcnt<1){IODONESUB; vrtxPost(&io_done_flag, TRUE);}}
|
||||||
|
#else
|
||||||
|
#ifdef VMS
|
||||||
|
# define SETPENDRECV {pndrecvcnt++;}
|
||||||
|
# define CLRPENDRECV\
|
||||||
|
{if(--pndrecvcnt<1){IODONESUB; sys$setef(io_done_flag);}}
|
||||||
|
#else
|
||||||
|
# define SETPENDRECV {pndrecvcnt++;}
|
||||||
|
# define CLRPENDRECV\
|
||||||
|
{if(--pndrecvcnt<1){IODONESUB;}}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINTCP /* Wallangong */
|
||||||
|
/* (the VAXC runtime lib has its own close */
|
||||||
|
# define socket_close(S) netclose(S)
|
||||||
|
# define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||||
|
#endif
|
||||||
|
#ifdef UNIX
|
||||||
|
# define socket_close(S) close(S)
|
||||||
|
# define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||||
|
#endif
|
||||||
|
#ifdef vxWorks
|
||||||
|
# define socket_close(S) close(S)
|
||||||
|
# define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* size of object in bytes rounded up to nearest long word */
|
||||||
|
#define QUAD_ROUND(A) (((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) (((A)+1)>>1)
|
||||||
|
#define BI_SIZEOF(A) (QUAD_ROUND(sizeof(A)))
|
||||||
|
|
||||||
|
#define MAX(A,B) (((A)>(B))?(A):(B))
|
||||||
|
#define MIN(A,B) (((A)>(B))?(B):(A))
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
#define VXTHISTASKID taskIdCurrent
|
||||||
|
extern int taskIdCurrent;
|
||||||
|
#define abort() taskSuspend(taskIdCurrent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef vxWorks
|
||||||
|
# define memcpy(D,S,N) bcopy(S,D,N)
|
||||||
|
# define memset(D,V,N) bfill(D,N,V)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
#ifdef WINTCP
|
||||||
|
extern int uerrno; /* Wallongong errno is uerrno */
|
||||||
|
# define MYERRNO uerrno
|
||||||
|
#else
|
||||||
|
extern volatile int noshare socket_errno;
|
||||||
|
# define MYERRNO socket_errno
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
# ifdef vxWorks
|
||||||
|
# define MYERRNO (errnoGet()&0xffff)
|
||||||
|
# else
|
||||||
|
extern int errno;
|
||||||
|
# define MYERRNO errno
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Structures */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
/* stk must be above and contiguous with buf ! */
|
||||||
|
struct buffer{
|
||||||
|
unsigned long stk;
|
||||||
|
char buf[MAX_MSG_SIZE]; /* from iocmsg.h */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
struct iosb{
|
||||||
|
short status;
|
||||||
|
unsigned short count;
|
||||||
|
void *device;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct timeval{
|
||||||
|
unsigned long tv_sec;
|
||||||
|
unsigned long tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Moved in an allocated structure for vxWorks Compatibility */
|
||||||
|
#define MAXIIU 25
|
||||||
|
#define LOCAL_IIU (MAXIIU+100)
|
||||||
|
#define BROADCAST_IIU 0
|
||||||
|
|
||||||
|
struct pending_io_event{
|
||||||
|
NODE node;
|
||||||
|
void (*io_done_sub)();
|
||||||
|
void *io_done_arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_CONTIGUOUS_MSG_COUNT 2
|
||||||
|
|
||||||
|
|
||||||
|
#define iiu (ca_static->ca_iiu)
|
||||||
|
#define pndrecvcnt (ca_static->ca_pndrecvcnt)
|
||||||
|
#define chidlist_pend (ca_static->ca_chidlist_pend)
|
||||||
|
#define chidlist_conn (ca_static->ca_chidlist_conn)
|
||||||
|
#define chidlist_noreply\
|
||||||
|
(ca_static->ca_chidlist_noreply)
|
||||||
|
#define eventlist (ca_static->ca_eventlist)
|
||||||
|
#define ioeventlist (ca_static->ca_ioeventlist)
|
||||||
|
#define nxtiiu (ca_static->ca_nxtiiu)
|
||||||
|
#ifdef UNIX
|
||||||
|
#define readch (ca_static->ca_readch)
|
||||||
|
#define writech (ca_static->ca_writech)
|
||||||
|
#define execch (ca_static->ca_execch)
|
||||||
|
#endif
|
||||||
|
#define post_msg_active (ca_static->ca_post_msg_active)
|
||||||
|
#ifdef vxWorks
|
||||||
|
#define io_done_flag (ca_static->ca_io_done_flag)
|
||||||
|
#define evuser (ca_static->ca_evuser)
|
||||||
|
#define client_lock (ca_static->ca_client_lock)
|
||||||
|
#define event_buf (ca_static->ca_event_buf)
|
||||||
|
#define event_buf_size (ca_static->ca_event_buf_size)
|
||||||
|
#endif
|
||||||
|
#ifdef VMS
|
||||||
|
#define io_done_flag (ca_static->ca_io_done_flag)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ca_static{
|
||||||
|
unsigned short ca_nxtiiu;
|
||||||
|
long ca_pndrecvcnt;
|
||||||
|
LIST ca_chidlist_conn;
|
||||||
|
LIST ca_chidlist_pend;
|
||||||
|
LIST ca_chidlist_noreply;
|
||||||
|
LIST ca_eventlist;
|
||||||
|
LIST ca_ioeventlist;
|
||||||
|
#ifdef UNIX
|
||||||
|
fd_set ca_readch;
|
||||||
|
fd_set ca_writech;
|
||||||
|
fd_set ca_execch;
|
||||||
|
#endif
|
||||||
|
short ca_exit_in_progress;
|
||||||
|
unsigned short ca_post_msg_active;
|
||||||
|
#ifdef VMS
|
||||||
|
int ca_io_done_flag;
|
||||||
|
#endif
|
||||||
|
#ifdef vxWorks
|
||||||
|
int ca_io_done_flag;
|
||||||
|
void *ca_evuser;
|
||||||
|
FAST_LOCK ca_client_lock;
|
||||||
|
void *ca_event_buf;
|
||||||
|
unsigned ca_event_buf_size;
|
||||||
|
int ca_tid;
|
||||||
|
#endif
|
||||||
|
struct ioc_in_use{
|
||||||
|
unsigned contiguous_msg_count;
|
||||||
|
unsigned client_busy;
|
||||||
|
int sock_proto;
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
int sock_chan;
|
||||||
|
int max_msg;
|
||||||
|
struct buffer *send;
|
||||||
|
struct buffer *recv;
|
||||||
|
unsigned read_seq;
|
||||||
|
unsigned cur_read_seq;
|
||||||
|
#ifdef VMS /* for qio ASTs */
|
||||||
|
struct sockaddr_in recvfrom;
|
||||||
|
struct iosb iosb;
|
||||||
|
#endif
|
||||||
|
#ifdef vxWorks
|
||||||
|
int recv_tid;
|
||||||
|
#endif
|
||||||
|
} ca_iiu[MAXIIU];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
GLOBAL VARIABLES
|
||||||
|
There should only be one - add others to ca_static above -joh
|
||||||
|
*/
|
||||||
|
#ifdef GLBLSOURCE
|
||||||
|
# ifdef VAXC
|
||||||
|
# define GLBLTYPE globaldef
|
||||||
|
# else
|
||||||
|
# define GLBLTYPE
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef VAXC
|
||||||
|
# define GLBLTYPE globalref
|
||||||
|
# else
|
||||||
|
# define GLBLTYPE extern
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GLBLTYPE
|
||||||
|
struct ca_static *ca_static;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
GLBLTYPE
|
||||||
|
char ca_unique_address;
|
||||||
|
# define MYTIMERID (&ca_unique_address)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Error handlers needed
|
||||||
|
|
||||||
|
remote_error(user_arg,chid,type,count)
|
||||||
|
diconnect(user_arg,chid)
|
||||||
|
connect(user_arg,chid)
|
||||||
|
io_done(user_arg)
|
||||||
|
|
||||||
|
*/
|
77
src/ca/iocmsg.h
Normal file
77
src/ca/iocmsg.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#ifndef __IOCMSG__
|
||||||
|
/*
|
||||||
|
History
|
||||||
|
1/90 Jeff Hill removed status field in favor of a
|
||||||
|
seperate command- saves space on every
|
||||||
|
successful operation
|
||||||
|
09/24/90 Marty Kraimer Temporily changed def for SERVER_NUM
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __IOCMSG__
|
||||||
|
|
||||||
|
/* TCP/UDP port number (bumped each protocol change) */
|
||||||
|
#define CA_PROTOCOL_VERSION 2
|
||||||
|
/*
|
||||||
|
#define SERVER_NUM (IPPORT_USERRESERVED+12+CA_PROTOCOL_VERSION)
|
||||||
|
*/
|
||||||
|
#define SERVER_NUM (1102+CA_PROTOCOL_VERSION)
|
||||||
|
|
||||||
|
#define RSERVERQ 1 /* qid for response server queue */
|
||||||
|
#define MAX_UDP 1024
|
||||||
|
#define MAX_TCP (MAX_UDP*16) /* so waveforms fit */
|
||||||
|
#define MAX_MSG_SIZE (MAX_TCP) /* the larger of tcp and udp max */
|
||||||
|
|
||||||
|
|
||||||
|
/* values for m_cmmd */
|
||||||
|
|
||||||
|
#define IOC_EVENT_ADD 2 /* add an event */
|
||||||
|
#define IOC_NOCMD 4 /* NOOP */
|
||||||
|
#define IOC_EVENT_CANCEL 5 /* cancel an event */
|
||||||
|
#define IOC_READ 7 /* read and return a channel value*/
|
||||||
|
#define IOC_WRITE 9 /* write a channel value */
|
||||||
|
#define IOC_SNAPSHOT 11 /* snapshot of the system */
|
||||||
|
#define IOC_SEARCH 31 /* IOC channel search */
|
||||||
|
#define IOC_BUILD 33 /* Conglomerate of IOC_SEARCH */
|
||||||
|
/* IOC_READ */
|
||||||
|
/* (optimizes OPI network use) */
|
||||||
|
#define IOC_EVENTS_OFF 13 /* flow control */
|
||||||
|
#define IOC_EVENTS_ON 14 /* flow control */
|
||||||
|
#define IOC_READ_SYNC 16 /* purge old reads */
|
||||||
|
#define IOC_ERROR 18 /* an operation failed */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* extmsg - the nonvariant part of each message sent/recv
|
||||||
|
by the request server.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct extmsg {
|
||||||
|
unsigned short m_cmmd; /* operation to be performed */
|
||||||
|
unsigned short m_postsize; /* size of message extension */
|
||||||
|
unsigned short m_type; /* operation data type */
|
||||||
|
unsigned short m_count; /* operation data count */
|
||||||
|
void *m_paddr; /* ptr to struct db_addr */
|
||||||
|
/* IOC db field addr info */
|
||||||
|
unsigned long m_available; /* undefined message location for use
|
||||||
|
* by client processes */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* for monitor message extension */
|
||||||
|
struct mon_info{
|
||||||
|
float m_lval; /* low value to look for (deviation low
|
||||||
|
* for continuous monitors) */
|
||||||
|
float m_hval; /* high value (high deviation
|
||||||
|
* for continuous monitors) */
|
||||||
|
float m_toval; /* timeout limit for returning cval */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct monops { /* monitor req opi to ioc */
|
||||||
|
struct extmsg m_header;
|
||||||
|
struct mon_info m_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
160
src/ca/net_convert.h
Normal file
160
src/ca/net_convert.h
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/************************************************************************/
|
||||||
|
/* So byte swapping can be performed in line for efficiency */
|
||||||
|
/* (WINTCP has library routines with the same same functionality */
|
||||||
|
/* but more than twice the delay) JH */
|
||||||
|
/* WARNING: WILL NOT WORK ON TYPES FLOAT OR DOUBLE */
|
||||||
|
/* (use *(long *)& to perform type convert without reformat) */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
#ifdef VAX
|
||||||
|
# define ntohs(SHORT)\
|
||||||
|
((unsigned short)(((short)(SHORT))<<8 | ((unsigned short)(SHORT))>>8 ))
|
||||||
|
# define htons(SHORT)\
|
||||||
|
((unsigned short)(((short)(SHORT))<<8 | ((unsigned short)(SHORT))>>8 ))
|
||||||
|
#else
|
||||||
|
# define ntohs(SHORT) (SHORT)
|
||||||
|
# define htons(SHORT) (SHORT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VAX
|
||||||
|
# define ntohl(LONG)\
|
||||||
|
(\
|
||||||
|
((long)(LONG))<<24 |\
|
||||||
|
((unsigned long)(LONG))>>24 |\
|
||||||
|
(((long)(LONG))&0x00ff0000)>>8 |\
|
||||||
|
(((long)(LONG))&0x0000ff00)<<8\
|
||||||
|
)
|
||||||
|
# define htonl(LONG)\
|
||||||
|
(\
|
||||||
|
((long)(LONG))<<24 |\
|
||||||
|
((unsigned long)(LONG))>>24 |\
|
||||||
|
(((long)(LONG))&0x00ff0000)>>8 |\
|
||||||
|
(((long)(LONG))&0x0000ff00)<<8\
|
||||||
|
)
|
||||||
|
#else
|
||||||
|
# define ntohl(LONG) (LONG)
|
||||||
|
# define htonl(LONG) (LONG)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* So float convert can be performed in line for efficiency */
|
||||||
|
/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */
|
||||||
|
/************************************************************************/
|
||||||
|
struct ieeeflt{
|
||||||
|
unsigned mant :23;
|
||||||
|
unsigned exp :8;
|
||||||
|
unsigned sign :1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Exponent sign bias */
|
||||||
|
#define IEEE_SB 127
|
||||||
|
|
||||||
|
/* Conversion Range */
|
||||||
|
/* -126<exp<127 with mantissa of form 1.mant */
|
||||||
|
#define EXPMINIEEE -126 /* min for norm # IEEE exponent */
|
||||||
|
|
||||||
|
#ifdef VAX
|
||||||
|
|
||||||
|
struct mitflt{
|
||||||
|
unsigned mant1 :7;
|
||||||
|
unsigned exp :8;
|
||||||
|
unsigned sign :1;
|
||||||
|
unsigned mant2 :16;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Exponent sign bias */
|
||||||
|
# define MIT_SB 129
|
||||||
|
|
||||||
|
/* Conversion Ranges */
|
||||||
|
/* -128<exp<126 with mantissa of form 1.mant */
|
||||||
|
# define EXPMAXMIT 126 /* max MIT exponent */
|
||||||
|
|
||||||
|
|
||||||
|
/* passed by ref untill beter alternative found */
|
||||||
|
/* (this includes mapping of fringe reals to zero or infinity) */
|
||||||
|
/* (byte swaps included in conversion */
|
||||||
|
|
||||||
|
# define htonf(MIT,IEEE)\
|
||||||
|
{\
|
||||||
|
long exp,mant,sign;\
|
||||||
|
sign = ((struct mitflt *) (MIT))->sign;\
|
||||||
|
if( (short)((struct mitflt *) (MIT))->exp < EXPMINIEEE + MIT_SB){\
|
||||||
|
exp = 0;\
|
||||||
|
mant = 0;\
|
||||||
|
}\
|
||||||
|
else{\
|
||||||
|
exp = (short)((struct mitflt *) (MIT))->exp-MIT_SB+IEEE_SB;\
|
||||||
|
mant = (((struct mitflt *) (MIT))->mant1<<16) |\
|
||||||
|
((struct mitflt *) (MIT))->mant2;\
|
||||||
|
}\
|
||||||
|
((struct ieeeflt *) (IEEE))->mant = mant;\
|
||||||
|
((struct ieeeflt *) (IEEE))->exp = exp;\
|
||||||
|
((struct ieeeflt *) (IEEE))->sign = sign;\
|
||||||
|
*(long *)(IEEE) = ntohl(*(long*)(IEEE));\
|
||||||
|
}
|
||||||
|
|
||||||
|
# define ntohf(IEEE,MIT)\
|
||||||
|
{\
|
||||||
|
long exp,mant2,mant1,sign;\
|
||||||
|
*(long *)(IEEE) = htonl(*(long*)(IEEE));\
|
||||||
|
sign = ((struct ieeeflt *) (IEEE))->sign;\
|
||||||
|
if( (short)((struct ieeeflt *) (IEEE))->exp > EXPMAXMIT + IEEE_SB){\
|
||||||
|
exp = EXPMAXMIT + MIT_SB;\
|
||||||
|
mant2 = ~0;\
|
||||||
|
mant1 = ~0;\
|
||||||
|
}\
|
||||||
|
else if( ((struct ieeeflt *) (IEEE))->exp == 0){\
|
||||||
|
exp = 0;\
|
||||||
|
mant2 = 0;\
|
||||||
|
mant1 = 0;\
|
||||||
|
}\
|
||||||
|
else{\
|
||||||
|
exp = ((struct ieeeflt *) (IEEE))->exp+MIT_SB-IEEE_SB;\
|
||||||
|
mant2 = ((struct ieeeflt *) (IEEE))->mant;\
|
||||||
|
mant1 = (((struct ieeeflt *) (IEEE))->mant>>(unsigned)16);\
|
||||||
|
}\
|
||||||
|
((struct mitflt *) (MIT))->exp = exp;\
|
||||||
|
((struct mitflt *) (MIT))->mant2 = mant2;\
|
||||||
|
((struct mitflt *) (MIT))->mant1 = mant1;\
|
||||||
|
((struct mitflt *) (MIT))->sign = sign;\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define ntohf(NET,HOST) {*(float *)(HOST) = *(float *)(NET);}
|
||||||
|
# define htonf(HOST,NET) {*(float *)(NET) = *(float *)(HOST);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VAX
|
||||||
|
/* cvrt is (array of) (pointer to) (function returning) int */
|
||||||
|
int cvrt_sts_string ();
|
||||||
|
int cvrt_sts_int ();
|
||||||
|
int cvrt_sts_float ();
|
||||||
|
int cvrt_sts_enum ();
|
||||||
|
int cvrt_gr_int ();
|
||||||
|
int cvrt_gr_float ();
|
||||||
|
int cvrt_ctrl_int ();
|
||||||
|
int cvrt_ctrl_float ();
|
||||||
|
int cvrt_ctrl_enum ();
|
||||||
|
|
||||||
|
static
|
||||||
|
int (*cvrt[])()
|
||||||
|
=
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
cvrt_sts_string,
|
||||||
|
cvrt_sts_int,
|
||||||
|
cvrt_sts_float,
|
||||||
|
cvrt_sts_enum,
|
||||||
|
cvrt_gr_int,
|
||||||
|
cvrt_gr_float,
|
||||||
|
cvrt_ctrl_int,
|
||||||
|
cvrt_ctrl_float,
|
||||||
|
cvrt_ctrl_enum
|
||||||
|
};
|
||||||
|
#endif
|
325
src/ca/service.c
Normal file
325
src/ca/service.c
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* L O S A L A M O S */
|
||||||
|
/* Los Alamos National Laboratory */
|
||||||
|
/* Los Alamos, New Mexico 87545 */
|
||||||
|
/* */
|
||||||
|
/* Copyright, 1986, The Regents of the University of California. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* History */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* Date Programmer Comments */
|
||||||
|
/* ---- ---------- -------- */
|
||||||
|
/* 8/87 Jeff Hill Init Release */
|
||||||
|
/* 1/90 Jeff Hill Made cmmd for errors which */
|
||||||
|
/* eliminated the status field */
|
||||||
|
/* */
|
||||||
|
/*_begin */
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Title: channel access service routines */
|
||||||
|
/* File: atcs:[ca]servuice.c */
|
||||||
|
/* Environment: VMS, UNIX, VRTX */
|
||||||
|
/* Equipment: VAX, SUN, VME */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Purpose */
|
||||||
|
/* ------- */
|
||||||
|
/* */
|
||||||
|
/* channel access service routines */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* Special comments */
|
||||||
|
/* ------- -------- */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
/*_end */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
#include <stsdef.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vxWorks.h>
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <net_convert.h>
|
||||||
|
#include <db_access.h>
|
||||||
|
#include <iocmsg.h>
|
||||||
|
#include <iocinf.h>
|
||||||
|
|
||||||
|
|
||||||
|
void post_msg(hdrptr,bufcnt,net_addr,piiu)
|
||||||
|
register struct extmsg *hdrptr;
|
||||||
|
register long bufcnt;
|
||||||
|
struct in_addr net_addr;
|
||||||
|
struct ioc_in_use *piiu;
|
||||||
|
{
|
||||||
|
evid monix;
|
||||||
|
long msgcnt;
|
||||||
|
long tmp;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
register void * t_available;
|
||||||
|
register unsigned short t_postsize;
|
||||||
|
register unsigned short t_cmmd;
|
||||||
|
register chtype t_type;
|
||||||
|
register unsigned short t_count;
|
||||||
|
register unsigned short t_size;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
# define BUFCHK(SIZE)\
|
||||||
|
msgcnt = (SIZE); if(bufcnt-msgcnt < 0)\
|
||||||
|
{printf("post_msg(): expected msg size larger than actual msg\n");return;}
|
||||||
|
|
||||||
|
# define BUFSTAT\
|
||||||
|
printf("expected %d left %d\n",msgcnt,bufcnt);
|
||||||
|
|
||||||
|
post_msg_active++;
|
||||||
|
|
||||||
|
while(bufcnt>0){
|
||||||
|
# ifdef DEBUG
|
||||||
|
printf( "processing message- bytes left %d, pending msgcnt %d\n",
|
||||||
|
bufcnt,
|
||||||
|
pndrecvcnt);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* byte swap the message up front */
|
||||||
|
t_available = (void *) hdrptr->m_available;
|
||||||
|
t_postsize = ntohs(hdrptr->m_postsize);
|
||||||
|
t_cmmd = ntohs(hdrptr->m_cmmd);
|
||||||
|
t_type = ntohs(hdrptr->m_type);
|
||||||
|
t_count = ntohs(hdrptr->m_count);
|
||||||
|
t_size = dbr_size[t_type];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch(t_cmmd){
|
||||||
|
|
||||||
|
case IOC_EVENT_ADD:
|
||||||
|
/* run the user's event handler */
|
||||||
|
/* m_available points to event descriptor */
|
||||||
|
|
||||||
|
monix = (evid) t_available;
|
||||||
|
|
||||||
|
/* m_postsize = 0 is a confirmation of a monitor cancel */
|
||||||
|
if( !t_postsize ){
|
||||||
|
LOCK;
|
||||||
|
lstDelete(&eventlist, monix);
|
||||||
|
UNLOCK;
|
||||||
|
if(free(monix)<0)
|
||||||
|
printf("Unable to dealloc VM on IOC monitor cancel confirmation\n");
|
||||||
|
|
||||||
|
BUFCHK(sizeof(*hdrptr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BREAK LEFT OUT HERE BY DESIGN -JH */
|
||||||
|
|
||||||
|
case IOC_READ:
|
||||||
|
{
|
||||||
|
/* update and convert the user's argument if read */
|
||||||
|
/* (m_available points to argument descriptor) */
|
||||||
|
/* else update in buffer if a monitor */
|
||||||
|
register void *objptr = (void *) (hdrptr+1);
|
||||||
|
register void *dstptr;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if(t_cmmd == IOC_READ){
|
||||||
|
/* only count get returns if from the current read seq */
|
||||||
|
if(!VALID_MSG(piiu))
|
||||||
|
break;
|
||||||
|
dstptr = (void *) t_available;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dstptr = objptr;
|
||||||
|
|
||||||
|
BUFCHK(sizeof(*hdrptr) + t_postsize);
|
||||||
|
|
||||||
|
# ifdef DEBUG
|
||||||
|
BUFSTAT
|
||||||
|
if(t_cmmd==IOC_READ)
|
||||||
|
{static short i; printf("global reccnt %d\n",++i);}
|
||||||
|
else
|
||||||
|
{static short i; printf("global moncnt %d\n",++i);}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
for(i=0; i<t_count; i++){
|
||||||
|
|
||||||
|
/* perform 2 and 4 byte transfer in line */
|
||||||
|
/* NOTE that if we are on a machine that does not require */
|
||||||
|
/* conversions these will be NULL macros */
|
||||||
|
switch(t_type){
|
||||||
|
|
||||||
|
/* long word convert/transfer */
|
||||||
|
case DBR_INT:
|
||||||
|
case DBR_ENUM:
|
||||||
|
*(short *)dstptr = ntohs(*(short *)objptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DBR_FLOAT:
|
||||||
|
tmp = *(long *)objptr;
|
||||||
|
ntohf(&tmp, dstptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DBR_STRING:
|
||||||
|
if(dstptr != objptr)
|
||||||
|
strcpy( dstptr,
|
||||||
|
objptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* record transfer and convert */
|
||||||
|
case DBR_STS_STRING:
|
||||||
|
case DBR_STS_INT:
|
||||||
|
case DBR_STS_FLOAT:
|
||||||
|
case DBR_STS_ENUM:
|
||||||
|
case DBR_GR_INT:
|
||||||
|
case DBR_GR_FLOAT:
|
||||||
|
case DBR_CTRL_INT:
|
||||||
|
case DBR_CTRL_FLOAT:
|
||||||
|
case DBR_CTRL_ENUM:
|
||||||
|
# ifdef VAX
|
||||||
|
(*cvrt[t_type])(objptr,dstptr,(int)FALSE,(int)t_count);
|
||||||
|
# else
|
||||||
|
if(dstptr != objptr)
|
||||||
|
memcpy( dstptr,
|
||||||
|
objptr,
|
||||||
|
t_size);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conversion Routines handle all elements of an array in one call
|
||||||
|
for efficiency.
|
||||||
|
*/
|
||||||
|
goto array_loop_exit;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("post_msg(): unsupported db fld type in msg ?%d\n",t_type);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
(char *) objptr += t_size;
|
||||||
|
(char *) dstptr += t_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
array_loop_exit:
|
||||||
|
|
||||||
|
if(t_cmmd == IOC_READ)
|
||||||
|
/* decrement the outstanding IO count */
|
||||||
|
CLRPENDRECV
|
||||||
|
else
|
||||||
|
/* call handler */
|
||||||
|
(*monix->usr_func)(
|
||||||
|
monix->usr_arg, /* usr supplied */
|
||||||
|
monix->chan, /* channel id */
|
||||||
|
t_type, /* type of returned val */
|
||||||
|
t_count, /* the element count */
|
||||||
|
hdrptr+1 /* ptr to returned val */
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOC_SEARCH:
|
||||||
|
case IOC_BUILD:
|
||||||
|
BUFCHK(sizeof(*hdrptr));
|
||||||
|
if( ((chid)t_available)->paddr ){
|
||||||
|
int iocix = ((chid)t_available)->iocix;
|
||||||
|
|
||||||
|
if(iiu[iocix].sock_addr.sin_addr.s_addr==net_addr.s_addr)
|
||||||
|
printf("burp ");
|
||||||
|
else{
|
||||||
|
char msg[256];
|
||||||
|
char acc[64];
|
||||||
|
char rej[64];
|
||||||
|
sprintf(acc,"%s",host_from_addr(iiu[iocix].sock_addr.sin_addr));
|
||||||
|
sprintf(rej,"%s",host_from_addr(net_addr));
|
||||||
|
sprintf( msg,
|
||||||
|
"Channel: %s Accepted: %s Rejected: %s ",
|
||||||
|
((chid)t_available)+1,
|
||||||
|
acc,
|
||||||
|
rej);
|
||||||
|
ca_signal(ECA_DBLCHNL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IOC_BUILD messages allways have a IOC_READ msg following */
|
||||||
|
/* (IOC_BUILD messages are sometimes followed by error messages */
|
||||||
|
/* which are also ignored on double replies) */
|
||||||
|
/* the following cause this message to be ignored for double replies */
|
||||||
|
if(t_cmmd == IOC_BUILD)
|
||||||
|
msgcnt += sizeof(struct extmsg) + (hdrptr+1)->m_postsize;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LOCK;
|
||||||
|
status = alloc_ioc (
|
||||||
|
net_addr,
|
||||||
|
IPPROTO_TCP,
|
||||||
|
&((chid)t_available)->iocix
|
||||||
|
);
|
||||||
|
SEVCHK(status, host_from_addr(net_addr));
|
||||||
|
SEVCHK(status, ((chid)t_available)+1);
|
||||||
|
|
||||||
|
/* Update rmt chid fields from extmsg fields */
|
||||||
|
((chid)t_available)->type = t_type;
|
||||||
|
((chid)t_available)->count = t_count;
|
||||||
|
((chid)t_available)->paddr = hdrptr->m_paddr;
|
||||||
|
lstDelete(&chidlist_pend, t_available);
|
||||||
|
lstAdd(&chidlist_conn, t_available);
|
||||||
|
UNLOCK;
|
||||||
|
|
||||||
|
/* decrement the outstanding IO count */
|
||||||
|
CLRPENDRECV;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOC_READ_SYNC:
|
||||||
|
BUFCHK(sizeof(struct extmsg));
|
||||||
|
piiu->read_seq++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOC_ERROR:
|
||||||
|
{
|
||||||
|
char context[255];
|
||||||
|
|
||||||
|
BUFCHK(sizeof(struct extmsg) + t_postsize);
|
||||||
|
|
||||||
|
name = (char *) host_from_addr(net_addr);
|
||||||
|
if(!name)
|
||||||
|
name = "an unregistered IOC";
|
||||||
|
|
||||||
|
if(t_postsize>sizeof(struct extmsg))
|
||||||
|
sprintf(context, "detected by: %s for: %s", name, hdrptr+2);
|
||||||
|
else
|
||||||
|
sprintf(context, "detected by: %s", name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOTE:
|
||||||
|
The orig request is stored as an extmsg structure at
|
||||||
|
hdrptr+1
|
||||||
|
I should print additional diagnostic info using this
|
||||||
|
info when time permits......
|
||||||
|
*/
|
||||||
|
|
||||||
|
SEVCHK(ntohl((int)t_available), context);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("post_msg(): Corrupt message or unsupported m_cmmd type\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufcnt -= msgcnt;
|
||||||
|
hdrptr = (struct extmsg *) (msgcnt + (char *) hdrptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
post_msg_active--;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
52
src/ca/test_event.c
Normal file
52
src/ca/test_event.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* System includes */
|
||||||
|
|
||||||
|
#include <cadef.h>
|
||||||
|
#include <db_access.h>
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ca_test_event(usr,chix,type,count,pval)
|
||||||
|
void *usr;
|
||||||
|
chid chix;
|
||||||
|
chtype type;
|
||||||
|
int count;
|
||||||
|
void *pval;
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("~~~### in test event for [%s] ###~~~\n",chix+1);
|
||||||
|
printf("user arg\t%x\n",usr);
|
||||||
|
printf("val ptr\t%x\n",pval);
|
||||||
|
printf("mon type\t%x\n",type);
|
||||||
|
printf("channel type\t%x\n",chix->type);
|
||||||
|
switch(type){
|
||||||
|
case DBR_STRING:
|
||||||
|
printf("Value:\t<%s>\n",pval);
|
||||||
|
break;
|
||||||
|
case DBR_INT:
|
||||||
|
case DBR_ENUM:
|
||||||
|
printf("Value:\t<%d>\n",*(int *)pval);
|
||||||
|
break;
|
||||||
|
case DBR_FLOAT:
|
||||||
|
printf("Value:\t<%f>\n",*(float *)pval);
|
||||||
|
break;
|
||||||
|
case DBR_STS_STRING:
|
||||||
|
printf("Value:\t<%s>\n",((struct dbr_sts_string *)pval)->value);
|
||||||
|
break;
|
||||||
|
case DBR_STS_INT:
|
||||||
|
printf("Value:\t<%d>\n",((struct dbr_sts_int *)pval)->value);
|
||||||
|
break;
|
||||||
|
case DBR_STS_FLOAT:
|
||||||
|
printf("Value:\t<%f>\n",((struct dbr_sts_float *)pval)->value);
|
||||||
|
break;
|
||||||
|
case DBR_STS_ENUM:
|
||||||
|
printf("Value:\t<%d>\n",((struct dbr_sts_enum *)pval)->value);
|
||||||
|
break;
|
||||||
|
case DBR_GR_FLOAT:
|
||||||
|
printf("Value:\t<%f>\n",((struct dbr_gr_float *)pval)->value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Sorry test_event does not handle this type monitor yet\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user