Files
epics-base/src/ca/iocinf.h
1994-03-30 12:05:05 +00:00

510 lines
13 KiB
C

/************************************************************************/
/* */
/* 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 */
/* ------- */
/* .01 08xx87 joh Init Release */
/* .02 01xx90 joh fd_set in the UNIX version only */
/* .03 060691 joh Rearanged buffer struct for SPARC port */
/* .04 072391 joh new lock prevents event preemption on vxWorks */
/* .05 082791 joh declaration of ca_request_event() */
/* .06 082791 joh added send message in progress flag */
/* .07 091691 joh moved channel_state enum to cadef.h for export */
/* .08 102991 joh added sprintf buffer */
/* .09 111891 joh added event task id for vxWorks */
/* .10 111991 joh mobe IODONESUB macro to service.c */
/* .11 031692 joh added declaration for post_msg() */
/* .12 031892 joh initial rebroadcast delay is now a #define */
/* .13 050492 joh added exception channel fd set */
/* .14 111792 joh increased MAXCONNTRIES from 3 to 30 */
/* .15 112092 joh added AST lck count var for VMS */
/* .16 120992 joh switched to dll list routines */
/* .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) */
/* */
/*_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 INCiocinfh
#define INCiocinfh
static char *iocinfhSccsId = "$Id$";
#define DONT_COMPILE @@@@ dont compile in this case @@@@
#if defined(UNIX)
# include <sys/types.h>
# include <netinet/in.h>
#else
# if defined(VMS)
# include <ssdef>
# include <sys/types.h>
# include <netinet/in.h>
# else
# if defined(vxWorks)
# include <vxWorks.h>
# include <in.h>
# else
DONT_COMPILE
# endif
# endif
#endif
#include <stdio.h>
#include <assert.h>
#include <cadef.h>
#include <iocmsg.h>
#include <bucketLib.h>
#include <ellLib.h>
#include <os_depen.h>
#ifndef min
#define min(A,B) ((A)>(B)?(B):(A))
#endif
/*
* catch when they use really large strings
*/
#define STRING_LIMIT 512
#define INITCHK \
if(!ca_static){ \
int s; \
s = ca_task_initialize(); \
if(s != ECA_NORMAL){ \
return s; \
} \
}
/* throw out requests prior to last ECA_TIMEOUT from ca_pend */
#define VALID_MSG(PIIU) (piiu->read_seq == piiu->cur_read_seq)
/* perform a build to reconnect this channel ? */
#define VALID_BUILD(CHID)\
(CHID->build_count && CHID->build_type != TYPENOTCONN && CHID->build_value)
#define SETPENDRECV {pndrecvcnt++;}
#define CLRPENDRECV(LOCK) {if(--pndrecvcnt<1){cac_io_done(LOCK); POST_IO_EV;}}
struct udpmsglog{
long nbytes;
int valid;
struct sockaddr_in addr;
};
/*
* for use with ca_mux_io()
*/
#define CA_DO_SENDS 1
#define CA_DO_RECVS 2
struct pending_io_event{
ELLNODE node;
void (*io_done_sub)();
void *io_done_arg;
};
typedef unsigned long ca_time;
#define MAXCONNTRIES 60 /* N conn retries on unchanged net */
#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */
#define CA_RECAST_DELAY 1 /* initial int sec to next recast */
#define CA_RECAST_PORT_MASK 0x3 /* random retry interval off port */
#define CA_RECAST_PERIOD 5 /* ul on retry period long term */
#define CA_CURRENT_TIME 0
/*
* for the beacon's recvd hash table
*/
#define BHT_INET_ADDR_MASK 0x7f
typedef struct beaconHashEntry{
struct beaconHashEntry *pNext;
struct in_addr inetAddr;
int timeStamp;
int averagePeriod;
}bhe;
#ifdef vxWorks
typedef struct caclient_put_notify{
ELLNODE node;
PUTNOTIFY dbPutNotify;
unsigned long valueSize; /* size of block pointed to by dbPutNotify */
void (*caUserCallback)(struct event_handler_args);
void *caUserArg;
struct ca_static *pcas;
int busy;
}CACLIENTPUTNOTIFY;
#endif /*vxWorks*/
#define MAX_CONTIGUOUS_MSG_COUNT 2
/*
* ! lock needs to be applied when an id is allocated !
*/
#define CLIENT_ID_WIDTH 20 /* bits (1 million before rollover) */
#define CLIENT_ID_COUNT (1<<CLIENT_ID_WIDTH)
#define CLIENT_ID_MASK (CLIENT_ID_COUNT-1)
#define CLIENT_ID_ALLOC (CLIENT_ID_MASK&nextBucketId++)
#define SEND_RETRY_COUNT_INIT 100
#define iiuList (ca_static->ca_iiuList)
#define piiuCast (ca_static->ca_piiuCast)
#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 ioeventlist (ca_static->ca_ioeventlist)
#define nxtiiu (ca_static->ca_nxtiiu)
#define free_event_list (ca_static->ca_free_event_list)
#define pend_read_list (ca_static->ca_pend_read_list)
#define pend_write_list (ca_static->ca_pend_write_list)
#define fd_register_func\
(ca_static->ca_fd_register_func)
#define fd_register_arg (ca_static->ca_fd_register_arg)
#define post_msg_active (ca_static->ca_post_msg_active)
#define send_msg_active (ca_static->ca_send_msg_active)
#define sprintf_buf (ca_static->ca_sprintf_buf)
#define pBucket (ca_static->ca_pBucket)
#define nextBucketId (ca_static->ca_nextBucketId)
#if defined(UNIX) || defined(vxWorks)
# define readch (ca_static->ca_readch)
# define writech (ca_static->ca_writech)
#endif
#if defined(UNIX)
#else
# if defined(vxWorks)
# define io_done_sem (ca_static->ca_io_done_sem)
# define evuser (ca_static->ca_evuser)
# define client_lock (ca_static->ca_client_lock)
# define event_lock (ca_static->ca_event_lock)
# define local_chidlist (ca_static->ca_local_chidlist)
# define dbfree_ev_list (ca_static->ca_dbfree_ev_list)
# define lcl_buff_list (ca_static->ca_lcl_buff_list)
# define event_tid (ca_static->ca_event_tid)
# else
# if defined(VMS)
# define io_done_flag (ca_static->ca_io_done_flag)
# define peek_ast_buf (ca_static->ca_peek_ast_buf)
# define ast_lock_count (ca_static->ca_ast_lock_count)
# else
DONT_COMPILE
# endif
# endif
#endif
/*
* one for each task that does a ca import
*/
typedef struct task_var_list{
ELLNODE node;
int tid;
}TVIU;
/*
* Ring buffering for both sends and recvs
*/
struct ca_buffer{
char buf[MAX_MSG_SIZE]; /* from iocmsg.h */
unsigned long max_msg;
unsigned long rdix;
unsigned long wtix;
int readLast;
};
#define CAC_RING_BUFFER_INIT(PRBUF, SIZE) \
assert((SIZE)>sizeof((PRBUF)->buf)); \
(PRBUF)->max_msg = (SIZE); \
(PRBUF)->rdix = 0; \
(PRBUF)->wtix = 0; \
(PRBUF)->readLast = TRUE;
#define CAC_RING_BUFFER_READ_ADVANCE(PRBUF, DELTA) \
( (PRBUF)->readLast = TRUE, \
((PRBUF)->rdix += (DELTA)) >= (PRBUF)->max_msg ? \
(PRBUF)->rdix = 0 : \
(PRBUF)->rdix \
)
#define CAC_RING_BUFFER_WRITE_ADVANCE(PRBUF, DELTA) \
( (PRBUF)->readLast = FALSE, \
((PRBUF)->wtix += (DELTA)) >= (PRBUF)->max_msg ? \
(PRBUF)->wtix = 0 : \
(PRBUF)->wtix \
)
/*
* One per IOC
*/
typedef struct ioc_in_use{
ELLNODE node;
struct ca_static *pcas;
unsigned minor_version_number;
unsigned contiguous_msg_count;
unsigned client_busy;
char active;
int sock_proto;
struct sockaddr_in sock_addr;
int sock_chan;
struct ca_buffer send;
struct ca_buffer recv;
struct extmsg curMsg;
unsigned curMsgBytes;
void *pCurData;
unsigned long curDataMax;
unsigned long curDataBytes;
#ifdef __STDC__
void (*sendBytes)(struct ioc_in_use *);
void (*recvBytes)(struct ioc_in_use *);
void (*procInput)(struct ioc_in_use *);
#else /*__STDC__*/
void (*sendBytes)();
void (*recvBytes)();
void (*procInput)();
#endif /*__STDC__*/
unsigned read_seq;
unsigned cur_read_seq;
ELLLIST chidlist; /* chans on this connection */
short conn_up; /* boolean: T-conn /F-disconn */
short send_needed; /* CA needs a send */
char host_name_str[32];
unsigned nconn_tries;
unsigned send_retry_count;
ca_time next_retry;
ca_time retry_delay;
#ifdef VMS /* for qio ASTs */
unsigned long putConvertBufSize;
void *pPutConvertBuf;
struct sockaddr_in recvfrom;
struct iosb iosb;
#endif /*VMS*/
#ifdef UNIX
#endif /*UNIX*/
#ifdef vxWorks
#endif /*vxWorks*/
}IIU;
struct ca_static{
IIU *ca_piiuCast;
ELLLIST ca_iiuList;
ELLLIST ca_ioeventlist;
ELLLIST ca_free_event_list;
ELLLIST ca_pend_read_list;
ELLLIST ca_pend_write_list;
ELLLIST activeCASG;
ELLLIST freeCASG;
ELLLIST activeCASGOP;
ELLLIST freeCASGOP;
long ca_pndrecvcnt;
void (*ca_exception_func)();
void *ca_exception_arg;
void (*ca_connection_func)();
void *ca_connection_arg;
void (*ca_fd_register_func)();
void *ca_fd_register_arg;
short ca_exit_in_progress;
unsigned short ca_post_msg_active;
short ca_repeater_contacted;
unsigned short ca_send_msg_active;
struct in_addr ca_castaddr;
char ca_sprintf_buf[256];
BUCKET *ca_pBucket;
unsigned long ca_nextBucketId;
bhe *ca_beaconHash[BHT_INET_ADDR_MASK+1];
char *ca_pUserName;
char *ca_pLocationName;
#if defined(UNIX) || defined(vxWorks)
fd_set ca_readch;
fd_set ca_writech;
#endif
#if defined(VMS)
int ca_io_done_flag;
char ca_peek_ast_buf;
long ca_ast_lock_count;
#endif
#if defined(vxWorks)
SEM_ID ca_io_done_sem;
SEM_ID ca_blockSem;
void *ca_evuser;
SEM_ID ca_client_lock;
SEM_ID ca_event_lock; /* dont allow events to preempt */
SEM_ID ca_putNotifyLock;
int ca_tid;
ELLLIST ca_local_chidlist;
ELLLIST ca_dbfree_ev_list;
ELLLIST ca_lcl_buff_list;
ELLLIST ca_putNotifyQue;
int ca_event_tid;
unsigned ca_local_ticks;
int recv_tid;
ELLLIST ca_taskVarList;
#endif
};
/*
GLOBAL VARIABLES
There should only be one - add others to ca_static above -joh
*/
#ifdef CA_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;
/*
* CA internal functions
*
*/
#ifdef __STDC__
void cac_send_msg();
void ca_mux_io(struct timeval *ptimeout, int flags);
int repeater_installed();
void build_msg(chid chix, int reply_type);
int ca_request_event(evid monix);
void ca_busy_message(struct ioc_in_use *piiu);
void ca_ready_message(struct ioc_in_use *piiu);
void noop_msg(struct ioc_in_use *piiu);
void issue_claim_channel(struct ioc_in_use *piiu, chid pchan);
void issue_identify_client(struct ioc_in_use *piiu);
void issue_identify_client_location(struct ioc_in_use *piiu);
int ca_defunct(void);
int ca_printf(char *pformat, ...);
void manage_conn(int silent);
void mark_server_available(struct in_addr *pnet_addr);
void flow_control(struct ioc_in_use *piiu);
int broadcast_addr(struct in_addr *pcastaddr);
int local_addr(int s, struct sockaddr_in *plcladdr);
int ca_repeater_task();
void cac_recv_task(int tid);
void cac_io_done(int lock);
void ca_sg_init(void);
void ca_sg_shutdown(struct ca_static *ca_temp);
int ca_select_io(struct timeval *ptimeout, int flags);
void host_from_addr(
struct in_addr *pnet_addr,
char *pBuf,
unsigned size
);
int post_msg(
struct ioc_in_use *piiu,
struct in_addr *pnet_addr,
char *pInBuf,
unsigned long blockSize
);
int alloc_ioc(
struct in_addr *pnet_addr,
int net_proto,
struct ioc_in_use **ppiiu
);
unsigned long cacRingBufferWrite(
struct ca_buffer *pRing,
void *pBuf,
unsigned long nBytes);
unsigned long cacRingBufferRead(
struct ca_buffer *pRing,
void *pBuf,
unsigned long nBytes);
unsigned long cacRingBufferWriteSize(struct ca_buffer *pBuf, int contiguous);
unsigned long cacRingBufferReadSize(struct ca_buffer *pBuf, int contiguous);
char *localUserName();
char *localLocationName();
#else /*__STDC__*/
int ca_defunct();
int repeater_installed();
void cac_send_msg();
void build_msg();
int broadcast_addr();
int local_addr();
void manage_conn();
void noop_msg();
void ca_busy_message();
void ca_ready_message();
void flow_control();
void host_from_addr();
int ca_repeater_task();
void mark_server_available();
void issue_claim_channel();
int ca_request_event();
void cac_io_done();
int post_msg();
int alloc_ioc();
int ca_printf();
void cac_recv_task();
void ca_sg_init();
void ca_sg_shutdown();
void issue_identify_client();
void issue_identify_client_location();
void ca_mux_io();
int ca_select_io();
unsigned long cacRingBufferRead();
unsigned long cacRingBufferWrite();
unsigned long cacRingBufferWriteSize();
unsigned long cacRingBufferReadSize();
char *localUserName();
char *localLocationName();
#endif /*__STDC__*/
/*
* !!KLUDGE!!
*
* this was extracted from dbAccess.h because we are unable
* to include both dbAccess.h and db_access.h at the
* same time.
*/
#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/
#endif /* this must be the last line in this file */