Files
pcas/src/ca/CAref.html
Jeff Hill 75c1d4a21e clean up
2002-08-08 15:37:05 +00:00

2512 lines
89 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>EPICS R3.14 Channel Access Reference Manual</title>
</head>
<body lang="en" bgcolor="#FFFFFF">
<hr>
<h1>EPICS R3.14 Channel Access Reference Manual</h1>
<address>
Jeffrey O. Hill<br>
</address>
<p><font size="2">Los Alamos National Laboratory</font></p>
<p>SNS Division<font size="2"></font></p>
<p><font size="1">Copyright © 2002 The University of Chicago, as Operator of
Argonne National Laboratory.<br>
Copyright © 2002 The Regents of the University of California, as Operator of
Los Alamos National Laboratory.<br>
EPICS BASE Versions 3.13.7 and higher are distributed subject to a Software
License Agreement found in the file LICENSE that is included with this
distribution.</font></p>
<p><a href="http://www.w3.org/Amaya/"><img
src="http://www.w3.org/Amaya/Icons/w3c-amaya.gif" alt="W3C-Amaya" height="31"
width="88"></a> <a href="http://validator.w3.org/check/referer"> <img
border="0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"
height="31" width="88"></a></p>
<p><small>Modified on $Date$</small></p>
<hr>
<h2>Table of Contents</h2>
<h3><a href="#Configuration">Configuration</a></h3>
<ul>
<li><a href="#EPICS">EPICS Environment Variables</a></li>
<li><a href="#CA and Wide Area Networks">CA and Wide Area Networks</a></li>
<li><a href="#Network">IP Network Administration Background
Information</a></li>
<li><a href="#port">IP port numbers</a></li>
<li><a href="#Environmen">WAN Environment</a></li>
<li><a href="#Dynamic">Disconnect Time Out Interval / Server Beacon
Period</a></li>
<li><a href="#Dynamic">Dynamic Changes in the CA Client Library Search
Interval</a></li>
<li><a href="#Configurin">Configuring the Time Zone</a></li>
<li><a href="#Configurin1">Configuring the maximum array size</a></li>
<li><a href="#Configurin2">Configuring a CA server</a></li>
</ul>
<h3><a href="#Troublesho">Troubleshooting</a></h3>
<h4><a href="#When">When Clients Do Not Connect to Their Server</a></h4>
<ul>
<li><a href="#Broadcast">Broadcast addresses dont match</a></li>
<li><a href="#Client">Client isnt configured to use the server's
port</a></li>
<li><a href="#Unicast">Unicast addreses in the EPICS_CA_ADDR_LIST does not
reliably contact servers sharing the same UDP port on the same
host</a></li>
</ul>
<h3><a href="#Notes">Function Call Interface Guidelines</a></h3>
<h3>Functionality Index </h3>
<ul>
<li><a href="#ca_context_create">create CA client context</a></li>
<li><a href="#ca_context_destroy">terminate CA client context</a></li>
<li><a href="#ca_create_channel">create a channel</a></li>
<li><a href="#ca_clear_channel">delete a channel</a></li>
<li><a href="#ca_put">write to a channel</a></li>
<li><a href="#ca_get">read from a channel</a></li>
<li><a href="#ca_add_event">subscribe for state change updates</a></li>
<li><a href="#ca_clear_event">cancel a subscription</a></li>
<li><a href="#ca_pend_io">block for certain requests to complete</a></li>
<li><a href="#ca_test_io">test to see if certain requests have
completed</a></li>
<li><a href="#L3249">process CA client library background
activities</a></li>
<li><a href="#L3251">flush outstanding requests to the server</a></li>
<li><a href="#L3253">replace the default exception handler</a></li>
</ul>
<h3><a href="#Function Call Reference">Function Call Interface Index</a></h3>
<ul>
<li><a href="#ca_add_event">ca_add_event</a></li>
<li><a href="#ca_add_exception_event">ca_add_exception_event</a></li>
<li><a href="#ca_attach_context">ca_attach_context </a></li>
<li><a href="#ca_clear_channel">ca_clear_channel</a></li>
<li><a href="#ca_clear_event">ca_clear_event</a></li>
<li><a href="#ca_client_status">ca_client_status</a></li>
<li><a href="#ca_client_status">ca_context_status</a></li>
<li><a href="#ca_context_destroy">ca_context_destroy</a></li>
<li><a href="#ca_create_channel">ca_create_channel</a></li>
<li><a href="#ca_current_context">ca_current_context</a></li>
<li><a href="#ca_element_count">ca_element_count</a></li>
<li><a href="#L6925">ca_field_type</a></li>
<li><a href="#L3251">ca_flush_io</a></li>
<li><a href="#ca_get">ca_get</a></li>
<li><a href="#L6927">ca_host_name</a></li>
<li><a href="#L6929">ca_message</a></li>
<li><a href="#L6931">ca_name</a></li>
<li><a href="#L6933">ca_read_access</a></li>
<li><a href="#L6935">ca_replace_access_rights_event</a></li>
<li><a href="#ca_replace">ca_replace_printf_handler</a></li>
<li><a href="#L3249">ca_pend_event</a></li>
<li><a href="#ca_pend_io">ca_pend_io</a></li>
<li><a href="#L3249">ca_poll</a></li>
<li><a href="#ca_puser">ca_puser</a></li>
<li><a href="#ca_put">ca_put</a></li>
<li><a href="#ca_set_puser">ca_set_puser</a></li>
<li><a href="#ca_sg_block">ca_sg_block</a></li>
<li><a href="#ca_sg_create">ca_sg_create</a></li>
<li><a href="#ca_sg_delete">ca_sg_delete</a></li>
<li><a href="#ca_sg_get">ca_sg_get</a></li>
<li><a href="#ca_sg_put">ca_sg_put</a></li>
<li><a href="#ca_sg_reset">ca_sg_reset</a></li>
<li><a href="#ca_sg_test">ca_sg_test</a></li>
<li><a href="#ca_test_event">ca_test_event</a></li>
<li><a href="#ca_test_io">ca_test_io</a></li>
<li><a href="#L6941">ca_write_access</a></li>
<li><a href="#L6746">channel_state</a></li>
<li><a href="#dbr_size[]">dbr_size[]</a></li>
<li><a href="#L6946">dbr_size_n</a></li>
<li><a href="#dbr_value_size">dbr_value_size[]</a></li>
</ul>
<h3>Deprecated Function Call Interface Function Index</h3>
<ul>
<li><a href="#ca_create_channel">ca_search</a></li>
<li><a href="#ca_create_channel">ca_search_and_connect</a></li>
<li><a href="#ca_context_destroy">ca_task_exit</a></li>
<li><a href="#ca_context_create">ca_task_initialize</a></li>
</ul>
<h3><a href="#Command">Command Line Utilities</a></h3>
<ul>
<li><a href="#acctst">acctst - CA client library regression test</a></li>
<li><a href="#caEventRat">caEventRate - PV event rate logging</a></li>
<li><a href="#casw">casw - CA server beacon anomaly logging</a></li>
<li><a href="#catime">catime - CA client library performance test</a></li>
<li><a href="#ca_test">ca_test - dump each external data type to the
console</a></li>
</ul>
<h3><a href="#Return">Return Codes</a></h3>
<hr>
<h2><a name="Configuration"></a>Configuration</h2>
<h3>Why Reconfigure Channel Access</h3>
<p>Typically reasons to reconfigure EPICS Channel Access:</p>
<ul>
<li>Two independent control systems must share a network without fear of
interaction</li>
<li>A test system must not interact with an operational system</li>
<li>Use of address lists instead of broadcasts for name resolution and
server beacons</li>
<li>Control system occupies multiple IP subnets</li>
<li>Nonstandard client disconnect time outs or server beacon intervals</li>
<li>Specify the local time zone</li>
<li>Transport of large arrays</li>
</ul>
<h3><a name="EPICS">EPICS Environment Variables</a></h3>
<p>All Channel Access (CA) configuration occurs through EPICS environment
variables. When searching for an EPICS environment variable EPICS first looks
in the environment using the ANSI C getenv() call. If no matching variable
exists then the default specified in the EPICS build system configuration
files is used.</p>
<table cellspacing="1" cellpadding="1" width="75%" border="1">
<tbody>
<tr>
<td>Name</td>
<td>Range</td>
<td>Default</td>
</tr>
<tr>
<td>EPICS_CA_ADDR_LIST</td>
<td>{N.N.N.N N.N.N.N:P ...}</td>
<td>&lt;none&gt;</td>
</tr>
<tr>
<td>EPICS_CA_AUTO_ADDR_LIST</td>
<td>{YES, NO}</td>
<td>YES</td>
</tr>
<tr>
<td>EPICS_CA_CONN_TMO</td>
<td>r &gt; 0.1 seconds</td>
<td>30.0</td>
</tr>
<tr>
<td>EPICS_CA_BEACON_PERIOD</td>
<td>r &gt; 0.1 seconds</td>
<td>15.0</td>
</tr>
<tr>
<td>EPICS_CA_REPEATER_PORT</td>
<td>i &gt; 5000</td>
<td>5065</td>
</tr>
<tr>
<td>EPICS_CA_SERVER_PORT</td>
<td>i &gt; 5000</td>
<td>5064</td>
</tr>
<tr>
<td>EPICS_CA_MAX_ARRAY_BYTES</td>
<td>i &gt;= 16384</td>
<td>16384</td>
</tr>
<tr>
<td>EPICS_TS_MIN_WEST</td>
<td>-720 &lt; i &lt;720 minutes</td>
<td>360</td>
</tr>
</tbody>
</table>
<p>Environment variables are set differently depending on the command line
shell that is in use.</p>
<table border="1">
<tbody>
<tr>
<td>C shell</td>
<td>setenv EPICS_CA_ADDR_LIST  1.2.3.4</td>
</tr>
<tr>
<td>bash</td>
<td>export EPICS_CA_ADDR_LIST=1.2.3.4</td>
</tr>
<tr>
<td>vxWorks shell</td>
<td>putenv ( "EPICS_CA_ADDR_LIST =1.2.3.4" )</td>
</tr>
<tr>
<td>DOS command line</td>
<td>set EPICS_CA_ADDR_LIST=1.2.3.4</td>
</tr>
<tr>
<td>Windows NT / 2000 / XP</td>
<td>control panel / system / environment tab</td>
</tr>
</tbody>
</table>
<h3><a name="CA and Wide Area Networks"></a>CA and Wide Area Networks</h3>
<p>Normally in a local area network (LAN) environment CA discovers the
address of the host for an EPICS process variable by broadcasting frames
containing a list of channel names ( CA search messages ) and waiting for
responses from the servers that host the channels identified. Likewise CA
clients efficiently discover that CA servers have recently joined the LAN or
disconnected from the LAN by monitoring periodically broadcasted beacons sent
out by the servers. Since hardware broadcasting requires special hardware
capabilities, we are required to provide additional configuration information
when EPICS is extended to operate over a wide area network (WAN).</p>
<h3><a name="Network">IP Network Administration Background
Information</a></h3>
<p>Channel Access is implemented using internet protocols (IP). IP addresses
are divided into host and network portions. The boundary between each portion
is determined by the IP netmask. Portions of the IP address corresponding to
zeros in the netmask specify the hosts address within an IP subnet. Portions
of the IP address corresponding to binary ones in the netmask specify the
address of a host's IP subnet. Normally the scope of a broadcasted frame will
be limited to one IP subnet. Addresses with the host address portion set to
all zeros or all ones are special. Modern IP kernel implementations reserve
destination addresses with the host portion set to all ones for the purpose
of addressing broadcasts to a particular subnet. In theory we can issue a
broadcast frame on any broadcast capable LAN within the interconnected
internet by specifying the proper subnet address combined with a host portion
set to all ones. In practice these "directed broadcasts" are frequently
limited by the default router configuration. The proper directed broadcast
address required to reach a particular host can be obtained by logging into
that host and typing the command required by your local operating
environment. Ignore the loop back interface and use the broadcast address
associated with an interface connected to a path through the network to your
client. Typically there will be only one Ethernet interface.</p>
<table border="1">
<tbody>
<tr>
<td>UNIX</td>
<td>ifconfig -a</td>
</tr>
<tr>
<td>vxWorks</td>
<td>ifShow</td>
</tr>
<tr>
<td>Windows</td>
<td>ipconfig</td>
</tr>
</tbody>
</table>
<p>IP ports are positive integers. The IP address, port number, and protocol
type uniquely identify the source and destination of a particular frame
transmitted between computers. Servers are typically addressed by a well
known port number. Clients are assigned a unique ephemeral port number during
initialization. IP ports below 1024 are reserved for servers that provide
standardized facilities such as mail or file transfer. Port number between
1024 and 5000 are typically reserved for ephemeral port number
assignments.</p>
<h3><a name="port">IP port numbers</a></h3>
<p>The two default IP port numbers used by Channel Access may be
reconfigured. This might occur when a site decides to set up two or more
completely independent control systems that will share the same network. For
instance, a site might set up an operational control system and a test
control system on the same network. In this situation it is desirable for the
test system and the operational system to use identical PV names without fear
of collision. Usually the best choice is to assign new port numbers to the
operational system and allow the test system to use the default CA port
numbers. A site might also configure the CA port numbers because some other
facility has already using the CA default port numbers.</p>
<table cellspacing="1" cellpadding="1" width="80%" border="1">
<col><tbody>
<tr>
<td>Purpose</td>
<td>Default</td>
<td>Environment Variable</td>
</tr>
<tr>
<td>CA Server</td>
<td>5064</td>
<td>EPICS_CA_SERVER_PORT</td>
</tr>
<tr>
<td>CA Beacons (sent to CA repeater daemon)</td>
<td>5065</td>
<td>EPICS_CA_REPEATER_PORT</td>
</tr>
</tbody>
</table>
<p>If a client needs to communicate with two servers that are residing at
different port numbers then an extended syntax may be used with the
EPICS_CA_ADDRESS_LIST environment variable. See <a href="#Environmen">WAN
Environment</a> below.</p>
<h3><a name="Environmen">WAN Environment</a></h3>
<p>When the CA client library connects a channel it must first determine the
IP address of the server the channels Process Variable resides on. To
accomplish this the server sends name resolution (search) requests to a list
of server destination addresses. These server destination addresses can be IP
unicast addresses (individual host addresses) or IP broadcast addresses. Each
name resolution (search) request contains a list of Process Variable names.If
one of the servers reachable by this address list knows the IP address of a
CA server that can service one or more of the specified Process Variables,
then it sends back a response containing the server's IP address and port
number.</p>
<p>During initialization CA builds the list of server destination addresses
used when sending CA client name resolution (search) requests. This table is
initialized by introspecting the network interfaces attached to the host. For
each interface found that is attached to a broadcast capable IP subnet, the
broadcast address of that subnet is added to the list. For each point to
point interface found, the destination address of that link is added to the
list. This automatic server address list initialization can be disabled if
the EPICS environment variable "EPICS_CA_AUTO_ADDR_LIST" exists and its value
is either of "no" or "NO". The typical default is to enable network interface
introspection driven initialization with "EPICS_CA_AUTO_ADDR_LIST" set to
"YES" or "yes".</p>
<p>Following network interface introspection, any IP addresses specified in
the EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of
destination addresses for CA client name resolution requests. In an EPICS
system crossing multiple subnets the EPICS_CA_ADDR_LIST must be set so that
CA name resolution ( search requests ) frames pass from CA clients to the
targeted CA servers unless a CA proxy (gateway) is installed. The addresses
in EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local
OS has support for host name to IP address translation. When multiple names
are added to EPICS_CA_ADDR_LIST they must be separated by white space. There
is no requirement that the addresses specified in the EPICS_CA_ADDR_LIST be a
broadcast addresses, but this will often be the most convenient choice.</p>
<table border="1">
<tbody>
<tr>
<td>C shell</td>
<td>setenv EPICS_CA_ADDR_LIST "1.2.3.255 8.9.10.255"</td>
</tr>
<tr>
<td>bash</td>
<td>export EPICS_CA_ADDR_LIST="1.2.3.255 8.9.10.255"</td>
</tr>
<tr>
<td>vxWorks</td>
<td>putenv ( "EPICS_CA_ADDR_LIST=1.2.3.255 8.9.10.255" )</td>
</tr>
</tbody>
</table>
<p>If a client needs to communicate with two servers that are residing at
different port numbers then an extended syntax may be used with the
EPICS_CA_ADDRESS_LIST environment variable. Each host name or IP address in
the EPICS_CA_ADDR_LIST may be immediately followed by a colon and an IP port
number without intervening whitespace. Entries that do not specify a port
number will default to EPICS_CA_SERVER_PORT.</p>
<table border="1">
<tbody>
<tr>
<td>C shell</td>
<td>setenv EPICS_CA_ADDR_LIST "1.2.3.255 8.9.10.255:10000"</td>
</tr>
</tbody>
</table>
<h3><a name="Disconnect">Disconnect Time Out Interval</a></h3>
<p>If the CA client library does not see a beacon from a server that it is
connected to for EPICS_CA_CONN_TMO seconds then an state-of-health message is
sent to the server over TCP/IP. If this state-of-health message isn't
promptly replied to then the client will assume that the server is no longer
present on the network and disconnect. Disconnecting implies notification of
client side application programs via function callbacks. The parameter
EPICS_CA_CONN_TMO is specified in floating point seconds. The default is
typically 30 seconds. For efficient operation it is recommended that
EPICS_CA_CONN_TMO be set to no less than twice the value specified for
EPICS_CA_BEACON_PERIOD.</p>
<h3><a name="Dynamic">Dynamic Changes in the CA Client Library Search
Interval</a></h3>
<p>The CA client library will continuously attempt to connect any CA channels
that an application has created until it is successful. The CA client library
periodically queries the server destination address list described above with
name resolution requests for any unresolved channels. Since this address list
frequently contains broadcast addresses, and because nonexistent process
variable names are frequently configured, or servers may be temporarily
unavailable, then it is necessary for the CA client library internals to
carefully schedule these requests in time to avoid introducing excessive load
on the network and the servers.</p>
<p>When the CA client library has many channels to connect, and most of its
name resolution requests are responded to, then it sends name resolution
requests at an interval that is twice the estimated round trip interval for
the set of servers responding, or at the minimum delay quantum for the
operating system - whichever is greater. The number of UDP frames per
interval is also dynamically adjusted based on the past success rate.</p>
<p>If name resolution requests are not responded to, then the client library
doubles the delay between name resolution attempts with each attempt
eventually limited by a maxuimum plateau interval, and it also reduces the
number of requests per interval. After some long interval, if the client
library does not receive any responses it stops sending name resolution
attempts altogether until it sees a beacon anomaly.</p>
<p>The CA client library continually estimates the beacon period of all
server beacons received. If a particular server's beacon period becomes
significantly shorter or longer then the client is said to detect a beacon
anomaly. When a client sees a beacon anomaly then it resumes search requests
but with a longer initial interval between requests than is used when the
application creates a channel. An initial delay based on the client's
ephemeral port number is also imposed before the first name resolution
request to avoid all clients responding to a beacon anomaly at the same
instant. The program "casw" prints a message on standard out each time that a
CA client will detect a beacon anomaly.</p>
<p>Two conclusions deserve special emphasis.<em> First, if a client does not
see the server's beacons, then it will use additional network and server
resources sending periodic state-of-health messages. Second, if a client does
not see the server's beacons, then it may not connect to a newly introduced
server that was initially inaccessible if the client timed out attempting to
find it.</em> The typical situation where a client would not see the server's
beacon might be when the client isnt on the same IP subnet as the server, the
EPICS_CA_ADDR_LIST was modified to include a destination address for the
server, but the server's beacon address list was not modified so that it's
beacons are received by the client.</p>
<h3><a name="Configurin">Configuring the Time Zone</a></h3>
<p><em>Readers Note: Starting with EPICS R3.14 all of the libraries in the
EPICS base distribution rely on facilities built into the operating system to
determine the correct time zone. Nevertheless, several programs commonly used
with EPICS still use the original "tssubr" library and therefore they still
rely on proper configuration of EPICS_TS_MIN_WEST.</em></p>
<p>While the CA client library does not translate in between the local time
and the time zone independent internal storage of EPICS time stamps, many
EPICS client side applications call core EPICS libraries which provide these
services. To set the correct time zone users must compute the number of
positive minutes west of GMT (maximum 720 inclusive) or the negative number
of minutes east of GMT (minimum -720 inclusive). This integer value is then
placed in the variable EPICS_TS_MIN_WEST.</p>
<table cellspacing="1" cellpadding="1" width="75%" border="1">
<tbody>
<tr>
<td>Time Zone</td>
<td>EPICS_TS_MIN_WEST</td>
</tr>
<tr>
<td>USA Eastern</td>
<td>300</td>
</tr>
<tr>
<td>USA Central</td>
<td>360</td>
</tr>
<tr>
<td>USA Mountain</td>
<td>420</td>
</tr>
<tr>
<td>USA Pacific</td>
<td>480</td>
</tr>
<tr>
<td>Alaska</td>
<td>540</td>
</tr>
<tr>
<td>Hawaii</td>
<td>600</td>
</tr>
<tr>
<td>Japan</td>
<td>-540</td>
</tr>
<tr>
<td>Germany</td>
<td>-120</td>
</tr>
<tr>
<td>United Kingdom</td>
<td>-60</td>
</tr>
</tbody>
</table>
<h3><a name="Configurin1">Configuring the Maximum Array Size</a></h3>
<p>The environment variable EPICS_CA_MAX_ARRAY_BYTES determines the size of
the largest array that may pass through CA. This parameter must be set
appropriately for both the CA client and the CA server. In EPICS R3.14 CA
maintains a free list of 16384 byte network buffers that are used for
ordinary communication. If EPICS_CA_MAX_ARRAY_BYTES  is larger than 16384
then a second free list of larger data buffers is established when clients
request transportation of large arrays.</p>
<h3><a name="Configurin2">Configuring a CA Server</a></h3>
<table cellspacing="1" cellpadding="1" width="75%" border="1">
<tbody>
<tr>
<td>Name</td>
<td>Range</td>
<td>Default</td>
</tr>
<tr>
<td>EPICS_CAS_SERVER_PORT</td>
<td>i &gt; 5000</td>
<td>EPICS_CA_SERVER_PORT</td>
</tr>
<tr>
<td>EPICS_CAS_AUTO_BEACON_ADDR_LIST</td>
<td>{YES, NO}</td>
<td>EPICS_CA_AUTO_ADDR_LIST</td>
</tr>
<tr>
<td>EPICS_CAS_BEACON_ADDR_LIST</td>
<td>{N.N.N.NN.N.N.N:P...}</td>
<td>EPICS_CA_ADDR_LIST</td>
</tr>
<tr>
<td>EPICS_CAS_BEACON_PERIOD</td>
<td>r &gt; 0.1 seconds</td>
<td>15.0</td>
</tr>
<tr>
<td>EPICS_CAS_BEACON_PORT</td>
<td>i &gt; 5000</td>
<td>EPICS_CA_REPEATER_PORT</td>
</tr>
<tr>
<td>EPICS_CAS_INTF_ADDR_LIST</td>
<td>{N.N.N.NN.N.N.N:P...}</td>
<td>&lt;none&gt;</td>
</tr>
</tbody>
</table>
<h4>Server Beacons</h4>
<p>CA servers send "beacon" messages to each address specified in
EPICS_CAS_BEACON_ADDR_LIST, and also any addresses auto configured from
network interfaces found if EPICS_CAS_AUTO_BEACON_ADDR_LIST is "yes" or
"YES".</p>
<h4>Configuring the Server's Beacon Period</h4>
<p>The EPICS_CAS_BEACON_PERIOD parameter determines the server's beacon
period and is specified in floating point seconds. The default is typically
15 seconds. See also <a href="#Disconnect">EPICS_CA_CONN_TMO</a> and <a
href="#Dynamic">Dynamic Changes in the CA Client Library Search
Interval</a>.</p>
<p>The server configures its port number from the EPICS_CAS_SERVER_PORT
environment variable if it is specified. Otherwise the EPICS_CA_SERVER_PORT
environment variable determines the server's port number. Two servers can
share the same UDP port number on the same machine, but there are
restrictions - see a <a href="#Unicast">discussion of unicast addresses and
two servers shareing the same UDP port on the same host</a>.</p>
<p>CA servers build a list of addresses to send beacons to during
initialization. If EPICS_CAS_AUTO_BEACON_ADDR_LIST has the value "YES" then
the beacon address list will contain at least the broadcast address of all
LAN interfaces found in the host and the destination address of all
point-to-point interfaces found in the host. If EPICS_CAS_BEACON_ADDR_LIST is
defined then its contents will be used to augment this list. Individual
entries in EPICS_CAS_BEACON_ADDR_LIST may override the destination port
number if ":nnn" follows the host name or IP address there. Only if
EPICS_CAS_BEACON_ADDR_LIST is not defined, EPICS_CA_ADDR_LIST is defined, and
EPICS_CAS_INTF_ADDR_LIST is not defined, then the contents of
EPICS_CA_ADDR_LIST will inetead be used to augment this list.</p>
<p>The parameter EPICS_CAS_INTF_ADDR_LIST allows a ca server to bind itself
to a limited set of network interfaces (each specified by its IP address). By
defualt, the CA server is accessible from all network interfaces configured
into its host. <em>In R3.14 and R3.13 the CA server employed by
iocCore does not implemet this feature</em>.</p>
<p>See also <a href="#Configurin1">Configuring the Maximum Array Size</a>.</p>
<p>Typically vxWorks hosts boot with routes configured for the host's subnet.
If a EPICS system is operating in a WAN environment it may be necessary to
configure routes into the vxWorks system which enable a vxWorks based CA
server to respond to requests originating outside it's subnet. An EPICS
system manager can implemnt an rudamentary, but robust, form of access
control for a particular host by not providing routes in that host that reach
outside of a limited set of subnets.</p>
<h2><a name="Troublesho">Troubleshooting</a></h2>
<h3><a name="When">When Clients Do Not Connect to Their Server</a></h3>
<h4><a name="Broadcast">Broadcast addresses dont match</a></h4>
<p>Verify that the broadcast addresses are identical on the server's host and
on the client's host. This can be checked on UNIX with "netstat -i" or
"ifconfig -a"; on vxWorks with ifShow; and on windows with ipconfig.</p>
<h4><a name="Client">Client isnt configured to use the server's port</a></h4>
<p>Verify that the client and server are using the same UDP port. Check the
server's port by running "netstat -a | grep nnn" where nnn is the port number
configured in the client. If you do not set EPICS_CA_SERVER_PORT or
EPICS_CAS_SERVER_PORT then the default port will be 5064.</p>
<h4><a name="Unicast">Unicast addreses in the EPICS_CA_ADDR_LIST does not
reliably contact servers sharing the same UDP port on the same host</a></h4>
<p>Two servers can run on the same host with the same server port number, but
there are restrictions. If the host has a modern IP kernel it is possible to
have two or more servers share the same UDP port. It is not possible for
these servers to run on the same host using the same TCP port. If the CA
server library detects that a server is attempting to start on the same port
as an existing CA server then both servers will use the same UDP port, and
the 2nd server will be allocated an ephemeral TCP port. Clients can be
configured to use the same port number for both servers. They will locate the
2nd server via the shared UDP port, and transparently connect to the 2nd
server's ephemeral TCP port. Be aware however that If there are two server's
running on the same host sharing the same UDP port then they will both
receive UDP search requests sent as broadcasts, but unfortunately (due to a
weakness of most IP kernel implementations) only one of the servers will
typically receive UDP search requests sent to unicast addresses (i.e. a
single specific host's ip address).</p>
<h2>Function Call Interface General Guidelines</h2>
<p>If successful, the routines described here return the status code
ECA_NORMAL. Unsuccessful status codes returned from the client library are
listed with each routine in this manual. Operations that appear to be valid
to the client can still fail in the server. Writing the string "off" to a
floating point field is an example of this type of error. If the server for a
channel is located in a different address space than the client then the
ca_xxx() operations that communicate with the server returns status
indicating the validity of the request and whether it was successfully
enqueued to the server.</p>
<p>Significant performance gains may be realized if we don't wait for a
response to return from the server after each request. All requests which
require interaction with a CA server are accumulated (buffered) and not
forwarded to the IOC until one of ca_flush_io, ca_pend_io, ca_pend_event, or
ca_sg_pend are called allowing several operations to be efficiently sent over
the network together. Any process variable values written into your program's
variables by ca_get() should not be referenced by your program until
ECA_NORMAL has been received from ca_pend_io().</p>
<p>All arguments of type chtype expect one of the set of DBR_XXXX. These
constants, defined in db_access.h, enumerate which of the standard data types
you wish to transfer. There are data types for all of the C primitive types
and there are also compound types that include various process variable
properties such as units, limits, time stamp, or alarm status.</p>
<p>Certain CA client initiated requests asynchronously execute an application
supplied call back in the client when a response arrives. The functions
ca_put_callback, ca_get_callback, and ca_add_event all request notification
of asynchronous completion via this mechanism. The structure
"event_handler_args" is passed to the application supplied callback. In this
structure the field "dbr" is a void pointer to any data that might be
returned. The field "status" will be set to one of the CA error codes in
caerr.h and will indicate the status of the operation performed in the IOC.
If the status field isn't set to ECA_NORMAL or data isn't normally returned
from the operation (i.e. put call back) then you should expect that the field
"dbr" will be set to NULL. The fields "usr", "chid", "type", and "count" are
set to the values specified when the operation was initiated by the
application.</p>
<pre><code>struct event_handler_args {
void *usr; /* user argument supplied when event added */
chid chid; /* channel id */
long type; /* dbr type of the value returned */
long count; /* element count of the item(s) returned */
void *dbr; /* pointer to the value returned */
int status; /* ECA_XXX status of the op from server */
};</code></pre>
<p>When the server detects a failure, and there is no client call back
function attached to the request, then an exception handler is executed in
the client. The default exception handler prints a message on the console and
exits if the exception condition is severe. To modify this behavior see <a
href="#ca_add_exception_event">ca_add_exception_event()</a>.</p>
<p>If the server for the channel and the client are located on the same node
then the ca_xxx() operations bypass the server and directly interact with the
server tool (the IOC's database). Therefore, the ca_xxx() routines always
return the status of the operation directly to the caller with no opportunity
for asynchronous notification of failure via an exception handler.</p>
<p>Certain routines have arguments that specify an address at which channel
access is to write a value of type DBR_XXXX. Care should be taken to ensure
that you have reserved space of sufficient size. Architecture independent
types are provided in db_access.h to assist programmers in writing portable
code. For example "dbr_short_t" should be used to send or receive type
DBR_SHORT. The dbr type size returning MACROS provided in db_access.h may
also be used.</p>
<p>For routines that require an argument specifying the number of array
elements, no more than the process variable's maximum native element count
may be requested. The process variable's maximum native element count is
available from ca_element_count() when the channel is connected. If less
elements than the process variable's native element count are requested the
requested values will be fetched beginning at element zero. By default CA
limits the number of elements in an array to be no more than approximately
16k divided by the size of one element in the array. Starting with EPICS
R3.14 the maximum array size may be configured in the client and in the
server.</p>
<p>Channel connections through the network are inherently transient. Channels
are always initially assumed to be disconnected. A connection state change
call back function may be installed to be run whenever a channel connects or
disconnects. If a connection state change call back function is not installed
(if a nil function pointer is supplied) then the user must wait for
successful status from ca_pend_io prior to using the channel for the first
time. Once the channel connects the user can freely perform IO operations
through the channel, but he should expect that the channel might disconnect
at any time due to network interruptions or server restarts. Otherwise, if a
connection state change call back function is supplied, one of the arguments
to this function distinguishes between connect and disconnect events. If a
connection state change call back function is installed on a particular
channel by the user ca_pend_io will not block for the channel to connect. The
user's connection state change function will be run immediately when the
channel is created if the CA client and the server are both hosted in the
same address space (IOC).</p>
<p>Starting with EPICS R3.14 the CA client libraries are fully thread safe on
all OS (in past releases the library was thread safe only on vxWorks). When
the client library is initialized the programmer may specify if preemptive
call back is enabled. Preemptive call back is disabled by default. If
preemptive call back is enabled then the user's call back functions might be
called by CA's auxiliary threads when the main initiating channel access
thread is not inside of a function in the channel access client library.
Otherwise, the user's call back functions will be called only when the main
initiating channel access thread is executing inside of the CA client
library.</p>
<p>If preemptive call back is not enabled, then for proper operation CA must
periodically be polled to take care of background activity. This requires
that your application must either wait in one of ca_pend_event(),
ca_pend_io(), or ca_sg_block() or alternatively it must call ca_poll() every
100 milli-seconds.</p>
<p>When CA invokes a user's call back function it will always wait for the
callback to run to completion prior to executing another call back
function.</p>
<p>The error number and the error severity are embedded in CA status (error)
constants. Applications shouldn't test the success of a CA function call by
checking to see if the returned value is zero as is the UNIX convention.
Below are several methods to test CA function returns. See ca_signal() on
page 24 for more information on this topic.</p>
<pre><code>status = ca_XXXX();
SEVCHK( status, "ca_XXXX() returned failure status");
if ( status &amp; CA_M_SUCCESS ) {
printf ( "The requested ca_XXXX() operation didn't complete successfully\n");
}
if ( status != ECA_NORMAL ) {
printf("The requested ca_XXXX() operation didn't complete successfully because \"%s\"\n",
ca_message ( status ) );
}</code></pre>
<p>With the embryonic releases of EPICS it was a common practice to examine a
channel's connection state, its native type, and its native element count by
directly accessing fields in a structure using a pointer stored in type
<code>chid</code>. Likewise, a user private pointer in the per channel
structure was also commonly set by directly accessing fields in the channel
structure. A number of difficulties arise from this practice, which has long
since been deprecated. For example, in release 3.13 it was recognized that
transient changes in certain private fields in the per channel structure
would make it difficult to reliably test the channels connection state using
these private fields directly. Therefore, in release 3.13 the names of
certain fields were changed to discourage this practice. Starting with
release 3.14 codes written this way will not compile. Codes intending to
maintain the highest degree of portability over a wide range of EPICS
versions should be especially careful. For example you should replace all
instances off <code>channel_id-&gt;count</code> with
<code>ca_element_count(channel_id)</code>. This approach should be reliable
on all versions of EPICS in use today. The construct <code>ca_puser(chid) =
xxxx</code> is particularly problematic. The best mechanisms for setting the
per channel private pointer will be to pass the user private pointer in when
creating the channel. This approach is implemented on all versions.
Otherwise, you can also use <code>ca_set_puser(CHID,PUSER)</code>, but this
function is available only after the first official (post beta) release of
EPICS 3.13.</p>
<h2><a name="Function Call Reference"></a>Function Call Reference</h2>
<h3><code><a name="ca_context_create">ca_context_create()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
enum ca_preemptive_callback_select
{ ca_disable_preemptive_callback, ca_enable_preemptive_callback };
int ca_context_create ( enum ca_preemptive_callback_select SELECT );</code></pre>
<h4>Description</h4>
<p>This function should be called once prior to making any of the other
channel access calls.</p>
<h4>Arguments</h4>
<dl>
<dt><code>SELECT</code></dt>
<dd>Specifies if preemptive calback is allowed. If it is allowed your
callbacks might be called when the thread that calls this routine is
not executing in the CA client library. Programmers who are unfamiliar
with mutual exclusion locking in a multi-threaded environment should
specify <code>ca_disable_preemptive_callback</code>. If
ca_enable_preemptive_callback is specified then CA client background
activies, such as connection management, will proceed even if the
thread that calls this routine is not executing in the CA client
library.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_ALLOCMEM - Failed, unable to allocate space in pool</p>
<h4>See Also</h4>
<p>ca_context_destroy()</p>
<h3><code><a name="ca_context_destroy">ca_context_destroy()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
void ca_context_destroy();</pre>
<h4>Description</h4>
<p>Shut down a channel access client context and free any resources
allocated. On most operating systems this is performed automatically at
process exit.</p>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<h4>See Also</h4>
<p><a>ca_context_create()</a></p>
<h3><a name="ca_create_channel"><code>ca_create_channel()</code></a></h3>
<pre><code>#include &lt;cadef.h&gt;
typedef void ( *pCallBack ) (
struct connection_handler_args );
int epicsShareAPI ca_create_channel
(
const char *PROCESS_VARIABLE_NAME,
caCh *USERFUNC,
void *PUSER,
capri priority,
chid *PCHID
);</code></pre>
<h4>Description</h4>
<p>This function creates a CA channel. The CA client library will attempt to
establish and maintain a virtual circuit between the caller's application and
a named process variable in a CA server. Each call to ca_create_channel
allocates resources in the CA client library and potentially also a CA
server. The function ca_clear_channel() is used to release these resources.
If successful, the routine writes a channel identifier into the user's
variable of type "chid". This identifier can be used with any channel access
call that operates on a channel.</p>
<p>The circuit may be initially connected or disconnected depending on the
state of the network and the location of the channel. A channel will
only enter a connected state after server's address is determined, and only
if channel access successfully establishes a virtual circuit through the
network to the server. Channel access routines that send a request to a
server will return ECA_DISCONNCHID if the channel is currently
disconnected.</p>
<p>There are two ways to obtain asynchronous notification when a channel
enters a connected state.</p>
<ul>
<li>The first and simplest method requires that you call ca_pend_io(), and
wait for successful completion, prior to using a channel that was created
specifying a nil connection call back function pointer.</li>
<li>The second method requires that you register a connection handler by
supplying a valid connection callback function pointer. This connection
handler is called whenever the connection state of the channel changes.
If you have installed a connection handler then ca_pend_io() will
<em>not</em> block waiting for the channel to enter a connected
state.</li>
</ul>
<p>The function ca_state(CHID) can be used to test the connection state of a
channel. Valid connections may be isolated from invalid ones with this
function if ca_pend_io() times out.</p>
<p>Due to the inherently transient nature of network connections the order of
connection call backs relative to the order that ca_create_channel() calls
are made by the application can't be guaranteed, and application programs may
need to be prepared for a connected channel to enter a disconnected state at
any time.</p>
<p>If <code>ca_disable_preemptive_callback</code> is specified then
additional threads are <em>not </em>allowed to join the CA context using
ca_context_attach() because allowing other threads to join implies that CA
callbacks will be called preemptively from more than one thread.</p>
<h4>Arguments</h4>
<dl>
<dt><code>PROCESS_VARIABLE_NAME</code></dt>
<dd>A nil terminated process variable name string. EPICS process control
function block database variable names are of the form "&lt;record
name&gt;.&lt;field name&gt;". If the field name and the period
separator are omitted then the "VAL" field is implicit. For example
"RFHV01" and "RFHV01.VAL" reference the same EPICS process control
function block database variable.</dd>
</dl>
<dl>
<dt><code>USERFUNC</code></dt>
<dd>Optional address of the user's call back function to be run when the
connection state changes. Casual users of channel access may decide to
set this field to nil or 0 if they do not need to have a call back
function run in response to each connection state change event.</dd>
</dl>
<dl>
<dt><code>PUSER</code></dt>
<dd>The value of this void pointer argument is retained in
storage associated with the specified channel. See the MACROS manual
page for reading and writing this field. Casual users of channel access
may wish to set this field to nil or 0.</dd>
</dl>
<dl>
<dt><code>PRIORITY</code></dt>
<dd>The priority level for dispatch within the server or network with 0
specifying the lowest dispatch priority and 99 the highest. This
parameter currently does not impact dispatch priorities within the
client, but this might change in the future. The abstract priority
range specified is mapped into an operating system specific range of
priorities within the server. This parameter is ignored if the server
is running on a network or operating system that does not have native
support for prioritized delivery or execution respectively.</dd>
</dl>
<dl>
<dt><code>PCHID</code></dt>
<dd>The user supplied channel identifier storage is overwritten with a
channel identifier if this routine is successful.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
<p>ECA_STRTOBIG - Unusually large string</p>
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
<h3><a name="ca_clear_channel"></a><code>ca_clear_channel()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_clear_channel (evid CHID);</code></pre>
<h4>Description</h4>
<p>Shutdown and reclaim resources associated with a channel created by
ca_create_channel().</p>
<p>All remote operation requests such as the above are accumulated (buffered)
and not forwarded to the IOC until one of ca_flush_io, ca_pend_io,
ca_pend_event, or ca_sg_pend are called. This allows several requests to be
efficiently sent over the network in one message.</p>
<p>Clearing a channel does not cause its disconnect handler to be called, but
clearing a channel does shutdown and reclaim any channel state change event
subscriptions (monitors) registered with the channel.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>Identifies the channel to delete.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADCHID - Corrupted CHID</p>
<h3><a name="ca_put"><code>ca_put()</code></a></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_put ( chtype TYPE,
chid CHID, void *PVALUE );
int ca_array_put ( chtype TYPE,
unsigned long COUNT,
chid CHID, const void *PVALUE);
typedef void ( *pCallBack ) (struct event_handler_args );
int ca_put_callback ( chtype TYPE,
chid CHID, const void *PVALUE,
pCallBack PFUNC, void *USERARG );
int ca_array_put_callback ( chtype TYPE,
unsigned long COUNT,
chid CHID, const void *PVALUE,
pCallBack PFUNC, void *USERARG );</code></pre>
<h4>Description</h4>
<p>Write a scalar or array value to a process variable.</p>
<p>When ca_array_put  or ca_put are invoked the client will receive no
response unless the request can not be fulfilled in the server. If
unsuccessful an exception handler is run on the client side. If a connection
is lost and then resumed outstanding ca_array_put  or ca_put  requests are
not automatically reissued following reconnect, and no additional
notification are provided to the user for each put request.</p>
<p>When ca_array_put_callback are invoked the user supplied asynchronous call
back is called only after the initiated write operation and all actions
resulting from the initiating write operation complete. If unsuccessful the
call back function is invoked indicating bad status. If the channel
disconnects before a put callback request can be completed, then the client's
call back function is called with bad status, but this does not gaurantee
that the server did not receive and process the request before the
disconnect.</p>
<p>All of these functions return ECA_DISCONN if the channel is currently
disconnected.</p>
<p>All put requests are accumulated (buffered) and not forwarded to the IOC
until one of ca_flush_io, ca_pend_io, ca_pend_event, or ca_sg_pend are calle.
This allows several requests to be efficiently combined into one message.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The external type of the supplied value to be written. Conversion
will occur if this does not match the native type. Specify one from the
set of DBR_XXXX in db_access.h</dd>
</dl>
<dl>
<dt><code>COUNT</code></dt>
<dd>Element count to be written to the specified channel. This must match
the array pointed to by PVALUE.</dd>
</dl>
<dl>
<dt><code>CHID</code></dt>
<dd>Channel identifier</dd>
</dl>
<dl>
<dt><code>PVALUE</code></dt>
<dd>Pointer to a value or array of values provided by the application to
be written to the channel.</dd>
</dl>
<dl>
<dt><code>PFUNC</code></dt>
<dd>address of user supplied function to be run when the requested
operation completes</dd>
</dl>
<dl>
<dt><code>USERARG</code></dt>
<dd>pointer sized variable retained and then passed back to user supplied
function above</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADCHID - Corrupted CHID</p>
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
<p>ECA_STRTOBIG - Unusually large string supplied</p>
<p>ECA_NOWTACCESS - Write access denied</p>
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
<p>ECA_DISCONN - Channel is disconnected</p>
<h4>See Also</h4>
ca_flush_io()
<p>ca_pend_event()</p>
<h3><a name="ca_get"></a><code>ca_get()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_get ( chtype TYPE,
chid CHID, void *PVALUE );
int ca_array_get ( chtype TYPE, unsigned long COUNT,
chid CHID, void *PVALUE );
typedef void ( *pCallBack ) (struct event_handler_args );
int ca_get_callback ( chtype TYPE,
chid CHID, pCallBack USERFUNC, void *USERARG);
int ca_array_get_callback ( chtype TYPE, unsigned long COUNT,
chid CHID,
pCallBack USERFUNC, void *USERARG );</code></pre>
<h4>Description</h4>
<p>Read a scalar or array value from a process variable.</p>
<p>When ca_get or ca_array_get are invoked the returned channel value cant be
assumed to be stable in the application supplied buffer until after
ECA_NORMAL is returned from ca_pend_io. If a connection is lost outstanding
get requests are not automatically reissued following reconnect.</p>
When ca_get_callback or ca_array_get_callback are invoked a value is read
from the channel and then the user's callback is invoked with a pointer to
the retrieved value. Note that ca_pend_io will not block for the delivery of
values requested by ca_get_callback. If the channel disconnects before a get
callback request can be completed, then the clients call back function is
called with bad status.
<p>All of these functions return ECA_DISCONN if the channel is currently
disconnected.</p>
<p>All get requests are accumulated (buffered) and not forwarded to the IOC
until one of ca_flush_io, ca_pend_io, ca_pend_event, or ca_sg_pend are
called. This allows several requests to be efficiently sent over the network
in one message.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The external type of the user variable to return the value into.
Conversion will occur if this does not match the native type. Specify
one from the set of DBR_XXXX in db_access.h</dd>
</dl>
<dl>
<dt><code>COUNT</code></dt>
<dd>Element count to be read from the specified channel. Must match the
array pointed to by PVALUE.</dd>
</dl>
<dl>
<dt><code>CHID</code></dt>
<dd>Channel identifier</dd>
</dl>
<dl>
<dt><code>PVALUE</code></dt>
<dd>Pointer to an application supplied buffer where the current value of
the channel is to be written.</dd>
</dl>
<dl>
<dt><code>USERFUNC</code></dt>
<dd>Address of user supplied function to be run when the requested
operation completes.</dd>
</dl>
<dl>
<dt><code>USERARG</code></dt>
<dd>Pointer sized variable retained and then passsed back to user
supplied call back function above.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
<p>ECA_BADCHID - Corrupted CHID</p>
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
<p>ECA_GETFAIL - A local database get failed</p>
<p>ECA_NORDACCESS - Read access denied</p>
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
<p>ECA_DISCONN - Channel is disconnected</p>
<h4>See Also</h4>
ca_pend_io()
<p>ca_pend_event()</p>
<h3><a name="ca_add_event"></a><code>ca_add_event()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
typedef void ( *pCallBack ) (
struct event_handler_args );
int ca_add_event( chtype TYPE, chid CHID,
pCallBack USERFUNC, void *USERARG,
evid *PEVID);
int ca_add_array_event( chtype TYPE,
unsigned long COUNT, chid CHID,
pCallBack USERFUNC, void *USERARG,
double RESERVED, double RESERVED,
double RESERVED, evid *PEVID );
int ca_add_masked_array_event ( chtype TYPE,
unsigned long COUNT, chid CHID,
pCallBack USERFUNC, void *USERARG,
double RESERVED, double RESERVED, double RESERVED,
evid *PEVID, unsigned long MASK );</code></pre>
<h4>Description</h4>
<p>Reguister a state change subscription and specify a call back function to
be invoked whenever the process variable undergoes significant state changes.
A significant change can be a change in the process variable's value, alarm
status, or alarm severity. In the process control function block database the
deadband field determines the magnitude of a significant change for for the
process variable's value. Each call to this function consumes resources in
the client library and potentially a CA server until one of ca_clear_channel
or ca_clear_event is called.</p>
<p>Subscriptions may be installed or canceled against both connected and
disconnected channels. The specified USERFUNC is called once immediately
after the subscription is installed with the process variable's current state
if the process variable is connected. Otherwise, the specified USERFUNC is
called immediately after establishing a connection (or reconnection) with the
process variable. The specified USERFUNC is called immediately with the
process variable's current state from within ca_add_event() if the client and
the process variable share the same address space.</p>
<p>If a subscription is installed on a channel in a disconnected state then
the requested count will be set to the native maximum element count of the
channel if the requested count is larger.</p>
<p>All subscription requests such as the above are accumulated (buffered) and
not forwarded to the IOC until one of ca_flush_io, ca_pend_io, ca_pend_event,
or ca_sg_pend are called. This allows several requests to be efficiently sent
over the network in one message.</p>
<p>If at any time after subscribing, read access to the specified process
variable is lost, then the call back will be invoked immediately indicating
that read access was lost via the status argument. When read access is
restored normal event processing will resume starting always with at
least one update indicating the current state of the channel.</p>
<p>A better name for this function might have been ca_subscribe.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The type of value presented to the call back funstion. Conversion
will occur if it does not match native type. Specify one from the set
of DBR_XXXX in db_access.h</dd>
</dl>
<dl>
<dt><code>COUNT</code></dt>
<dd>The element count to be read from the specified channel. A count of
zero specifies the native elemnt count.</dd>
</dl>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<dl>
<dt><code>USRERFUNC</code></dt>
<dd>Address of user supplied callback function to be invoked with each
subscription update</dd>
</dl>
<dl>
<dt><code>USERARG</code></dt>
<dd>pointer sized variable retained and passed back to user callback
function</dd>
</dl>
<dl>
<dt><code>RESERVED</code></dt>
<dd>Reserved for future use. Specify 0.0 to remain upwardly
compatible.</dd>
</dl>
<dl>
<dt><code>PEVID</code></dt>
<dd>This is a pointer to user supplied event id which is overwritten if
successful. This event id can later be used to clear a specific
event. This option may may be omitted by passing a nil pointer.</dd>
</dl>
<dl>
<dt><code>MASK</code></dt>
<dd>A mask with bits set for each of the event trigger types requested.
The event trigger mask must be a logical or of one or more of the
following constants.
<ul>
<li>DBE_VALUE - Trigger events when the channel value exceeds the
monitor dead band</li>
<li>DBE_LOG - Trigger events when the channel value exceeds the
archival dead band</li>
<li>DBE_ALARM - Trigger events when the channel alarm state
changes.</li>
</ul>
<p>For functions above that do not include a trigger specification,
events will be triggered when there are significant changes in the
channel's value or when there are changes in the channel's alarm state.
This is the same as "DBE_VALUE | DBE_ALARM."</p>
</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADCHID - Corrupted CHID</p>
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
<p>ECA_ALLOCMEM - Unable to allocate memory</p>
<p>ECA_ADDFAIL - A local database event add failed</p>
<h4>See Also</h4>
ca_pend_event()
<p>ca_flush_io()</p>
<h3><a name="ca_clear_event"></a><code>ca_clear_event()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_clear_event ( evid EVID );</code></pre>
<h4>Description</h4>
<p>Cancel a subscription.</p>
<p>All ca_clear_event() requests such as the above are accumulated (buffered)
and not forwarded to the server until one of ca_flush_io, ca_pend_io,
ca_pend_event, or ca_sg_pend are called. This allows several requests to be
efficiently sent together in one message.</p>
<h4>Arguments</h4>
<dl>
<dt>EVID</dt>
<dd>event id returned by ca_add_event()</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADCHID - Corrupted CHID SEE ALSO ca_add_event()</p>
<h3><a name="ca_pend_io"><code>ca_pend_io()</code></a></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_pend_io ( double TIMEOUT );</code></pre>
<h4>Description</h4>
<p>This function flushes the send buffer and then blocks until outstanding <a
href="#ca_get">ca_get</a> requests complete, and until channels created
specifying nill connection handler function pointers connect for the first
time.</p>
<ul>
<li>If ECA_NORMAL is returned then it can be safely assumed that all
outstanding <a href="#ca_get">ca_get</a> requests have completed
successfully and channels created specifying nill connection handler
function pointers have connected for the first time.</li>
<li>If ECA_TIMEOUT is returned then it must be assumed for all previous <a
href="#ca_get">ca_get</a> requests and properly qualified first time
channel connects have failed.</li>
</ul>
<p>If ECA_TIMEOUT is returned then get requests may be reissued followed by a
subsequent call to ca_pend_io(). Specifically, the function will block only
for outstanding outstanding <a href="#ca_get">ca_get</a> requests issued, and
also any channels created specifying a nill connection handler function
pointer, after the last call to ca_pend_io() or ca client context creation
whichever is later. Note that <a
href="#ca_create_channel">ca_create_channel</a> requests should not be
reissued unless <a href="#ca_clear_channel">ca_clear_channel</a> is called
first.</p>
<p>If no <a href="#ca_get">ca_get</a> or connection state change events are
outstanding then ca_pend_io() will flush the send buffer and return
immediately <em>without processing any outstanding channel access background
activities</em>.</p>
<p>The delay specified to ca_pend_io() should take into account worst case
network delays such as Ethernet collision backoff and retransmission.</p>
<h4>Arguments</h4>
<dl>
<dt>TIMEOUT</dt>
<dd>Specifies the time out interval. A <code>TIMEOUT</code> interval of
zero specifies forever.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_EVDISALLOW - Function inappropriate for use within an event handler</p>
<h4>See Also</h4>
<a href="#ca_get">ca_get</a>()
<p><a href="#ca_create_channel">ca_create_channel</a>()</p>
<p><a href="#ca_test_io">ca_test_io</a>()</p>
<h3><a name="ca_test_io"><code>ca_test_io()</code></a></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_test_io();</code></pre>
<h4>Description</h4>
<p>This function tests to see if all <a href="#ca_get">ca_get</a> requests
are complete and channels created specifying a nill connection callback
function pointer are connected. It will report the status of outstanding <a
href="#ca_get">ca_get</a> requests issued, and channels created specifying a
nill connection callback function pointer, after the last call to
ca_pend_io() or CA context initialization whichever is later.</p>
<h4>Returns</h4>
<p>ECA_IODONE - All IO operations completed</p>
<p>ECA_IOINPROGRESS - IO operations still in progress</p>
<h4>See Also</h4>
<p><a href="#ca_pend_io">ca_pend_io</a>()</p>
<h3><code><a name="L3249">ca_pend_event()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_pend_event ( double TIMEOUT );
int ca_poll ();</pre>
<h4>Description</h4>
<p>When ca_pend_event is invoked the send buffer is flushed and CA background
activity is processed for TIMEOUT seconds.</p>
<p>When ca_poll is invoked the send buffer is flushed and any outstanding CA
background activity is processed.</p>
<p>The routine will not return before the time-out expires and all unfinished
channel access labor has been processed.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TIMEOUT</code></dt>
<dd>The duration to block in this routine in seconds. A timeout of zero
seconds blocks forever.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_TIMEOUT - The operation timed out</p>
<p>ECA_EVDISALLOW - Function inappropriate for use within a call back
handler</p>
<h3><code><a name="L3251">ca_flush_io()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_flush_io();</pre>
<h4>Description</h4>
<p>Flush outstanding IO requests to the server. This routine might be useful
to users who need to flush requests prior to performing client side labor in
parallel with labor performed in the server.</p>
<p>Outstanding requests are also sent whenever the buffer which holds them
becomes full.</p>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<h3><code>ca_signal()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING );
void SEVCHK( CA_STATUS, CONTEXT_STRING );</code></pre>
<h4>Description</h4>
<p>Provide the error message character string associated with the supplied
channel access error code and the supplied error context to diagnostics. If
the error code indicates an unsuccessful operation a stack dump is printed,
if this capability is available on the local operating system, and execution
is terminated.</p>
<p>SEVCHK is a macro envelope around ca_signal which only calls ca_signal()
if the supplied error code indicates an unsuccessful operation. SEVCHK is the
recommended error handler for simple applications which do not wish to write
code testing the status returned from each channel access call.</p>
<h4>Examples</h4>
<pre><code>status = ca_context_create (...);
SEVCHK ( status, "Unable to create a CA client context" );</code></pre>
<p>If the application only wishes to print the message associated with an
error code or test the severity of an error there are also functions provided
for this purpose.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CA_STATUS</code></dt>
<dd>The status (error code) returned from a channel access function.</dd>
</dl>
<dl>
<dt><code>CONTEXT_STRING</code></dt>
<dd>A null terminated character string to supply as error context to
diagnostics.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<h3><code><a
name="ca_add_exception_event">ca_add_exception_event()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
typedef void (*pCallback) ( struct exception_handler_args HANDLERARGS );
int ca_add_exception_event ( pCallback USERFUNC, void *USERARG );</pre>
<h4>Description</h4>
<p>Replace the currently installed exception handler call back.</p>
<p>When an error occurs in the server asynchronous to the clients thread then
information about this type of error is passed from the server to the client
in an exception message. When the client receives this exception message an
exception handler callbackis called.The default exceptionhandler printsa
diagnostic message on the client's standard out and terminates execution if
the error condition is severe.</p>
<p>Note that certain fields in "struct exception_handler_args" are not
applicable in the context of some error messages. For instance, a failed get
will supply the address in the client taskwhere thereturned value
wasrequested tobe written. For other failed operations the value of the addr
field should not be used.</p>
<h4>Arguments</h4>
<dl>
<dt><code>USERFUNC</code></dt>
<dd>Addressof usercall back functionto beexecuted when exceptions occur.
Passing a nil value causes the default exception handler to be
reinstalled.</dd>
</dl>
<dl>
<dt><code>USERARG</code></dt>
<dd>pointer sized variable retained and passed back to user function
above</dd>
</dl>
<h4>Example</h4>
<pre><code>void ca_exception_handler (
struct exception_handler_args args)
{
char buf[512];
char *pName;
if ( args.chid ) {
pName = ca_name ( args.chid );
}
else{
pName = "?";
}
sprintf ( buf,
"%s - with request chan=%s op=%d data type=%s count=%d",
args.ctx, pName, args.op, dbr_type_to_text ( args.type ), args.count );
ca_signal ( args.stat, buf );
}
ca_add_exception_event ( ca_exception_handler , 0 );</code></pre>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<h3><code><a name="ca_replace">ca_replace_printf_handler ()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
typedef int caPrintfFunc ( const char *pFromat, va_list args );
int ca_replace_printf_handler ( caPrintfFunc *PFUNC );</code></pre>
<h4>Description</h4>
<p>Replace the default handler for formatted diagnostic message output. The
default handler uses fprintf to send messages to 'stderr'.</p>
<h4>Arguments</h4>
<dl>
<dt><code>PFUNC</code></dt>
<dd>The address of a user supplied call back handler to be invoked when
CA prints diagnostic messages. Installing a nil pointer will cause the
default call back handler to be reinstalled.</dd>
</dl>
<h4>Examples</h4>
<pre><code>int my_printf ( char *pformat, va_list args ) {
int status;
status = vfprintf( stderr, pformat, args);
return status;
}
status = ca_replace_printf_handler ( my_printf );
SEVCHK ( status, "failed to install my printf handler" );</code></pre>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<h3><code><a name="L6935">ca_replace_access_rights_event()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
typedef void ( *pCallBack )( struct access_rights_handler_args );
int ca_replace_access_rights_event ( chid CHAN, pCallBack PFUNC );</code></pre>
<h4>Description</h4>
<p>Install or replace the access rights state change call back handler for
the specified channel.</p>
<p>The call back handler is called in the following situations.</p>
<ul>
<li>whenever CA connects the channel immediately before the channel's
connection handler is called</li>
<li>whenever CA disconnects the channel immediately after the channel's
disconnect call back is called</li>
<li>once immediately after installation if the channel is connected.</li>
<li>whenever the access rights state of a connected channel changes</li>
</ul>
<p>When a channel is created no access rights handler is installed.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHAN</code></dt>
<dd>The channel identifier.</dd>
</dl>
<dl>
<dt><code>PFUNC</code></dt>
<dd>Address of user supplied call back function. A nil pointer uninstalls
the current handler.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<h4>See Also</h4>
<p>ca_modify_user_name()</p>
<p>ca_modify_host_name()</p>
<h3><code><a name="L6925">ca_field_type()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
chtype ca_field_type ( CHID );</code></pre>
<h4>Description</h4>
<p>Return the native type in the server of the process variable.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The data type code will be a member of the set of DBF_XXXX in
db_access.h. The constant TYPENOTCONN is returned if the channel is
disconnected.<a name="ca_element_count"></a></dd>
</dl>
<h3><code>ca_element_count()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
unsigned ca_element_count ( CHID );</code></pre>
<h4>Description</h4>
<p>Return the maximum array element count in  the server for the specified IO
channel.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>COUNT</code></dt>
<dd>The maximum array element count in  the server. An element count of
zero is returned if the channel is disconnected.</dd>
</dl>
<h3><code><a name="L6931">ca_name()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
char * ca_name ( CHID );</code></pre>
<h4>Description</h4>
<p>Return the name provided when the supplied channel id was created.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>PNAME</code></dt>
<dd>The channel name. The string returned is valid as long as the channel
specified exists.</dd>
</dl>
<h3><code><a name="ca_set_puser">ca_set_puser()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
void ca_set_puser ( chid CHID, void *PUSER );</code></pre>
<h4>Description</h4>
<p>Set a user private void pointer variable retained with each channel for
use at the users discretion.</p>
<h4>Arguments</h4>
<dl>
<dt>CHID</dt>
<dd>channel identifier</dd>
</dl>
<dl>
<dt>PUSER</dt>
<dd>user private void pointer</dd>
</dl>
<h3><code><a name="ca_puser">ca_puser()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
void * ca_puser ( CHID );</code></pre>
<h4>Description</h4>
<p>Return a user private void pointer variable retained with each channel for
use at the users discretion.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>PUSER</code></dt>
<dd>user private pointer</dd>
</dl>
<h3><code><a name="L6746">channel_state()</a></code></h3>
<pre><code>/* channel connection state */
#include &lt;cadef.h&gt;
enum channel_state {
cs_never_conn, /* valid chid, server not found or unavaliable */
cs_prev_conn, /* valid chid, previously connected to server */
cs_conn, /* valid chid, connected to server */
cs_closed }; /* channel deleted by user */
enum channel_state ca_state ( CHID );</code></pre>
<h4>Description</h4>
<p>Returns an enumerated type indicating the current state of the specified
IO channel.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>STATE</code></dt>
<dd>the conection state</dd>
</dl>
<h3><code><a name="L6929">ca_message()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
const char * ca_message ( STATUS );</code></pre>
<h4>Description</h4>
<p>return a message character string corresponding to a user specified CA
status code.</p>
<h4>Arguments</h4>
<dl>
<dt><code>STATUS</code></dt>
<dd>a CA status code</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt>STR<code></code>ING</dt>
<dd>the corresponding error message string</dd>
</dl>
<h3><code><a name="L6927">ca_host_name()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
char * ca_host_name ( CHID );</code></pre>
<h4>Description</h4>
<p>Return a character string which contains the name of the host to which a
channel is currently connected.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>the channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>STRING</code></dt>
<dd>The process variable server's host name. If the channel is
disconnected the string "&lt;disconnected&gt;" is returned.</dd>
</dl>
<h3><code><a name="L6933">ca_read_access()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_read_access ( CHID );</code></pre>
<h4>Description</h4>
<p>Returns boolean true if the client currently has read access to the
specified channel and boolean false otherwise.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>the channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>STRING</code></dt>
<dd>boolean true if the client currently has read access to the specified
channel and boolean false otherwisex</dd>
</dl>
<h3><code><a name="L6941">ca_write_access()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_write_access ( CHID );</code></pre>
<h4>Description</h4>
<p>Returns boolean true if the client currently has write access to the
specified channel and boolean false otherwise.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
<dd>the channel identifier</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>STRING</code></dt>
<dd>boolean true if the client currently has write access to the
specified channel and boolean false otherwise</dd>
</dl>
<h3><code><a name="dbr_size[]">dbr_size[]</a></code></h3>
<pre><code>#include &lt;db_access.h&gt;
extern unsigned dbr_size[/*TYPE*/];</code></pre>
<h4>Description</h4>
<p>An array that returns the size in bytes for a DBR_XXXX type.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The data type code. A member of the set of DBF_XXXX in
db_access.h.</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>SIZE</code></dt>
<dd>the size in bytes of the specified type</dd>
</dl>
<h3><code><a name="L6946">dbr_size_n()</a></code></h3>
<pre><code>#include &lt;db_access.h&gt;
unsigned dbr_size_n ( TYPE, COUNT );</code></pre>
<h4>Description</h4>
<p>Returns the size in bytes for a DBR_XXXX type with COUNT elements. If the
DBR type is a structure then the value field is the last field in the
structure. If COUNT is greater than one then COUNT-1 elements are appended to
the end of the structure so that they can be addressed as an array through a
pointer to the value field.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The data type</dd>
</dl>
<dl>
<dt><code>COUNT</code></dt>
<dd>The element count</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>SIZE</code></dt>
<dd>the size in bytes of the specified type with the specified number of
elements</dd>
</dl>
<h3><code><a name="dbr_value_size">dbr_value_size[]</a></code></h3>
<pre><code>#include &lt;db_access.h&gt;
extern unsigned dbr_value_size[/* TYPE */];</code></pre>
<h4>Description</h4>
<p>The array dbr_value_size[TYPE] returns the size in bytes for the value
stored in a DBR_XXXX type. If the type is a structure the size of the value
field is returned otherwise the size of the type is returned.</p>
<h4>Arguments</h4>
<dl>
<dt><code>TYPE</code></dt>
<dd>The data type code. A member of the set of DBF_XXXX in
db_access.h.</dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>SIZE</code></dt>
<dd>the size in bytes of the value field if the type is a structure and
otherwise the size in bytes of the type</dd>
</dl>
<h3><code><a name="ca_test_event">ca_test_event()</a></code></h3>
<pre>#include &lt;cadef.h&gt;</pre>
<h4>Description</h4>
<pre>void ca_test_event ( struct event_handler_args );</pre>
<p>A built-in subscription update call back handler for debugging purposes
that prints diagnostics to standard out.</p>
<h4>Examples</h4>
<pre><code>void ca_test_event ();
status = ca_add_event ( type, chid, ca_test_event, NULL, NULL );
SEVCHK ( status, .... );</code></pre>
<h4>See Also</h4>
<p><a href="#ca_add_event">ca_add_event</a>()</p>
<h3><code><a name="ca_sg_create">ca_sg_create()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_create ( CA_SYNC_GID *PGID );</code></pre>
<h4>Description</h4>
<p>Create a synchronous group and return an identifier for it.</p>
<p>A synchronous group can be used to guarantee that a set of channel access
requests have completed. Once a synchronous group has been created then
channel access get and put requests may be issued within it using ca_sg_get()
and ca_sg_put() respectively. The routines ca_sg_block() and ca_sg_test() can
be used to block for and test for completion respectively. The routine
ca_sg_reset() is used to discard knowledge of old requests which have timed
out and in all likelihood will never be satisfied.</p>
<p>Any number of asynchronous groups can have application requested
operations outstanding within them at any given time.</p>
<h4>Arguments</h4>
<dl>
<dt><code>PGID</code></dt>
<dd>Pointer to a user supplied CA_SYNC_GID.</dd>
</dl>
<h4>Examples</h4>
<pre><code>CA_SYNC_GID gid;
status = ca_sg_create ( &amp;gid );
SEVCHK ( status, Sync group create failed );</code></pre>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_ALLOCMEM - Failed, unable to allocate memory</p>
<h4>See Also</h4>
ca_sg_delete()
<p>ca_sg_block()</p>
<p>ca_sg_test()</p>
<p>ca_sg_reset()</p>
<p>ca_sg_put()</p>
<p>ca_sg_get()</p>
<h3><code><a name="ca_sg_delete">ca_sg_delete()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_delete ( CA_SYNC_GID GID );</code></pre>
<h4>Description</h4>
<p>Deletes a synchronous group.</p>
<h4>Arguments</h4>
<dl>
<dt>GID</dt>
<dd>Identifier of the synchronous group to be deleted.</dd>
</dl>
<h4>Examples</h4>
<pre><code>CA_SYNC_GID gid;
status = ca_sg_delete ( gid );
SEVCHK ( status, Sync group delete failed );</code></pre>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
<h4>See Also</h4>
<p><a href="#ca_sg_create">ca_sg_create</a>()</p>
<h3><a name="ca_sg_block"><code>ca_sg_block</code></a><code>()</code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_block ( CA_SYNC_GID GID, double timeout );</code></pre>
<h4>Description</h4>
<p>Flushes the send buffer and then waits until outstanding requests complete
or the specified time out expires. At this time outstanding requests include
calls to ca_sg_array_get() and calls to ca_sg_array_put(). If ECA_TIMEOUT is
returned then failure must be assumed for all outstanding queries. Operations
can be reissued followed by another ca_sg_block(). This routine will only
block on outstanding queries issued after the last call to ca_sg_block(),
ca_sg_reset(), or ca_sg_create() whichever occurs later in time. If no
queries are outstanding then ca_sg_block() will return immediately without
processing any pending channel access activities.</p>
<p>Values written into your program's variables by a channel access
synchronous group request should not be referenced by your program until
ECA_NORMAL has been received from ca_sg_block(). This routine will process
pending channel access background activity while it is waiting.</p>
<h4>Arguments</h4>
<dl>
<dt>GID</dt>
<dd>Identifier of the synchronous group.</dd>
</dl>
<h4>Examples</h4>
<pre><code>CA_SYNC_GID gid;
status = ca_sg_block(gid);
SEVCHK(status, Sync group block failed);</code></pre>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_TIMEOUT - The operation timed out</p>
<p>ECA_EVDISALLOW - Function inappropriate for use within an event handler</p>
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
<h4>See Also</h4>
<p>ca_sg_test()</p>
<p>ca_sg_reset()</p>
<h3><code><a name="ca_sg_test">ca_sg_test()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_test  ( CA_SYNC_GID GID )</code></pre>
<h4>Description</h4>
<p>Test to see if all requests made within a synchronous group have
completed.</p>
<h4>Arguments</h4>
<dl>
<dt><code>GID</code></dt>
<dd>Identifier of the synchronous group.</dd>
</dl>
<h4>Description</h4>
<p>Test to see if all requests made within a synchronous group have
completed.</p>
<h4>Examples</h4>
<pre><code>CA_SYNC_GID gid;
status = ca_sg_test ( gid );</code></pre>
<h4>Returns</h4>
<p>ECA_IODONE - IO operations completed</p>
<p>ECA_IOINPROGRESS - Some IO operations still in progress</p>
<h3><code><a name="ca_sg_reset">ca_sg_reset()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_reset ( CA_SYNC_GID GID )</code></pre>
<h4>Description</h4>
<p>Reset the number of outstanding requests within the specified synchronous
group to zero so that ca_sg_test() will return ECA_IODONE and ca_sg_block()
will not block unless additional subsequent requests are made.</p>
<h4>Arguments</h4>
<dl>
<dt><code>GID</code></dt>
<dd>Identifier of the synchronous group.</dd>
</dl>
<h4>Examples</h4>
<pre><code>CA_SYNC_GID gid;
status = ca_sg_reset(gid);</code></pre>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
<h3><code><a name="ca_sg_put">ca_sg_put()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
unsigned long COUNT, chid CHID, void *PVALUE );</code></pre>
<p>Write a value, or array of values, to a channel and increment the
outstanding request count of a synchronous group.</p>
<p>All remote operation requests such as the above are accumulated (buffered)
and not forwarded to the server until one of ca_flush_io(), ca_pend_io(),
ca_pend_event(), or ca_sg_pend() are called. This allows several requests to
be efficiently sent in one message.</p>
<p>If a connection is lost and then resumed outstanding puts are not
reissued.</p>
<h4>Arguments</h4>
<dl>
<dt><code>GID</code></dt>
<dd>synchronous group identifier</dd>
</dl>
<dl>
<dt><code>TYPE</code></dt>
<dd>The type of supplied value. Conversion will occur if it does not
match the native type. Specify one from the set of DBR_XXXX in
db_access.h.</dd>
</dl>
<dl>
<dt><code>COUNT</code></dt>
<dd>element count to be written to the specified channel - must match the
array pointed to by PVALUE</dd>
</dl>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<dl>
<dt><code>PVALUE</code></dt>
<dd>A pointer to an application supplied buffer containing the value or
array of valuesReturns</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_BADSYNCGRP - Invalid synchronous group</p>
<p>ECA_BADCHID - Corrupted CHID</p>
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
<p>ECA_STRTOBIG - Unusually large string supplied</p>
<p>ECA_PUTFAIL - A local database put failed</p>
<h4>See Also</h4>
<p><a href="#ca_flush_io">ca_flush_io</a>()</p>
<h3><code><a name="ca_sg_get">ca_sg_get()</a></code></h3>
<pre><code>#include &lt;cadef.h&gt;
int ca_sg_array_get ( CA_SYNC_GID GID,
chtype TYPE, unsigned long COUNT,
chid CHID, void *PVALUE );</code></pre>
<h4>Description</h4>
<p>Read a value from a channel and increment the outstanding request count of
a synchronous group.</p>
<p>The values written into your program's variables by ca_sg_get should not
be referenced by your program until ECA_NORMAL has been received from
ca_sg_block , or until ca_sg_test returns ECA_IODONE.</p>
<p>All remote operation requests such as the above are accumulated (buffered)
and not forwarded to the server until one of ca_flush_io, ca_pend_io,
ca_pend_event, or ca_sg_pend are called. This allows several requests to be
efficiently sent in one message.</p>
<p>If a connection is lost and then resumed outstanding gets are not
reissued.</p>
<h4>Arguments</h4>
<dl>
<dt><code>GID</code></dt>
<dd>Identifier of the synchronous group.</dd>
</dl>
<dl>
<dt><code>TYPE</code></dt>
<dd>External type of returned value. Conversion will occur if this does
not match native type. Specify one from the set of DBR_XXXX in
db_access.h</dd>
</dl>
<dl>
<dt><code>COUNT</code></dt>
<dd>Element count to be read from the specified channel. It must match
the array pointed to by PVALUE.</dd>
</dl>
<dl>
<dt><code>CHID</code></dt>
<dd>channel identifier</dd>
</dl>
<dl>
<dt><code>PVALUE</code></dt>
<dd>Pointer to application supplied buffer that is to contain the value
or array of values to be returned</dd>
</dl>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion </p>
<p>ECA_BADSYNCGRP - Invalid synchronous group </p>
<p>ECA_BADCHID - Corrupted CHID</p>
<p>ECA_BADCOUNT - Requested count larger than native element count</p>
<p>ECA_BADTYPE - Invalid DBR_XXXX type</p>
<p>ECA_GETFAIL - A local database get failed</p>
<h4>See Also</h4>
<p><a href="#ca_pend_io">ca_pend_io</a>()</p>
<p><a href="#ca_flush_io">ca_flush_io</a>()</p>
<p><a href="#ca_get_callback">ca_get_callback</a>()</p>
<h3><code><a name="ca_client_status">ca_client_status()</a></code></h3>
<pre>int ca_client_status ( unsigned level );
int ca_context_status ( struct ca_client_context *,
unsigned level );</pre>
<h4>Description</h4>
<p>Prints information about the client context including, at higher intereest
levels, status for each channel.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CONTEXT</code></dt>
<dd>A pointer to the CA context to join with.</dd>
<dt><code>LEVEL</code></dt>
<dd>The interest level. Increasing level produces increasing detail.</dd>
</dl>
<h3><a name="ca_current_context">ca_current_context()</a></h3>
<pre>struct ca_client_context * ca_current_context ();</pre>
<h4>Description</h4>
<p>Returns a pointer to the current thread's CA context. If none then nil is
returned.</p>
<h4>See Also</h4>
<p>ca_attach_context()</p>
<h3><a name="ca_attach_context">ca_attach_context()</a></h3>
<pre>int ca_attach_context (struct ca_client_context *CONTEXT);</pre>
<h4>Description</h4>
<p>Become a member of the specified CA context. If
<code>ca_disable_preemptive_callback</code> is specified when
ca_context_create() is called (or if ca_task_initialize() is called) then
additional threads are <em>not </em>allowed to join the CA context because
allowing other threads to join implies that CA callbacks will be called
preemptively from more than one thread.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CONTEXT</code></dt>
<dd>A pointer to the CA context to join with.</dd>
</dl>
<h4>Returns</h4>
<p>ECA_ISATTACHED - already attached to a CA context</p>
<h4>See Also</h4>
<p>ca_current_context()</p>
<h2><a name="Command">Command Line Utilities</a></h2>
<h3><a name="acctst">acctst</a></h3>
<pre>acctst &lt;PV name&gt; [progress logging level] [channel duplication count]
[test repetition count] [enable preemptive callback]</pre>
<h4>Description</h4>
<p>Channel Access Client Library regression test.</p>
<p>Test failure is indicated if the program stops prior to printing "test
complete". If unspecified the progress logging level is zero, and no messages
are printed while the test is progressing. If unspecified, the channel
duplication count is 20000. If unspecified, the test repetition count is once
only. If unspecified, preemptive callback is disabled.</p>
<h3><a name="catime">catime</a></h3>
<pre>catime &lt;PV name&gt; [channel count] [append number to pv name if true]</pre>
<h4>Description</h4>
<p>Channel Access Client Library performance test.</p>
<p>If unspecified, the channel count is 10000. If the "append number to pv
name if true" argument is specified and it is greater than zero then the
channel names in the test are numbered as follows.</p>
<p>&lt;PV name&gt;000000, &lt;PV name&gt;000001, ... &lt;PV name&gt;nnnnnn</p>
<h3><a name="casw">casw</a></h3>
<pre>casw</pre>
<h4>Description</h4>
<p>CA server "beacon anomaly" logging.</p>
<p>CA server beacon anomalies occur when a new server joins the network, a
server is rebooted, network connectivity to a server is reestablished, or if
a server's CPU exits a CPU load saturated state.</p>
<p>CA clients with unresolved channels reset their search request schedualing
timers whenever they see a beacon anomaly.</p>
<p>This program can be useful to verify that configuration problems have not
resulted in false beacon anomalies that might cause CA to use unnecessary
additional network bandwidth and server CPU load when searching for
unresolved channels.</p>
<h3><a name="caEventRat">caEventRate</a></h3>
<pre>caEventRate &lt;PV name&gt;</pre>
<h4>Description</h4>
<p>Subscribe to the specified PV and periodically log its event rate.</p>
<h3><a name="ca_test">ca_test</a></h3>
<pre>ca_test &lt;PV name&gt; [value to be written]</pre>
<h4>Description</h4>
<p>If a value is specified it is written to the PV. Next, the current value
of the PV is converted to each of the many external data type that can be
specified at the CA client library interface, and each of these is formated
and then output to the console.</p>
<h2><a name="Return">Return Codes</a></h2>
<dl>
<dt>ECA_NORMAL</dt>
<dd>normal successful completion</dd>
</dl>
<dl>
<dt>ECA_ALLOCMEM</dt>
<dd>unable to allocate memory</dd>
</dl>
<dl>
<dt>ECA_BADTYPE</dt>
<dd>invalid DBR_XXXX type</dd>
</dl>
<dl>
<dt>ECA_STRTOBIG</dt>
<dd>unusually large string supplied</dd>
</dl>
<dl>
<dt>ECA_BADCHID</dt>
<dd>ivalid channel identifier</dd>
</dl>
<dl>
<dt>ECA_BADCOUNT</dt>
<dd>requested count larger than native element count</dd>
</dl>
<dl>
<dt>ECA_PUTFAIL</dt>
<dd>a write request failed in the server</dd>
</dl>
<dl>
<dt>ECA_GETFAIL</dt>
<dd>a read request faile din the server</dd>
</dl>
<dl>
<dt>ECA_ADDFAIL</dt>
<dd>unable to instal subscription request</dd>
</dl>
<dl>
<dt>ECA_TIMEOUT</dt>
<dd>requested operation timed out</dd>
</dl>
<dl>
<dt>ECA_EVDISALLOW</dt>
<dd>function called was inappropriate for use within a callback
function</dd>
</dl>
<dl>
<dt>ECA_IODONE</dt>
<dd>IO operations completed</dd>
</dl>
<dl>
<dt>ECA_IOINPROGRESS</dt>
<dd>some IO operations still in progress</dd>
</dl>
<dl>
<dt>ECA_BADSYNCGRP</dt>
<dd>invalid synchronous group identifier</dd>
</dl>
<dl>
<dt>ECA_NORDACCESS</dt>
<dd>read access denied</dd>
</dl>
<dl>
<dt>ECA_NOWTACCESS</dt>
<dd>write access denied</dd>
</dl>
<p><small>CVS Revision $Id$</small></p>
</body>
</html>