diff --git a/src/ca/Makefile b/src/ca/Makefile index 8e6b9f089..22c370a1e 100644 --- a/src/ca/Makefile +++ b/src/ca/Makefile @@ -10,6 +10,7 @@ CMPLR = STRICT # INC += cadef.h INC += caerr.h +INC += caeventmask.h INC += caProto.h INC += db_access.h diff --git a/src/ca/cadef.h b/src/ca/cadef.h new file mode 100644 index 000000000..44273e5fa --- /dev/null +++ b/src/ca/cadef.h @@ -0,0 +1,1069 @@ +/* + * $Id$ + * + * 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. + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + * + */ + +#ifndef INCLcadefh +#define INCLcadefh + +#include "shareLib.h" + +/* + * auto include of all stuff that cadef.h uses + */ + +/* + * use two ifdef's for trad C compatibility + */ +#ifndef CA_DONT_INCLUDE_STDARGH +#ifdef CAC_ANSI_FUNC_PROTO +#include +#endif +#endif + +#include "caerr.h" +#include "db_access.h" +#include "caeventmask.h" +#include "ellLib.h" +#include "osiThread.h" + +/* + * done in two ifdef steps so that we will remain compatible with + * traditional C + */ +#ifdef __cplusplus +extern "C" { +#define CAC_ANSI_FUNC_PROTO +#endif +#ifdef __STDC__ +#ifndef CAC_ANSI_FUNC_PROTO +#define CAC_ANSI_FUNC_PROTO +#endif +#endif + +typedef void *chid; +typedef chid chanId; /* for when the structures field name is "chid" */ +typedef long chtype; +typedef void *evid; +typedef double ca_real; + +/* Format for the arguments to user connection handlers */ +struct connection_handler_args { + chanId chid; /* Channel id */ + long op; /* External codes for CA op */ +}; + +#ifdef CAC_ANSI_FUNC_PROTO +typedef void caCh(struct connection_handler_args args); +#else /*CAC_ANSI_FUNC_PROTO*/ +typedef void caCh(); +#endif /*CAC_ANSI_FUNC_PROTO*/ + +typedef struct ca_access_rights{ + unsigned read_access:1; + unsigned write_access:1; +}caar; + +/* Format for the arguments to user access rights handlers */ +struct access_rights_handler_args{ + chanId chid; /* Channel id */ + caar ar; /* New access rights state */ +}; + +#ifdef CAC_ANSI_FUNC_PROTO +typedef void caArh(struct access_rights_handler_args args); +#else /*CAC_ANSI_FUNC_PROTO*/ +typedef void caArh(); +#endif /*CAC_ANSI_FUNC_PROTO*/ + +/* The conversion routine to call for each type */ +#define VALID_TYPE(TYPE) (((unsigned short)TYPE)<=LAST_BUFFER_TYPE) + + +/* + * Arguments passed to event handlers and get/put call back handlers. + * + * The status field below is the CA ECA_XXX status of the requested + * operation which is saved from when the operation was attempted in the + * server and copied back to the clients call back routine. + * If the status is not ECA_NORMAL then the dbr pointer will be NULL + * and the requested operation can not be assumed to be successful. + */ +typedef struct event_handler_args{ + void *usr; /* User argument supplied when event added */ + chanId chid; /* Channel id */ + long type; /* the type of the value returned */ + long count; /* the element count of the item returned */ + READONLY void *dbr; /* Pointer to the value returned */ + int status; /* ECA_XXX Status of the requested op from server */ +}evargs; + + +epicsShareFunc void epicsShareAPI ca_test_event + ( +#ifdef CAC_ANSI_FUNC_PROTO + struct event_handler_args +#endif /*CAC_ANSI_FUNC_PROTO*/ + ); + +/* Format for the arguments to user exception handlers */ +struct exception_handler_args{ + void *usr; /* User argument supplied when event added */ + chanId chid; /* Channel id (may be NULL) */ + long type; /* Requested type for the operation */ + long count; /* Requested count for the operation */ + void *addr; /* User's address to write results of CA_OP_GET */ + long stat; /* Channel access std status code */ + long op; /* External codes for channel access operations */ + READONLY char *ctx; /* A character string containing context info */ + READONLY char *pFile; /* source file name (may be NULL) */ + unsigned lineNo; /* source file line number */ +}; + +typedef unsigned CA_SYNC_GID; + +/* + * External OP codes for CA operations + */ +#define CA_OP_GET 0 +#define CA_OP_PUT 1 +#define CA_OP_SEARCH 2 +#define CA_OP_ADD_EVENT 3 +#define CA_OP_CLEAR_EVENT 4 +#define CA_OP_OTHER 5 +#define CA_OP_CONN_UP 6 +#define CA_OP_CONN_DOWN 7 + +/* + * provides efficient test and display of channel access errors + */ +#define SEVCHK(CA_ERROR_CODE, MESSAGE_STRING) \ +{ \ + int ca_unique_status_name = (CA_ERROR_CODE); \ + if(!(ca_unique_status_name & CA_M_SUCCESS)) \ + ca_signal_with_file_and_lineno( \ + ca_unique_status_name, \ + (MESSAGE_STRING), \ + __FILE__, \ + __LINE__); \ +} + +#ifdef CAC_ANSI_FUNC_PROTO + +#define TYPENOTCONN (-1) /* the channel's native type when disconnected */ +epicsShareFunc short epicsShareAPI ca_field_type (chid chan); +epicsShareFunc unsigned long epicsShareAPI ca_element_count (chid chan); +epicsShareFunc const char * epicsShareAPI ca_name (chid chan); +epicsShareFunc void epicsShareAPI ca_set_puser (chid chan, void *puser); +epicsShareFunc unsigned epicsShareAPI ca_read_access (chid chan); +epicsShareFunc unsigned epicsShareAPI ca_write_access (chid chan); + +/* + * cs_ - `channel state' + * + * cs_never_conn valid chid, IOC not found + * cs_prev_conn valid chid, IOC was found, but unavailable + * cs_conn valid chid, IOC was found, still available + * cs_closed channel deleted by user + */ +enum channel_state {cs_never_conn, cs_prev_conn, cs_conn, cs_closed}; +epicsShareFunc enum channel_state epicsShareAPI ca_state (chid chan); + +/************************************************************************/ +/* Perform Library Initialization */ +/* */ +/* Must be called once before calling any of the other routines */ +/************************************************************************/ +epicsShareFunc int epicsShareAPI ca_task_initialize (void); + +/************************************************************************/ +/* Remove CA facility from your task */ +/* */ +/* Normally called automatically at task exit */ +/************************************************************************/ +epicsShareFunc int epicsShareAPI ca_task_exit (void); + +/************************************************************************ + * anachronistic entry points * + * **** Fetching a value while searching no longer supported**** * + ************************************************************************/ +#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ +ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) + +#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\ +ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) + + +/************************************************************************/ +/* Return a channel identification for the supplied channel name */ +/* (and attempt to create a virtual circuit) */ +/************************************************************************/ + +/* + * ca_search() + * + * a preferred search request API + * + * pChanName R channel name string + * pChanID RW channel id written here + */ +#define ca_search(pChanName, pChanID)\ +ca_search_and_connect(pChanName, pChanID, 0, 0) + + +/* + * ca_search_and_connect() + * + * a preferred search request API + * + * pChanName R channel name string + * pChanID RW channel id written here + * pFunc R address of connection call-back function + * pArg R placed in the channel's puser field + * (fetched later by ca_puser(CHID)) + * (passed as void * arg to (*pFunc)() above) + */ +epicsShareFunc int epicsShareAPI ca_search_and_connect +( + READONLY char *pChanName, + chid *pChanID, + void (*pFunc)(struct connection_handler_args), + void *pArg +); + +/* + * anachronistic entry point + * **** Fetching a value while searching no longer supported **** + * + * pChanName R channel name string + * pChanID RW channel id written here + * pFunc R address of connection call-back function + * pArg R placed in the channel's puser field + * (fetched later by ca_puser(CHID)) + * (passed as void * arg to (*pFunc)() above) + */ +epicsShareFunc int epicsShareAPI ca_build_and_connect +( + READONLY char *pChanName, + chtype, /* pass TYPENOTCONN */ + unsigned long, /* pass 0 */ + chid *pChanID, + void *, /* pass NULL */ + void (*pFunc)(struct connection_handler_args), + READONLY void *pArg +); + +/* + * ca_change_connection_event() + * + * chan R channel identifier + * pfunc R address of connection call-back function + */ +epicsShareFunc int epicsShareAPI ca_change_connection_event +( + chid chan, + void (*pfunc)(struct connection_handler_args) +); + +/* + * ca_replace_access_rights_event () + * + * chan R channel identifier + * pfunc R address of access rights call-back function + */ +epicsShareFunc int epicsShareAPI ca_replace_access_rights_event( + chid chan, + void (*pfunc)(struct access_rights_handler_args) +); + +/* + * ca_add_exception_event () + * + * replace the default exception handler + * + * pfunc R address of exception call-back function + * pArg R copy of this pointer passed to exception + * call-back function + */ +epicsShareFunc int epicsShareAPI ca_add_exception_event +( + void (*pfunc) (struct exception_handler_args), + READONLY void *pArg +); + +/* + * ca_clear_channel() + * - deallocate resources reserved for a channel + * + * chanId R channel ID + */ +epicsShareFunc int epicsShareAPI ca_clear_channel +( + chid chanId +); + +/************************************************************************/ +/* Write a value to a channel */ +/************************************************************************/ +/* + * ca_bput() + * + * WARNING: this copies the new value from a string (dbr_string_t) + * (and not as an integer) + * + * chan R channel identifier + * pValue R new channel value string copied from this location + */ +#define ca_bput(chan, pValue) \ +ca_array_put(DBR_STRING, 1u, chan, (READONLY dbr_string_t *) (pValue)) + +/* + * ca_rput() + * + * WARNING: this copies the new value from a dbr_float_t + * + * chan R channel identifier + * pValue R new channel value copied from this location + */ +#define ca_rput(chan,pValue) \ +ca_array_put(DBR_FLOAT, 1u, chan, (READONLY dbr_float_t *) pValue) + +/* + * ca_put() + * + * type R data type from db_access.h + * chan R channel identifier + * pValue R new channel value copied from this location + */ +#define ca_put(type, chan, pValue) ca_array_put(type, 1u, chan, pValue) + +/* + * ca_array_put() + * + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pValue R new channel value copied from this location + */ +epicsShareFunc int epicsShareAPI ca_array_put +( + chtype type, + unsigned long count, + chid chanId, + READONLY void *pValue +); + +/* + * ca_array_put_callback() + * + * This routine functions identically to the original ca put request + * with the addition of a callback to the user supplied function + * after recod processing completes in the IOC. The arguments + * to the user supplied callback function are declared in + * the structure event_handler_args and include the pointer + * sized user argument supplied when ca_array_put_callback() is called. + * + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pValue R new channel value copied from this location + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + */ +epicsShareFunc int epicsShareAPI ca_array_put_callback +( + chtype type, + unsigned long count, + chid chanId, + READONLY void *pValue, + void (*pFunc)(struct event_handler_args), + void *pArg +); + +#define ca_put_callback(type, chan, pValue, pFunc, pArg) \ + ca_array_put_callback(type, 1u, chan, pValue, pFunc, pArg) + +/************************************************************************/ +/* Read a value from a channel */ +/************************************************************************/ + +/* + * ca_bget() + * + * WARNING: this copies the new value into a string (dbr_string_t) + * (and not into an integer) + * + * chan R channel identifier + * pValue W channel value copied to this location + */ +#define ca_bget(chan, pValue) \ +ca_array_get(DBR_STRING, 1u, chan, (dbr_string_t *)(pValue)) + +/* + * ca_rget() + * + * WARNING: this copies the new value into a 32 bit float (dbr_float_t) + * + * chan R channel identifier + * pValue W channel value copied to this location + */ +#define ca_rget(chan, pValue) \ +ca_array_get(DBR_FLOAT, 1u, chan, (dbr_float_t *)(pValue)) + +/* + * ca_rget() + * + * type R data type from db_access.h + * chan R channel identifier + * pValue W channel value copied to this location + */ +#define ca_get(type, chan, pValue) ca_array_get(type, 1u, chan, pValue) + +/* + * ca_array_get() + * + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pValue W channel value copied to this location + */ +epicsShareFunc int epicsShareAPI ca_array_get +( + chtype type, + unsigned long count, + chid chanId, + void *pValue +); + +/************************************************************************/ +/* Read a value from a channel and run a callback when the value */ +/* returns */ +/* */ +/* */ +/************************************************************************/ +/* + * ca_bget_callback() + * + * WARNING: this returns the new value as a string (dbr_string_t) + * (and not as an integer) + * + * chan R channel identifier + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + */ +#define ca_bget_callback(chan, pFunc, pArg)\ +ca_array_get_callback(DBR_STRING, 1u, chan, pFunc, pArg) + +/* + * ca_rget_callback() + * + * WARNING: this returns the new value as a float (dbr_float_t) + * + * chan R channel identifier + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + */ +#define ca_rget_callback(chan, pFunc, pArg)\ +ca_array_get_callback(DBR_FLOAT, 1u, chan, pFunc, pArg) + +/* + * ca_get_callback() + * + * type R data type from db_access.h + * chan R channel identifier + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + */ +#define ca_get_callback(type, chan, pFunc, pArg)\ +ca_array_get_callback(type, 1u, chan, pFunc, pArg) + +/* + * ca_array_get_callback() + * + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + */ +epicsShareFunc int epicsShareAPI ca_array_get_callback +( + chtype type, + unsigned long count, + chid chanId, + void (*pFunc)(struct event_handler_args), + void *pArg +); + +/************************************************************************/ +/* Specify a function to be executed whenever significant changes */ +/* occur to a channel. */ +/* NOTES: */ +/* 1) Evid may be omited by passing a NULL pointer */ +/* */ +/* 2) An array count of zero specifies the native db count */ +/* */ +/************************************************************************/ + +/* + * ca_add_event () + * + * assumes "delta" info comes from the database or defaults + * + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + * pEventID W event id written at specified address + */ +#define ca_add_event(type,chan,pFunc,pArg,pEventID)\ +ca_add_array_event(type,1u,chan,pFunc,pArg,0.0,0.0,0.0,pEventID) + + +/* Sets both P_DELTA and M_DELTA below to argument DELTA */ +#define ca_add_delta_event(TYPE,CHID,ENTRY,ARG,DELTA,EVID)\ + ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,DELTA,DELTA,0.0,EVID) + +#define ca_add_general_event(TYPE,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ +ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID) + +#define ca_add_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ +ca_add_masked_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID, DBE_VALUE | DBE_ALARM) + +/* + * ca_add_masked_array_event () + * + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pFunc R pointer to call-back function + * pArg R copy of this pointer passed to pFunc + * p_delta R not currently used (set to 0.0) + * n_delta R not currently used (set to 0.0) + * timeout R not currently used (set to 0.0) + * pEventID W event id written at specified address + * mask R event mask - one of {DBE_VALUE, DBE_ALARM, DBE_LOG} + */ +epicsShareFunc int epicsShareAPI ca_add_masked_array_event +( + chtype type, + unsigned long count, + chid chanId, + void (*pFunc)(struct event_handler_args), + void *pArg, + ca_real p_delta, + ca_real n_delta, + ca_real timeout, + evid *pEventID, + long mask +); + +/************************************************************************/ +/* Remove a function from a list of those specified to run */ +/* whenever significant changes occur to a channel */ +/* */ +/************************************************************************/ +/* + * ca_clear_event() + * + * eventID R event id + */ +epicsShareFunc int epicsShareAPI ca_clear_event +( + evid eventID +); + + +/************************************************************************/ +/* */ +/* Requested data is not necessarily stable prior to */ +/* return from called subroutine. Call ca_pend_io() */ +/* to guarantee that requested data is stable. Call the routine */ +/* ca_flush_io() to force all outstanding requests to be */ +/* sent out over the network. Significant increases in */ +/* performance have been measured when batching several remote */ +/* requests together into one message. Additional */ +/* improvements can be obtained by performing local processing */ +/* in parallel with outstanding remote processing. */ +/* */ +/* FLOW OF TYPICAL APPLICATION */ +/* */ +/* search() ! Obtain Channel ids */ +/* . ! " */ +/* . ! " */ +/* pend_io ! wait for channels to connect */ +/* */ +/* get() ! several requests for remote info */ +/* get() ! " */ +/* add_event() ! " */ +/* get() ! " */ +/* . */ +/* . */ +/* . */ +/* flush_io() ! send get requests */ +/* ! optional parallel processing */ +/* . ! " */ +/* . ! " */ +/* pend_io() ! wait for replies from get requests */ +/* . ! access to requested data */ +/* . ! " */ +/* pend_event() ! wait for requested events */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* This routine pends waiting for channel events and calls the */ +/* functions specified with add_event when events occur. If the */ +/* timeout is specified as 0 an infinite timeout is assumed. */ +/* if the argument early is specified TRUE then CA_NORMAL is */ +/* returned when outstanding queries complete. Otherwise if the */ +/* argument early is FALSE the routine does not return until the */ +/* entire delay specified by the timeout argument has expired. */ +/* ca_flush_io() is called by this routine. If the argument */ +/* early is TRUE then ca_pend() will return immediately without */ +/* processing outstanding CA labor if no queries are outstanding */ +/************************************************************************/ +#define ca_poll() ca_pend((1e-12), 0/*FALSE*/) +#define ca_pend_event(TIMEOUT) ca_pend((TIMEOUT), 0/*FALSE*/) +#define ca_pend_io(TIMEOUT) ca_pend((TIMEOUT), 1/*TRUE*/) + +/* + * ca_pend() + * + * timeOut R delay in seconds + * early R T: return early if all get requests (or search + * requests with null connection handler pointer + * have completed) + * F: wait for the entire delay to expire + */ +epicsShareFunc int epicsShareAPI ca_pend +( + ca_real timeOut, + int early +); + +/* + * ca_test_io() + * + * returns TRUE when get requests (or search requests with null + * connection handler pointer) are outstanding + */ +epicsShareFunc int epicsShareAPI ca_test_io (void); + +/************************************************************************/ +/* Send out all outstanding messages in the send queue */ +/************************************************************************/ +/* + * ca_flush_io() + */ +epicsShareFunc int epicsShareAPI ca_flush_io (void); + + +/* + * ca_signal() + * + * errorCode R status returned from channel access function + * pCtxStr R context string included with error print out + */ +epicsShareFunc void epicsShareAPI ca_signal +( + long errorCode, + READONLY char *pCtxStr +); + +/* + * ca_signal_with_file_and_lineno() + * errorCode R status returned from channel access function + * pCtxStr R context string included with error print out + * pFileStr R file name string included with error print out + * lineNo R line number included with error print out + * + */ +epicsShareFunc void epicsShareAPI ca_signal_with_file_and_lineno +( + long errorCode, + READONLY char *pCtxStr, + READONLY char *pFileStr, + int lineNo +); + +/* + * ca_signal_formated() + * errorCode R status returned from channel access function + * pFileStr R file name string included with error print out + * lineNo R line number included with error print out + * pFormat R printf dtyle format string (and optional arguments) + * + */ +epicsShareFunc void epicsShareAPI ca_signal_formated (long ca_status, READONLY char *pfilenm, + int lineno, READONLY char *pFormat, ...); + +/* + * ca_host_name_function() + * + * channel R channel identifier + */ +epicsShareFunc READONLY char * epicsShareAPI ca_host_name (chid channel); + +/* + * CA_ADD_FD_REGISTRATION + * + * call their function with their argument whenever + * a new fd is added or removed + * (for use with a manager of the select system call under UNIX) + * + * if (opened) then fd was created + * if (!opened) then fd was deleted + * + */ +typedef void CAFDHANDLER (void *parg, int fd, int opened); + +/* + * ca_add_fd_registration() + * + * pHandler R pointer to function which is to be called + * when an fd is created or deleted + * pArg R argument passed to above function + */ +epicsShareFunc int epicsShareAPI ca_add_fd_registration +( + CAFDHANDLER *pHandler, + READONLY void *pArg +); + + +/* + * CA synch groups + * + * This facility will allow the programmer to create + * any number of synchronization groups. The programmer might then + * interleave IO requests within any of the groups. Once The + * IO operations are initiated then the programmer is free to + * block for IO completion within any one of the groups as needed. + */ + +/* + * ca_sg_create() + * + * create a sync group + * + * pgid W pointer to sync group id that will be written + */ +epicsShareFunc int epicsShareAPI ca_sg_create (CA_SYNC_GID * pgid); + +/* + * ca_sg_delete() + * + * delete a sync group + * + * gid R sync group id + */ +epicsShareFunc int epicsShareAPI ca_sg_delete (READONLY CA_SYNC_GID gid); + +/* + * ca_sg_block() + * + * block for IO performed within a sync group to complete + * + * gid R sync group id + * timeout R wait for this duration prior to timing out + * and returning ECA_TIMEOUT + */ +epicsShareFunc int epicsShareAPI ca_sg_block (READONLY CA_SYNC_GID gid, ca_real timeout); + +/* + * ca_sg_test() + * + * test for sync group IO operations in progress + * + * gid R sync group id + * + * returns one of ECA_BADSYNCGRP, ECA_IOINPROGRESS, ECA_IODONE + */ +epicsShareFunc int epicsShareAPI ca_sg_test (READONLY CA_SYNC_GID gid); + +/* + * ca_sg_reset + * + * gid R sync group id + */ +epicsShareFunc int epicsShareAPI ca_sg_reset(READONLY CA_SYNC_GID gid); + +/* + * ca_sg_array_get() + * + * initiate a get within a sync group + * (essentially a ca_array_get() with a sync group specified) + * + * gid R sync group id + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pValue W channel value copied to this location + */ +epicsShareFunc int epicsShareAPI ca_sg_array_get +( + READONLY CA_SYNC_GID gid, + chtype type, /* TYPE R channel type */ + unsigned long count, + chid chan, + void *pValue +); + +#define ca_sg_get(gid, type, chan, pValue) \ +ca_sg_array_get (gid, type, 1u, chan, pValue) + +/* + * ca_sg_array_put() + * + * initiate a put within a sync group + * (essentially a ca_array_put() with a sync group specified) + * + * gid R sync group id + * type R data type from db_access.h + * count R array element count + * chan R channel identifier + * pValue R new channel value copied from this location + */ +epicsShareFunc int epicsShareAPI ca_sg_array_put +( + READONLY CA_SYNC_GID gid, + chtype type, + unsigned long count, + chid chan, + READONLY void *pValue +); + +#define ca_sg_put(gid, type, chan, pValue) \ +ca_sg_array_put (gid, type, 1u, chan, pValue) + +/* + * ca_sg_stat() + * + * print status of a sync group + * + * gid R sync group id + */ +epicsShareFunc int epicsShareAPI ca_sg_stat (READONLY CA_SYNC_GID gid); + +/* + * ca_modify_user_name() + * + * Modify or override the default + * client user name. + * + * pUserName R new user name string copied from this location + */ +epicsShareFunc int epicsShareAPI ca_modify_user_name (READONLY char *pUserName); + +/* + * CA_MODIFY_HOST_NAME() + * + * Modify or override the default + * client host name. + * + * pHostName R new host name string copied from this location + */ +epicsShareFunc int epicsShareAPI ca_modify_host_name (READONLY char *pHostName); + +/* + * ca_v42_ok() + * + * Put call back is available if the CA server is on version is 4.2 + * or higher. + * + * chan R channel identifier + * + * (returns true or false) + */ +epicsShareFunc int epicsShareAPI ca_v42_ok (chid chan); + +/* + * ca_version() + * + * returns the CA version string + */ +epicsShareFunc READONLY char * epicsShareAPI ca_version (void); + +/* + * ca_replace_printf_handler () + * + * for apps that want to change where ca formatted + * text output goes + * + * use two ifdef's for trad C compatibility + * + * ca_printf_func R pointer to new function called when + * CA prints an error message + */ +#ifndef CA_DONT_INCLUDE_STDARGH +epicsShareFunc int epicsShareAPI ca_replace_printf_handler ( + int (*ca_printf_func)(READONLY char *pformat, va_list args) +); +#endif /*CA_DONT_INCLUDE_STDARGH*/ + +/* + * (for testing purposes only) + */ +epicsShareFunc unsigned epicsShareAPI ca_get_ioc_connection_count (void); +epicsShareFunc unsigned epicsShareAPI ca_search_attempts (chid chan); + +/* + * Warning - this is an temporary CA client API + * which will probably vanish in the future. + */ +typedef void * pvId; +typedef void * putNotifyId; +struct db_field_log; +struct putNotify; +typedef struct pvAdapter { + pvId (*p_pvNameToId) (READONLY char *pname); + int (*p_pvPutField) (pvId, int src_type, + READONLY void *psrc, int no_elements); + int (*p_pvGetField) (pvId, int dest_type, + void *pdest, int no_elements, void *pfl); + long (*p_pvPutNotifyInitiate) (pvId, unsigned type, unsigned long count, + const void *pValue, void (*callback)(void *), void *usrPvt, putNotifyId * pID); + void (*p_pvPutNotifyDestroy) (putNotifyId); + const char * (*p_pvName) (pvId); + unsigned long (*p_pvNoElements) (pvId); + short (*p_pvType) (pvId); + void * (*p_pvEventQueueInit) (void); + int (*p_pvEventQueueStart) (void *, const char *taskname, + void (*init_func)(void *), void *init_func_arg, int priority_offset); + void (*p_pvEventQueueClose) (void *); + int (*p_pvEventQueuePostSingleEvent) (void *es); + void * (*p_pvEventQueueAddEvent) (void *ctx, pvId id, + void (*user_sub)(void *usrArg, pvId id, int eventsRemaining, struct db_field_log *), + void *user_arg, unsigned select); + void (*p_pvEventQueueCancelEvent) (void *es); + int (*p_pvEventQueueAddExtraLaborEvent) (void *, void (*func)(void *), void *arg); + int (*p_pvEventQueuePostExtraLabor) (void *ctx); +} pvAdapter; +epicsShareFunc void * epicsShareAPI ca_create_context (pvAdapter *pAdapter); + +/* + * used when an auxillary thread needs to join a CA client context started + * by another thread + */ +typedef void * caClientCtx; +epicsShareFunc int epicsShareAPI ca_current_context (caClientCtx *pCurrentContext); +epicsShareFunc int epicsShareAPI ca_attach_context (caClientCtx context); + +epicsShareFunc int epicsShareAPI ca_channel_status (threadId tid); + +/* + * deprecated + */ +epicsShareFunc int epicsShareAPI ca_import (threadId tid); +epicsShareFunc int epicsShareAPI ca_import_cancel (threadId tid); + + +#else /* CAC_ANSI_FUNC_PROTO */ +epicsShareFunc short epicsShareAPI ca_get_field_type (); +epicsShareFunc unsigned long epicsShareAPI ca_element_count (); +epicsShareFunc char * epicsShareAPI ca_name (chid chan); +epicsShareFunc enum channel_state epicsShareAPI ca_state (); +epicsShareFunc void epicsShareAPI ca_set_puser (); +epicsShareFunc unsigned epicsShareAPI ca_read_access (); +epicsShareFunc unsigned epicsShareAPI ca_write_access (); +epicsShareFunc int epicsShareAPI ca_task_initialize (); +epicsShareFunc int epicsShareAPI ca_task_exit (); +epicsShareFunc int epicsShareAPI ca_search_and_connect (); +epicsShareFunc int epicsShareAPI ca_build_and_connect (); +epicsShareFunc int epicsShareAPI ca_change_connection_event (); +epicsShareFunc int epicsShareAPI ca_replace_access_rights_event (); +epicsShareFunc int epicsShareAPI ca_add_exception_event (); +epicsShareFunc int epicsShareAPI ca_clear_channel (); +epicsShareFunc int epicsShareAPI ca_array_put (); +epicsShareFunc int epicsShareAPI ca_array_put_callback (); +epicsShareFunc int epicsShareAPI ca_array_get (); +epicsShareFunc int epicsShareAPI ca_array_get_callback (); +epicsShareFunc int epicsShareAPI ca_add_masked_array_event (); +epicsShareFunc int epicsShareAPI ca_clear_event (); +epicsShareFunc int epicsShareAPI ca_pend (); +epicsShareFunc int epicsShareAPI ca_test_io (); +epicsShareFunc int epicsShareAPI ca_flush_io (); +epicsShareFunc void epicsShareAPI ca_signal (); +epicsShareFunc void epicsShareAPI ca_signal_with_file_and_lineno (); +epicsShareFunc void epicsShareAPI ca_signal_formated (); +epicsShareFunc char * epicsShareAPI ca_host_name (); +typedef void CAFDHANDLER(); +epicsShareFunc int epicsShareAPI ca_add_fd_registration(); +epicsShareFunc int epicsShareAPI ca_replace_printf_handler (); +epicsShareFunc int epicsShareAPI ca_sg_create(); +epicsShareFunc int epicsShareAPI ca_sg_delete(); +epicsShareFunc int epicsShareAPI ca_sg_block(); +epicsShareFunc int epicsShareAPI ca_sg_test(); +epicsShareFunc int epicsShareAPI ca_sg_reset(); +epicsShareFunc int epicsShareAPI ca_sg_array_get(); +epicsShareFunc int epicsShareAPI ca_sg_array_put(); +epicsShareFunc int epicsShareAPI ca_sg_stat(); +epicsShareFunc int epicsShareAPI ca_modify_user_name(); +epicsShareFunc int epicsShareAPI ca_modify_host_name(); +epicsShareFunc int epicsShareAPI ca_v42_ok(); +epicsShareFunc char * epicsShareAPI ca_version(); +epicsShareFunc int epicsShareAPI ca_import(); +epicsShareFunc int epicsShareAPI ca_import_cancel(); +epicsShareFunc int epicsShareAPI ca_channel_status (); +#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ + ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) +#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\ + ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) +#define ca_search(pChanName, pChanID)\ + ca_search_and_connect(pChanName, pChanID, 0, 0) +#define ca_bput(chan, pValue) \ + ca_array_put(DBR_STRING, 1, chan, (READONLY dbr_string_t *) (pValue)) +#define ca_rput(chan,pValue) \ + ca_array_put(DBR_FLOAT, 1, chan, (READONLY dbr_float_t *) pValue) +#define ca_put(type, chan, pValue) ca_array_put(type, 1, chan, pValue) +#define ca_bget(chan, pValue) \ + ca_array_get(DBR_STRING, 1, chan, (dbr_string_t *)(pValue)) +#define ca_rget(chan, pValue) \ + ca_array_get(DBR_FLOAT, 1, chan, (dbr_float_t *)(pValue)) +#define ca_get(type, chan, pValue) ca_array_get(type, 1, chan, pValue) +#define ca_bget_callback(chan, pFunc, pArg)\ + ca_array_get_callback(DBR_STRING, 1, chan, pFunc, pArg) +#define ca_rget_callback(chan, pFunc, pArg)\ + ca_array_get_callback(DBR_FLOAT, 1, chan, pFunc, pArg) +#define ca_get_callback(type, chan, pFunc, pArg)\ + ca_array_get_callback(type, 1, chan, pFunc, pArg) +#define ca_put_callback(type, chan, pValue, pFunc, pArg) \ + ca_array_put_callback(type, 1u, chan, pValue, pFunc, pArg) +#define ca_add_event(type,chan,pFunc,pArg,pEventID)\ + ca_add_array_event(type,1,chan,pFunc,pArg,0.0,0.0,0.0,pEventID) +#define ca_add_delta_event(TYPE,CHID,ENTRY,ARG,DELTA,EVID)\ + ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,DELTA,DELTA,0.0,EVID) +#define ca_add_general_event(TYPE,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ + ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID) +#define ca_add_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ +ca_add_masked_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID, DBE_VALUE | DBE_ALARM) +#define ca_poll() ca_pend((1e-12), 0/*FALSE*/) +#define ca_pend_event(TIMEOUT) ca_pend((TIMEOUT), 0/*FALSE*/) +#define ca_pend_io(TIMEOUT) ca_pend((TIMEOUT), 1/*TRUE*/) +#define ca_sg_get(gid, type, chan, pValue) \ +ca_sg_array_get(gid, type, 1u, chan, pValue) +#define ca_sg_put(gid, type, chan, pValue) \ +ca_sg_array_put(gid, type, 1u, chan, pValue) +#endif /* CAC_ANSI_FUNC_PROTO */ + +#ifdef __cplusplus +} +#endif + +/* + * no additions below this endif + */ +#endif /* INCLcadefh */ + diff --git a/src/ca/caerr.h b/src/ca/caerr.h new file mode 100644 index 000000000..5adca223a --- /dev/null +++ b/src/ca/caerr.h @@ -0,0 +1,201 @@ +/* + * + * 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. + * + * Author: Jeffrey O. Hill + * + */ + + +#ifndef INCLcaerrh +#define INCLcaerrh + +#include "shareLib.h" +#include "epicsTypes.h" + +/* CA Status Code Definitions */ + +#define CA_K_INFO 3 /* successful */ +#define CA_K_ERROR 2 /* failed- continue */ +#define CA_K_SUCCESS 1 /* successful */ +#define CA_K_WARNING 0 /* unsuccessful */ +#define CA_K_SEVERE 4 /* failed- quit */ +#define CA_K_FATAL CA_K_ERROR | CA_K_SEVERE + +#define CA_M_MSG_NO 0x0000FFF8 +#define CA_M_SEVERITY 0x00000007 +#define CA_M_LEVEL 0x00000003 +#define CA_M_SUCCESS 0x00000001 +#define CA_M_ERROR 0x00000002 +#define CA_M_SEVERE 0x00000004 + +#define CA_S_MSG_NO 0x0D +#define CA_S_SEVERITY 0x03 + +#define CA_V_MSG_NO 0x03 +#define CA_V_SEVERITY 0x00 +#define CA_V_SUCCESS 0x00 + +/* Define MACROS to extract/insert individual fields from a status value */ + +#define CA_EXTRACT_MSG_NO(code)\ +( ( (code) & CA_M_MSG_NO ) >> CA_V_MSG_NO ) +#define CA_EXTRACT_SEVERITY(code)\ +( ( (code) & CA_M_SEVERITY ) >> CA_V_SEVERITY ) +#define CA_EXTRACT_SUCCESS(code)\ +( ( (code) & CA_M_SUCCESS ) >> CA_V_SUCCESS ) + +#define CA_INSERT_MSG_NO(code)\ +( ((code)<< CA_V_MSG_NO) & CA_M_MSG_NO ) +#define CA_INSERT_SEVERITY(code)\ +( ((code)<< CA_V_SEVERITY)& CA_M_SEVERITY ) +#define CA_INSERT_SUCCESS(code)\ +( ((code)<< CA_V_SUCCESS) & CA_M_SUCCESS ) + + +#define DEFMSG(SEVERITY,NUMBER)\ +(CA_INSERT_MSG_NO(NUMBER) | CA_INSERT_SEVERITY(SEVERITY)) + + +#define ECA_NORMAL DEFMSG(CA_K_SUCCESS, 0) +#define ECA_MAXIOC DEFMSG(CA_K_ERROR, 1) +#define ECA_UKNHOST DEFMSG(CA_K_ERROR, 2) +#define ECA_UKNSERV DEFMSG(CA_K_ERROR, 3) +#define ECA_SOCK DEFMSG(CA_K_ERROR, 4) +#define ECA_CONN DEFMSG(CA_K_WARNING, 5) +#define ECA_ALLOCMEM DEFMSG(CA_K_WARNING, 6) +#define ECA_UKNCHAN DEFMSG(CA_K_WARNING, 7) +#define ECA_UKNFIELD DEFMSG(CA_K_WARNING, 8) +#define ECA_TOLARGE DEFMSG(CA_K_ERROR, 9) +#define ECA_TIMEOUT DEFMSG(CA_K_WARNING, 10) +#define ECA_NOSUPPORT DEFMSG(CA_K_WARNING, 11) +#define ECA_STRTOBIG DEFMSG(CA_K_WARNING, 12) +#define ECA_DISCONNCHID DEFMSG(CA_K_ERROR, 13) +#define ECA_BADTYPE DEFMSG(CA_K_ERROR, 14) +#define ECA_CHIDNOTFND DEFMSG(CA_K_INFO, 15) +#define ECA_CHIDRETRY DEFMSG(CA_K_INFO, 16) +#define ECA_INTERNAL DEFMSG(CA_K_FATAL, 17) +#define ECA_DBLCLFAIL DEFMSG(CA_K_WARNING, 18) +#define ECA_GETFAIL DEFMSG(CA_K_WARNING, 19) +#define ECA_PUTFAIL DEFMSG(CA_K_WARNING, 20) +#define ECA_ADDFAIL DEFMSG(CA_K_WARNING, 21) +#define ECA_BADCOUNT DEFMSG(CA_K_WARNING, 22) +#define ECA_BADSTR DEFMSG(CA_K_ERROR, 23) +#define ECA_DISCONN DEFMSG(CA_K_WARNING, 24) +#define ECA_DBLCHNL DEFMSG(CA_K_WARNING, 25) +#define ECA_EVDISALLOW DEFMSG(CA_K_ERROR, 26) +#define ECA_BUILDGET DEFMSG(CA_K_WARNING, 27) +#define ECA_NEEDSFP DEFMSG(CA_K_WARNING, 28) +#define ECA_OVEVFAIL DEFMSG(CA_K_WARNING, 29) +#define ECA_BADMONID DEFMSG(CA_K_ERROR, 30) +#define ECA_NEWADDR DEFMSG(CA_K_WARNING, 31) +#define ECA_NEWCONN DEFMSG(CA_K_INFO, 32) +#define ECA_NOCACTX DEFMSG(CA_K_WARNING, 33) +#define ECA_DEFUNCT DEFMSG(CA_K_FATAL, 34) +#define ECA_EMPTYSTR DEFMSG(CA_K_WARNING, 35) +#define ECA_NOREPEATER DEFMSG(CA_K_WARNING, 36) +#define ECA_NOCHANMSG DEFMSG(CA_K_WARNING, 37) +#define ECA_DLCKREST DEFMSG(CA_K_WARNING, 38) +#define ECA_SERVBEHIND DEFMSG(CA_K_WARNING, 39) +#define ECA_NOCAST DEFMSG(CA_K_WARNING, 40) +#define ECA_BADMASK DEFMSG(CA_K_ERROR, 41) +#define ECA_IODONE DEFMSG(CA_K_INFO, 42) +#define ECA_IOINPROGRESS DEFMSG(CA_K_INFO, 43) +#define ECA_BADSYNCGRP DEFMSG(CA_K_ERROR, 44) +#define ECA_PUTCBINPROG DEFMSG(CA_K_ERROR, 45) +#define ECA_NORDACCESS DEFMSG(CA_K_WARNING, 46) +#define ECA_NOWTACCESS DEFMSG(CA_K_WARNING, 47) +#define ECA_ANACHRONISM DEFMSG(CA_K_ERROR, 48) +#define ECA_NOSEARCHADDR DEFMSG(CA_K_WARNING, 49) +#define ECA_NOCONVERT DEFMSG(CA_K_WARNING, 50) +#define ECA_BADCHID DEFMSG(CA_K_ERROR, 51) +#define ECA_BADFUNCPTR DEFMSG(CA_K_ERROR, 52) + +#ifndef CA_ERROR_GLBLSOURCE +epicsShareExtern READONLY char *ca_message_text[]; +#else +READONLY char *ca_message_text[] += +{ +"Normal successful completion", +"Maximum simultaneous IOC connections exceeded", +"Unknown internet host", +"Unknown internet service", +"Unable to allocate a new socket", +"Unable to connect to internet host or service", +"Unable to allocate additional dynamic memory", +"Unknown IO channel", +"Record field specified inappropriate for channel specified", +"The array or data structure specified will not fit in CA message buffer", +"User specified timeout on IO operation expired", +"Sorry, that feature is planned but not supported at this time", +"The supplied string is unusually large", +"The request was ignored because the specified channel is disconnected", +"The type you have requested from this channel is unknown", +"Remote Channel not found", +"Unable to locate all user specified channels", +"Channel Access Internal Failure", +"The requested local DB operation failed", +"Could not perform a database value get for that channel", +"Could not perform a database value put for that channel", +"Could not perform a database event add for that channel", +"Count requested inappropriate for that channel", +"The supplied string has improper format", +"Network connection lost", +"Ambiguous channel host (multiple IOC's have a channel by that name)", +"The CA routine called is inappropriate for use within an event handler", +"Database value get for that channel failed during channel search", +"Unable to initialize without the vxWorks VX_FP_TASK task option set", +"Event queue overflow has prevented first pass event after event add", +"A monitor by that id cant be found", +"Remote channel has new network address", +"New or resumed network connection", +"Specified task isnt a member of a CA context", +"Attempt to use defunct CA feature failed", +"The supplied string is empty", +"Unable to spawn the CA repeater thread- auto reconnect will fail", +"No channel id match for search reply- search reply ignored", +"Reseting dead connection- will try to reconnect", +"Server (IOC) has fallen behind or is not responding- still waiting", +"No internet interface with broadcast available", +"The event selection mask supplied is empty or inappropriate", +"IO operations have completed", +"IO operations are in progress", +"Invalid synchronous group identifier", +"Put call back operation collision with put call back operation in progress", +"Read access denied", +"Write access denied", +"Sorry, that anachronistic feature of CA is no longer supported", +"The search request/beacon address list was empty after initialization", +"Data conversion between client's type and the server's type failed", +"Invalid channel identifier", +"Invalid function pointer" +}; +#endif + +#ifdef __STDC__ +#define CAERR_USE_FUNC_PROTO +#endif + +#ifdef __cplusplus +#ifndef CAERR_USE_FUNC_PROTO +#define CAERR_USE_FUNC_PROTO +#endif +extern "C" { +#endif + +#ifdef CAERR_USE_FUNC_PROTO +epicsShareFunc READONLY char * epicsShareAPI ca_message(long ca_status); +#else /* CAERR_USE_FUNC_PROTO */ +READONLY char *ca_message(); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ca/caeventmask.h b/src/ca/caeventmask.h new file mode 100644 index 000000000..e146e0001 --- /dev/null +++ b/src/ca/caeventmask.h @@ -0,0 +1,36 @@ +/* + $Id$ + caeventmask.h + + Modification History + joh 04-16-90 Created + +*/ + +#ifndef INCLcaeventmaskh +#define INCLcaeventmaskh + +/* + event selections + (If any more than 8 of these are needed then update the + select field in the event_block struct in db_event.c from + unsigned char to unsigned short) + + + DBE_VALUE + Trigger an event when a significant change in the channel's value + occurs. Relies on the monitor deadband field under DCT. + + DBE_LOG + Trigger an event when an archive significant change in the channel's + valuue occurs. Relies on the archiver monitor deadband field under DCT. + + DBE_ALARM + Trigger an event when the alarm state changes + +*/ +#define DBE_VALUE (1<<0) +#define DBE_LOG (1<<1) +#define DBE_ALARM (1<<2) + +#endif diff --git a/src/db/db_access.h b/src/ca/db_access.h similarity index 99% rename from src/db/db_access.h rename to src/ca/db_access.h index 9f630b947..ddf4f4709 100644 --- a/src/db/db_access.h +++ b/src/ca/db_access.h @@ -85,7 +85,6 @@ of this distribution. #include "shareLib.h" #include "epicsTypes.h" #include "tsStamp.h" -#include "ellLib.h" #ifdef __cplusplus extern "C" { diff --git a/src/db/Makefile b/src/db/Makefile index 783ddf5b8..e2b53f710 100644 --- a/src/db/Makefile +++ b/src/db/Makefile @@ -21,7 +21,6 @@ INC += db_field_log.h INC += initHooks.h INC += recGbl.h # The following go away what old database access goes away -INC += db_access.h INC += db_access_routines.h INC += db_convert.h diff --git a/src/libCom/Makefile b/src/libCom/Makefile index 9c776f5ff..c5acf3895 100644 --- a/src/libCom/Makefile +++ b/src/libCom/Makefile @@ -82,9 +82,6 @@ SRCS += macUtil.c SRC_DIRS += $(LIBCOM)/misc INC += adjustment.h -INC += cadef.h -INC += caerr.h -INC += caeventmask.h INC += cantProceed.h INC += dbDefs.h INC += epicsString.h diff --git a/src/libCom/logClient/logClient.c b/src/libCom/logClient/logClient.c index edb0a0072..836fc8fd4 100644 --- a/src/libCom/logClient/logClient.c +++ b/src/libCom/logClient/logClient.c @@ -613,7 +613,7 @@ epicsShareFunc logClientId epicsShareAPI logClientInit () /* * iocLogInit() */ -int iocLogInit (void) +epicsShareFunc int epicsShareAPI iocLogInit (void) { /* * check for global disable @@ -641,7 +641,7 @@ int iocLogInit (void) /* * logClientShow () */ -void logClientShow (logClientId id, unsigned level) +epicsShareFunc void epicsShareAPI logClientShow (logClientId id, unsigned level) { logClient *pClient = (logClient *) id; char name[64]; @@ -665,7 +665,7 @@ void logClientShow (logClientId id, unsigned level) /* * iocLogShow () */ -void iocLogShow (unsigned level) +epicsShareFunc void epicsShareAPI iocLogShow (unsigned level) { if (pLogClientDefaultClient!=NULL) { logClientShow ((logClientId)pLogClientDefaultClient, level);