1605 lines
52 KiB
HTML
1605 lines
52 KiB
HTML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
|
<title>EPICS pvAccessCPP</title>
|
|
<link rel="stylesheet" type="text/css"
|
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
|
<link rel="stylesheet" type="text/css"
|
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
|
<style type="text/css">
|
|
/*<![CDATA[*/
|
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
|
table { margin-left: auto; margin-right: auto }
|
|
.diagram { text-align: center; margin: 2.5em 0 }
|
|
span.opt { color: grey }
|
|
span.nterm { font-style:italic }
|
|
span.term { font-family:courier }
|
|
span.user { font-family:courier }
|
|
span.user:before { content:"<" }
|
|
span.user:after { content:">" }
|
|
.nonnorm { font-style:italic }
|
|
p.ed { color: #AA0000 }
|
|
span.ed { color: #AA0000 }
|
|
p.ed.priv { display: inline; }
|
|
span.ed.priv { display: inline; }
|
|
/*]]>*/</style>
|
|
<!-- Script that generates the Table of Contents -->
|
|
<script type="text/javascript"
|
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="head">
|
|
<h1>EPICS pvAccessCPP</h1>
|
|
|
|
<h2 class="nocount">Release 4.0 - 2015.12.10</h2>
|
|
|
|
|
|
<h2 class="nocount">Abstract</h2>
|
|
<p>pvAccessCPP is the C++ implementation of pvAccess,
|
|
which is network support for transporting structured data as defined by pvData.
|
|
</p>
|
|
<p>
|
|
pvAccess is one of a related
|
|
set of products:
|
|
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
|
</p>
|
|
|
|
|
|
|
|
<h2 class="nocount">Status of this Document</h2>
|
|
|
|
<p>This is the 12-December-2015 version of the C++ implementation of pvAccess. The
|
|
code is a complete implementation of pvAccess.</p>
|
|
|
|
</div>
|
|
|
|
<div id="toc">
|
|
<h2 class="nocount">Table of Contents</h2>
|
|
</div>
|
|
|
|
<!-- Place what you would like in the Table of Contents, inside the contents div -->
|
|
<div id="contents" class="contents">
|
|
<hr />
|
|
|
|
|
|
<h2>Preface</h2>
|
|
<p>This product is available via an
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source license
|
|
</a>
|
|
</p>
|
|
<p>This document describes the pvAccess Application Program Interface (API).
|
|
The reader is assumed to have a basic understanding of EPICS V4 as described in:<br />
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
|
|
EPICS V4 Developer's Guide
|
|
</a>
|
|
</p>
|
|
<p>The pvAccess API is callback based and uses Status to report problems to the
|
|
client, which means that it can be complex to use.
|
|
If your primary interest is client access then, instead of reading this document,
|
|
read:<br />
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/docbuild/pvaClientCPP/tip/documentation/pvaClientCPP.html">
|
|
pvaClientCPP
|
|
</a>
|
|
</p>
|
|
<p>If your primary interest is implementing support for PVRecords then,
|
|
before reading this documement read:<br />
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/docbuild/pvDatabaseCPP/tip/documentation/pvDatabaseCPP.html">
|
|
pvDatabaseCPP
|
|
</a>
|
|
</p>
|
|
<p>
|
|
Doxygen documentation is available at
|
|
<a
|
|
href="../html/index.html">doxygenDoc
|
|
</a>
|
|
</p>
|
|
|
|
<h2>Introduction</h2>
|
|
<p>This document briefly describes the most important classes,
|
|
class methods, and global methods used by client and/or service code.
|
|
Not all classes and methods are described.
|
|
When source code from include files is shown it
|
|
is often a simplified version.
|
|
<b>Ptr</b> is shorthand for <b>::shared_pointer</b>
|
|
For example:
|
|
</p>
|
|
<pre>
|
|
ChannelFindPtr
|
|
</pre>
|
|
instead of
|
|
<pre>
|
|
ChannelFind::shared_pointer
|
|
</pre>
|
|
<p>pvAccess provides network support for structured data as described by
|
|
pvData.
|
|
</p>
|
|
<h3>Basic Concepts</h3>
|
|
<p>
|
|
<b>pvAccess</b> has the following basic concepts:
|
|
</p>
|
|
<dl>
|
|
<dt>client and server</dt>
|
|
<dd>pvAccess provides a way for a client to communicate with a server.
|
|
All data passed between client and server is via pvData.
|
|
</dd>
|
|
<dt>channel</dt>
|
|
<dd>A channel is a communication path between a client and a server.
|
|
Each channel has a <b>channelName</b> that is unique within the local area network.
|
|
</dd>
|
|
<dt>provider</dt>
|
|
<dd>
|
|
A provider is the server side of the communication between client and server.
|
|
An arbitrary number of providers can exist.
|
|
<p>
|
|
The client and server can exists in the same process or if the provider is <b>pva</b>
|
|
the provider can be at some remote location in the network.
|
|
</p>
|
|
<p>
|
|
Each provider must have a <b>providerName</b> that is unique in the local process.
|
|
</p>
|
|
<p>An arbitrary number of channelProviders can be implemented
|
|
on both the client and server side.
|
|
</p>
|
|
</dd>
|
|
<dt>registry</dt>
|
|
<dd>
|
|
This allows clients and providers to locate each other.
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3>ChannelProviderRegistry Overview</h3>
|
|
<p>Three global methods are available:</p>
|
|
<dl>
|
|
<dt>getChannelProviderRegistry</dt>
|
|
<dd>Get the single instance of ChannelProviderRegistry.</dd>
|
|
<dt>registerChannelProviderFactory</dt>
|
|
<dd>Register a ChannelProvider</dd>
|
|
<dt>unregisterChannelProviderFactory</dt>
|
|
<dd>Remove a ChannelProvider</dd>
|
|
</dl>
|
|
<p>ChannelProviderRegistry provides the method:</p>
|
|
<dl>
|
|
<dt>getProvider</dt>
|
|
</dl>
|
|
|
|
<h3>ChannelProvider Overview</h3>
|
|
<p>Provides the following methods:</p>
|
|
<dl>
|
|
<dt>createChannel</dt>
|
|
<dd>Create a channel.</dd>
|
|
</dl>
|
|
<h3>Channel Overview</h3>
|
|
<p>Channel provides methods to create the following:</p>
|
|
<dl>
|
|
<dt>ChannelProcess</dt>
|
|
<dd>Client can make requests to process the channel.</dd>
|
|
<dt>ChannelGet</dt>
|
|
<dd>Client can make requests to get data from a channel.</dd>
|
|
<dt>ChannelPut</dt>
|
|
<dd>Client can make requests to put data to a channel.</dd>
|
|
<dt>ChannelPutGet</dt>
|
|
<dd>Client can make requests to put data to a channel,
|
|
process the channel, and get data from the channel.
|
|
</dd>
|
|
<dt>Monitor</dt>
|
|
<dd>Monitor data changes in the channel.</dd>
|
|
<dt>ChannelArray</dt>
|
|
<dd>Get or put data to a sub-array.</dd>
|
|
<dt>ChannelRPC</dt>
|
|
<dd>Similar to ChannelPutGet but data types can change for each request.</dd>
|
|
</dl>
|
|
<h3>ChannelProviders implemented by pvAccessCPP</h3>
|
|
<h4>Client Side</h4>
|
|
<dl>
|
|
<dt>pva network protocol</dt>
|
|
<dd>
|
|
This connects the client to a server via the <b>pva</b> network protocol,
|
|
which is a protocol for passing pvData objects.
|
|
The protocol is described in:<br />
|
|
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/pvAccess_Protocol_Specification.html">
|
|
pvAccess Protocol Specification
|
|
</a>
|
|
</dd>
|
|
<dt>ca network protocol</dt>
|
|
<dd>This connects the client to a server via the <b>ca</b> network protocal,
|
|
i. e. it connects to an existing V3 IOC.
|
|
This is client side only code.
|
|
It transforms data between pvData and ca DBR data,
|
|
The ca protocol is described in:<br />
|
|
<a
|
|
href="http://www.aps.anl.gov/epics/base/R3-14/12-docs/CAref.html">
|
|
Channel Access Reference Manual
|
|
</a>
|
|
</dd>
|
|
</dl>
|
|
<p>Since both the client and server side of pvAccess use the same ChannelProviderRegistry an an arbitrary number of providers can register. Note in particular that both the client and server sides of <b>pva</b> can both register.
|
|
This allows server code to also use <b>pva</b> client to communicate with other servers.
|
|
</p>
|
|
|
|
<h4>Server Side</h4>
|
|
<dl>
|
|
<dt>pva network protocol</dt>
|
|
<dd>The server side for pva network protocol.
|
|
It connects the server side of the network to ChannelProviders.
|
|
</dd>
|
|
<dt>rpcService</dt>
|
|
<dd>This is the "glue" code for implementing the server side of a ChannelRPC service.
|
|
An actual service must implement method request.</dd>
|
|
<dt>PipelineService</dt>
|
|
<dd>This is the "glue" code for implementing the server side pipeline service (reliable monitors using flow control).
|
|
</dd>
|
|
</dl>
|
|
<p>The server side of the pva network protocal.
|
|
allows an arbitrary number of providers to register with it.
|
|
Existing examples are:</p>
|
|
<dl>
|
|
<dt>local provider</dt>
|
|
<dd>pvDatabase implements a PVDatabase, which is a memory resident
|
|
database of PVRecords. Each PVRecord has a name, which is the channel name,
|
|
and a top level PVStructure. A record is "smart" because each record has
|
|
an associated method named process.
|
|
</dd>
|
|
<dt>pvaSrv</dt>
|
|
<dd>This is a ChannelProvider for accessing V3 IOC DBRecords.
|
|
It transforms the data in a V3 DBRecord to a top level PVStructure.
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2>Command Line Utilities</h2>
|
|
<p>pvAccessCPP provides the following command line utilities:<br /> pvlist, pvinfo, pvget, pvput, and eget.</p>
|
|
<p>In order to use these commands a path to the pvAccessCPP bin directory must exists.
|
|
For example, on my linux workstation <b>.bash_profile</b> includes the statements:</p>
|
|
<pre>
|
|
export EPICSV4=/home/epicsv4
|
|
export PATH=$PATH:${EPICSV4}/pvAccessCPP/bin/${EPICS_HOST_ARCH}
|
|
</pre>
|
|
<p>
|
|
This document gives a VERY brief explaination if each command but each provides a -help option.
|
|
For example:</p>
|
|
<pre>
|
|
mrk> pvlist -help
|
|
|
|
Usage: pvlist [options] [server address or GUID starting with '0x']...
|
|
|
|
-h: Help: Print this message
|
|
options:
|
|
-i Print server info (when server address list/GUID is given)
|
|
-w <sec>: Wait time, specifies timeout, default is 3.000000 second(s)
|
|
-q: Quiet mode, print only error messages
|
|
-d: Enable debug output
|
|
|
|
examples:
|
|
pvlist
|
|
pvlist ioc0001
|
|
pvlist 10.5.1.205:10000
|
|
pvlist 0x83DE3C540000000000BF351F
|
|
</pre>
|
|
<p>
|
|
A longer explanation of the commands is in:</p>
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
|
|
EPICS V4 Developer's Guide
|
|
</a>
|
|
<h3>pvlist</h3>
|
|
<p>Shows all servers avaliable via the pva network protocal and also a list
|
|
of all channels for a particular server.
|
|
</p>
|
|
<h3>pvinfo</h3>
|
|
<p>Shows the connection status and introspection interface for channels.</p>
|
|
<h3>pvget</h3>
|
|
<p>Returns data for a channel via channelGet or monitor.
|
|
</p>
|
|
<h3>pvput</h3>
|
|
<p>Puts data to a channel via channelPut.</p>
|
|
<h3>eget</h3>
|
|
<p>pvget on steroids.
|
|
Also has support for channelRPC and some of the normative types.</p>
|
|
<h2>Include Files</h2>
|
|
<p>The following are the include files that are of most interest to clients:</p>
|
|
<dl>
|
|
<dt>pvAccess.h</dt>
|
|
<dd>This document discusses most of the clases described in pvAccess.h.
|
|
The following are not discussed in this document:
|
|
<pre>
|
|
enum AccessRights {none,read,readWrite};
|
|
class Lockable...
|
|
class ScopedLock...
|
|
</pre>
|
|
</dd>
|
|
<dt>clientFactory.h</dt>
|
|
<dd>Static methods to start and stop the pva provider.</dd>
|
|
<dt>rpcClient.h</dt>
|
|
<dd>Code for implementing the client side of a channelRPC request.
|
|
</dd>
|
|
<dt>caProvider.h</dt>
|
|
<dd>Needed to start the provider for the ca network protocol.
|
|
</dd>
|
|
</dl>
|
|
<p>The following are of interest to service code:</p>
|
|
<dl>
|
|
<dt>serverContext.h</dt>
|
|
<dd>Needed to start pvAccess Server Context.</dd>
|
|
<dt>rpcServer.h</dt>
|
|
<dd>Code for implementing the context for server side of a channelRPC request.
|
|
</dd>
|
|
<dt>rpcService.h</dt>
|
|
<dd>Each channelRpc service must implement RPCService or RPCServiceAsync interface.</dd>
|
|
<dt>pipelineServer.h</dt>
|
|
<dd>Code for implementing the context for server side pipeline service.
|
|
</dd>
|
|
<dt>pipelineService.h</dt>
|
|
<dd>Each pipeline service must implement PipelineService interface.</dd>
|
|
</dl>
|
|
|
|
<h2>Starting PVAccess Clients</h2>
|
|
<p>To start both the pva and ca client providers issue the commands:</p>
|
|
<pre>
|
|
ClientFactory::start();
|
|
CAClientFactory::start();
|
|
</pre>
|
|
|
|
<h2>Starting pvAccess Server Context</h2>
|
|
<p>To see examples of how to start a pvAccess server look at the examples provided
|
|
in <b>exampleDatabaseCPP</b>.
|
|
It shows examples for both a standalone main server and a V4 server that runs as part of
|
|
a V3 IOC.
|
|
The following is taken from <b>exampleDatabaseMain.cpp</b> that is in example database:</p>
|
|
<pre>
|
|
int main(int argc,char *argv[])
|
|
{
|
|
|
|
...
|
|
|
|
ChannelProviderLocalPtr channelProvider = getChannelProviderLocal();
|
|
ServerContext::shared_pointer ctx =
|
|
startPVAServer(PVACCESS_ALL_PROVIDERS,0,true,true);
|
|
|
|
...
|
|
ctx->destroy();
|
|
return 0;
|
|
}
|
|
</pre>
|
|
|
|
|
|
<h2>class ChannelProviderRegistry</h2>
|
|
<pre>
|
|
class ChannelProviderRegistry
|
|
{
|
|
public:
|
|
virtual ~ChannelProviderRegistry();
|
|
virtual ChannelProviderPtr getProvider(string const & providerName);
|
|
virtual ChannelProviderPtr createProvider(string const & providerName);
|
|
virtual std::auto_ptr<vector<string> > getProviderNames();
|
|
};
|
|
epicsShareExtern ChannelProviderRegistryPtr getChannelProviderRegistry();
|
|
epicsShareExtern void registerChannelProviderFactory(ChannelProviderFactoryPtr const & channelProviderFactory);
|
|
epicsShareExtern void unregisterChannelProviderFactory(ChannelProviderFactoryPtr const & channelProviderFactor
|
|
</pre>
|
|
<p>The global methods are:</p>
|
|
<dl>
|
|
<dt>getChannelProviderRegistry</dt>
|
|
<dd>Called by both client and services to get the single instance of <b>ChannelProviderRegistry</b>.
|
|
</dd>
|
|
<dt>registerChannelProviderFactory</dt>
|
|
<dd>Called by a service that implements ChannelProvider.
|
|
Note that implementing a ChannelProvider is a big task,
|
|
which is why pvDatabaseCPP exists.
|
|
</dd>
|
|
<dt>unregisterChannelProviderFactory</dt>
|
|
<dd>Called by a service if it no longer wants the provider to be used.</dd>
|
|
</dl>
|
|
<p>The methods for <b>ChannelProviderRegistry</b> are:</p>
|
|
<dl>
|
|
<dt>getProvider</dt>
|
|
<dd>Called by both client and services to get the shared instance of channelProvider.<br />
|
|
The providerName must be the name of a registered provider.<br />
|
|
Most clients will use either <b>pva</b> or <b>ca</b>.<br />
|
|
Most services will use pvDatabaseCPP, which implements provider <b>local</b>.
|
|
A service that is also a client can also use <b>local</b> or <b>pvaSrv</b>.
|
|
</dd>
|
|
<dt>createProvider</dt>
|
|
<dd>Same as getProvider just that this call creates a new instance of the provider (i.e. this instance is not shared).
|
|
<br />Most clients will use getProvider method.</dd>
|
|
<dt>getProviderNames</dt>
|
|
<dd>Gets the names of all registered providers.</dd>
|
|
</dl>
|
|
<h2>class ChannelProvider</h2>
|
|
<pre>
|
|
class ChannelProvider
|
|
{
|
|
public:
|
|
static const short PRIORITY_MIN = 0;
|
|
static const short PRIORITY_MAX = 99;
|
|
static const short PRIORITY_DEFAULT = PRIORITY_MIN;
|
|
static const short PRIORITY_LINKS_DB = PRIORITY_MAX;
|
|
static const short PRIORITY_ARCHIVE = (PRIORITY_MAX + PRIORITY_MIN) / 2;
|
|
static const short PRIORITY_OPI = PRIORITY_MIN;
|
|
|
|
virtual destroy() {}
|
|
virtual std::string getProviderName() = 0;
|
|
virtual ChannelFindPtr channelFind(
|
|
std::string const & channelName,
|
|
ChannelFindRequesterPtr const & channelFindRequester) = 0;
|
|
virtual ChannelFindPtr channelList(
|
|
ChannelListRequesterPtr const & channelListRequester) = 0;
|
|
virtual ChannelPtr createChannel(
|
|
std::string const & channelName,
|
|
ChannelRequesterPtr const & channelRequester,
|
|
virtual ChannelPtr createChannel(
|
|
std::string const & channelName,
|
|
ChannelRequesterPtr const & channelRequester,
|
|
short priority,
|
|
std::string const & address);
|
|
|
|
/// experimental methods
|
|
virtual void configure(PVStructurePtr /*configuration*/) {};
|
|
virtual void flush() {};
|
|
virtual void poll() {};
|
|
|
|
};
|
|
|
|
class ChannelFind
|
|
{
|
|
public:
|
|
virtual ChannelProviderPtr getChannelProvider();
|
|
virtual void cancel();
|
|
};
|
|
|
|
class ChannelFindRequester
|
|
{
|
|
public:
|
|
virtual ~ChannelFindRequester() {}
|
|
virtual void channelFindResult(
|
|
const Status& status,
|
|
ChannelFindPtr const & channelFind,
|
|
bool wasFound) = 0;
|
|
};
|
|
|
|
class ChannelListRequester
|
|
{
|
|
public:
|
|
virtual ~ChannelListRequester() {};
|
|
virtual void channelListResult(
|
|
const Status& status,
|
|
ChannelFindPtr const & channelFind,
|
|
PVStringArray::const_svector const & channelNames,
|
|
bool hasDynamic) = 0;
|
|
};
|
|
</pre>
|
|
<p>The methods of <b>ChannelProvider</b> are:</p>
|
|
<dl>
|
|
<dt>getProviderName</dt>
|
|
<dd>Returns the name of the channel provider.</dd>
|
|
<dt>channelFind</dt>
|
|
<dd>Determines if the channel exists.
|
|
The result is passed by calling the channelFindResult of channelFindRequester.
|
|
The caller must implement channelFindRequester, which is described below.
|
|
The return value is ChannelFindPtr, which the caller can use to cancel a request.
|
|
</dd>
|
|
<dt>channelList</dt>
|
|
<dd>Gets a list of all the channels served by this provider.
|
|
The result is passed by calling the channelListResult of channelListRequester.
|
|
The caller must implement channelListRequester, which is described below.
|
|
The return value is ChannelFindPtr, which the caller can use to cancel a request.
|
|
</dd>
|
|
<dt>createChannel</dt>
|
|
<dd>Creates a connection to a channel.
|
|
The result passed by calling methods of ChannelRequester.
|
|
The caller must implememt ChannelRequester, which is described along with Channel below.
|
|
</dd>
|
|
</dl>
|
|
<p>The methods of <b>ChannelFind</b> are:</p>
|
|
<dl>
|
|
<dt>getChannelProvider</dt>
|
|
<dd>Returns the provider.</dd>
|
|
<dt>cancel</dt>
|
|
<dd>Cancel the current channelFind or channelList request.</dd>
|
|
</dl>
|
|
<p>The method of <b>ChannelFindRequester are:</b></p>
|
|
<dl>
|
|
<dt>channelFindResult</dt>
|
|
<dd>If wasFound is true then status is OK.
|
|
If not found then status provides reason for failure.
|
|
</dd>
|
|
</dl>
|
|
<p>The method of <b>ChannelListRequester are:</b></p>
|
|
<dl>
|
|
<dt>channelListResult</dt>
|
|
<dd>If there is a problem with the channelList request status provides the reason.
|
|
channelNames provides the list of channels the provider is
|
|
currently providing. hasDynamic indicates that the set of channels is not static, i.e. might
|
|
change during runtime.<br />
|
|
</dd>
|
|
</dl>
|
|
<h2>Channel</h2>
|
|
<h3>class ChannelRequester</h3>
|
|
<p>This must be implemented by a client.
|
|
It shows the result of a <b>ChannelProvider::createChannel</b> request
|
|
and also the connection state of the channel.
|
|
</p>
|
|
<pre>
|
|
class ChannelRequester : Requester
|
|
{
|
|
public:
|
|
virtual void channelCreated(
|
|
const Status& status, ChannelPtr const & channel) = 0;
|
|
virtual void channelStateChange(
|
|
ChannelPtr const & channel,
|
|
Channel::ConnectionState connectionState) = 0;
|
|
};
|
|
</pre>
|
|
<p>The methods of <b>ChannelRequester are:</b></p>
|
|
<dl>
|
|
<dt>channelCreated</dt>
|
|
<dd>This is called as a result of a <b>ChannelProvider::createChannel</b> request.
|
|
It shows if the request was successful.
|
|
If not successful then channel is null and status shows why the request failed.
|
|
</dd>
|
|
<dt>channelStateChange</dt>
|
|
<dd>When the client successfuly connects to a channel this is called with ConnectionState=CONNECTED.
|
|
After successfuly connecting the client can call the channel methods.
|
|
<br />
|
|
This method is also called whenever the channel disconnects or re-connects.
|
|
When a reconnect occurs the implementaion automatically reconnects any
|
|
channelGet, channelPut, etc that the client has created.
|
|
</dd>
|
|
</dl>
|
|
<h3>class Channel</h3>
|
|
<pre>
|
|
class Channel : Requester ...
|
|
{
|
|
public:
|
|
POINTER_DEFINITIONS(Channel);
|
|
|
|
enum ConnectionState {
|
|
NEVER_CONNECTED, CONNECTED, DISCONNECTED, DESTROYED
|
|
};
|
|
|
|
static const char* ConnectionStateNames[];
|
|
|
|
virtual destroy() {}
|
|
virtual ChannelProviderPtr getProvider() = 0;
|
|
virtual std::string getRemoteAddress() = 0;
|
|
virtual ConnectionState getConnectionState() = 0;
|
|
virtual std::string getChannelName() = 0;
|
|
virtual ChannelRequesterPtr getChannelRequester() = 0;
|
|
virtual bool isConnected() = 0;
|
|
virtual void getField(
|
|
GetFieldRequesterPtr const & requester,
|
|
std::string const & subField) = 0;
|
|
virtual AccessRights getAccessRights(PVFieldPtr const & pvField) = 0;
|
|
virtual ChannelProcessPtr createChannelProcess(
|
|
ChannelProcessRequesterPtr const & channelProcessRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual ChannelGetPtr createChannelGet(
|
|
ChannelGetRequesterPtr const & channelGetRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual ChannelPutPtr createChannelPut(
|
|
ChannelPutRequesterPtr const & channelPutRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual ChannelPutGetPtr createChannelPutGet(
|
|
ChannelPutGetRequesterPtr const & channelPutGetRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual ChannelRPCPtr createChannelRPC(
|
|
ChannelRPCRequesterPtr const & channelRPCRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual MonitorPtr createMonitor(
|
|
MonitorRequesterPtr const & monitorRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual ChannelArrayPtr createChannelArray(
|
|
ChannelArrayRequesterPtr const & channelArrayRequester,
|
|
PVStructurePtr const & pvRequest) = 0;
|
|
virtual void printInfo() = 0;
|
|
virtual void printInfo(std::ostream& out) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>destroy</dt>
|
|
<dd>
|
|
Destroy all resources belonging to the channel.
|
|
This includes all channelPuts, channelGets, etc and any remote connections.
|
|
</dd>
|
|
<dt>getProvider</dt>
|
|
<dd>
|
|
Get the name of the provider.
|
|
</dd>
|
|
<dt>getRemoteAddress</dt>
|
|
<dd>
|
|
Get the remote address of the channel.
|
|
</dd>
|
|
<dt>getConnectionState</dt>
|
|
<dd>
|
|
Get the connection state.
|
|
</dd>
|
|
<dt>getChannelName</dt>
|
|
<dd>
|
|
Get the channel name.
|
|
</dd>
|
|
<dt>getChannelRequester</dt>
|
|
<dd>
|
|
Get the interface to the code that created the channel.
|
|
</dd>
|
|
<dt>isConnected</dt>
|
|
<dd>
|
|
Is the channel connected?
|
|
</dd>
|
|
<dt>getField</dt>
|
|
<dd>
|
|
Get the introspection interface for the subfield of the PVStructure attached to the channel.
|
|
The result is returned via the GetFieldRequester, which must be implemented by the caller.
|
|
</dd>
|
|
<dt>getAccessRights</dt>
|
|
<dd>
|
|
Get the access rights for the caller.
|
|
The access rights are one of <b>none</b>, <b>read</b> , or <b>readWrite</b>.
|
|
</dd>
|
|
<dt>createChannelProcess</dt>
|
|
<dd>
|
|
Create a ChannelProcess, which is described below.
|
|
</dd>
|
|
<dt>createChannelGet</dt>
|
|
<dd>
|
|
Create a ChannelGet, which is described below.
|
|
</dd>
|
|
<dt>createChannelPut</dt>
|
|
<dd>
|
|
Create a ChannelPut, which is described below.
|
|
</dd>
|
|
<dt>createChannelPutGet</dt>
|
|
<dd>
|
|
Create a ChannelPutGet, which is described below.
|
|
</dd>
|
|
<dt>createChannelRPC</dt>
|
|
<dd>
|
|
Create a ChannelRPC, which is described below.
|
|
</dd>
|
|
<dt>createMonitor</dt>
|
|
<dd>
|
|
Create a Monitor, which is described below.
|
|
</dd>
|
|
<dt>createChannelArray</dt>
|
|
<dd>
|
|
Create a ChannelArray, which is described below.
|
|
</dd>
|
|
<dt>printInfo</dt>
|
|
<dd>
|
|
Print information about the channel.
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3>class GetFieldRequester</h3>
|
|
<pre>
|
|
class GetFieldRequester : virtual public Requester {
|
|
public:
|
|
virtual void getDone(
|
|
const Status& status,
|
|
FieldConstPtr const & field) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>getDone</dt>
|
|
<dd>This is called as a result of a call to Channel::getField.
|
|
status shows the result.
|
|
if status is OK then field is the introspection interface for the requested field.
|
|
</dd>
|
|
</dl>
|
|
<h3>class ChannelRequest</h3>
|
|
<p>This is a base class for ChannelGet, ChannelPut, etc.</p>
|
|
<pre>
|
|
class ChannelRequest
|
|
{
|
|
public:
|
|
virtual ChannelPtr getChannel() = 0;
|
|
virtual void cancel() = 0;
|
|
virtual void lastRequest() = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>getChannel</dt>
|
|
<dd>Get the Channel interface.</dd>
|
|
<dt>cancel</dt>
|
|
<dd>Cancel any outstanding request</dd>
|
|
<dt>lastRequest</dt>
|
|
<dd>The current request is the last request.
|
|
Allows the implementation to release resources
|
|
</dd>
|
|
</dl>
|
|
<h2>ChannelGet</h2>
|
|
<p>This is used to get data from a server.</p>
|
|
<h3>class ChannelGet</h3>
|
|
<pre>
|
|
class ChannelGet : public ChannelRequest {
|
|
public:
|
|
virtual void get() = 0;
|
|
};
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>get</dt>
|
|
<dd>Issue a get request to the server.
|
|
The result is returned via a call to ChannelGetRequester::getDone.
|
|
Only one get request at a time can be outstanding, i. e.
|
|
a new get can not be issued until the callback for the first is called.
|
|
</dd>
|
|
</dl>
|
|
<h3>class ChannelGetRequester</h3>
|
|
<pre>
|
|
class ChannelGetRequester : virtual public Requester {
|
|
public:
|
|
virtual void channelGetConnect(
|
|
const Status& status,
|
|
ChannelGetPtr const & channelGet,
|
|
Structure::const_shared_pointer const & structure) = 0;
|
|
virtual void getDone(
|
|
const Status& status,
|
|
ChannelGetPtr const & channelGet,
|
|
PVStructurePtr const & pvStructure,
|
|
BitSetPtr const & bitSet) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>channelGetConnect</dt>
|
|
<dd>This is called as a result of calling Channel::createChannelGet.
|
|
If status is OK, then channelGet is the interface to ChannelGet and
|
|
structure is the introspection interface that will be used for
|
|
the data returned by every call to ChannelGet::get.
|
|
If status shows a failure then the client should NOT use either channelGet
|
|
or structure.
|
|
</dd>
|
|
<dt>getDone</dt>
|
|
<dd>This is called as a result of a call to ChannelGet::get.
|
|
status shows the result.
|
|
if status is OK then pvStructure has the data and bitSet shows which fields
|
|
have changed since the previous call.
|
|
The data and bitSet "belong" to the client until the next get is issued.
|
|
After that the data may change.
|
|
</dd>
|
|
</dl>
|
|
<h2>ChannelPut</h2>
|
|
<p>This is used to put data to a server.</p>
|
|
<h3>class ChannelPut</h3>
|
|
<pre>
|
|
class ChannelPut : public ChannelRequest {
|
|
public:
|
|
virtual void put(
|
|
PVStructurePtr const & pvPutStructure,
|
|
BitSetPtr const & putBitSet) = 0;
|
|
virtual void get() = 0;
|
|
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>put</dt>
|
|
<dd>Put all changed fields of pvPutStructure to the server.
|
|
putBitSet shows which fields are to be sent.
|
|
When the put completes (an ack is received from the server)
|
|
ChannelPutRequester::putDone is called.
|
|
Only one put or get request at a time can be outstanding, i. e.
|
|
a new put or get can not be issued until the callback for the first is called.
|
|
</dd>
|
|
<dt>get</dt>
|
|
<dd>Get the current data from the server.
|
|
The result is returned via a call to ChannelPutRequester::getDone.
|
|
</dd>
|
|
</dl>
|
|
<h3>class ChannelPutRequester</h3>
|
|
<pre>
|
|
class ChannelPutRequester : virtual public Requester {
|
|
public:
|
|
virtual void channelPutConnect(
|
|
const Status& status,
|
|
ChannelPutPtr const & channelPut,
|
|
Structure::const_shared_pointer const & structure) = 0;
|
|
virtual void putDone(
|
|
Status & status,
|
|
ChannelPutPtr const & channelPut) = 0;
|
|
virtual void getDone(
|
|
const Status& status,
|
|
ChannelPutPtr const & channelPut,
|
|
PVStructurePtr const & pvStructure,
|
|
BitSetPtr const & bitSet) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>channelPutConnect</dt>
|
|
<dd>This is called as a result of calling Channel::createChannelPut.
|
|
If status is OK, then channelPut is the interface to ChannelPut and
|
|
structure is the introspection interface that
|
|
must be used for the pvStructure passed to each ChannelPut::put
|
|
and will be used for
|
|
the data returned by every call to ChannelPut::get.
|
|
If status shows a failure then the client should NOT use either channelPut
|
|
or structure.
|
|
</dd>
|
|
<dt>putDone</dt>
|
|
<dd>Called when ChannelPut::put is acknowledged by the server.
|
|
status shows the result.
|
|
</dd>
|
|
|
|
<dt>getDone</dt>
|
|
<dd>This is called as a result of a call to ChannelPut::get.
|
|
status shows the result.
|
|
if status is OK then pvStructure has the data and bitSet shows which fields
|
|
have changed since the previous call.
|
|
The data and bitSet "belong" to the client until the next get is issued.
|
|
After that the data may change.
|
|
</dd>
|
|
</dl>
|
|
<h2>ChannelPutGet</h2>
|
|
<p>This is used to:</p>
|
|
<pre>
|
|
put data to a server
|
|
process
|
|
get data from the server
|
|
</pre>
|
|
<h3>class ChannelPutGet</h3>
|
|
<pre>
|
|
class ChannelPutGet : public ChannelRequest {
|
|
public:
|
|
virtual void putGet(
|
|
PVStructurePtr const & pvPutStructure,
|
|
BitSetPtr const & putBitSet) = 0;
|
|
virtual void getPut() = 0;
|
|
virtual void getGet() = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>putGet</dt>
|
|
<dd>Put all changed fields of pvPutStructure to the server.
|
|
putBitSet shows which fields are to be sent.
|
|
<br />
|
|
The server processes and returns data to the client.
|
|
<br />
|
|
When the putGet completes
|
|
ChannelPutGetRequester::putDone is called with the result.
|
|
<br />
|
|
Only one putGet or getGet or getPut request at a time can be outstanding, i. e.
|
|
a new request can not be issued until the callback for the first is called.
|
|
</dd>
|
|
<dt>getPut</dt>
|
|
<dd>Get the current put data from the server.
|
|
<br />
|
|
The result is returned via a call to ChannelPutGetRequester::getPutDone.
|
|
</dd>
|
|
<dt>getGet</dt>
|
|
<dd>Get the current get data from the server.
|
|
<br />
|
|
The result is returned via a call to ChannelPutGetRequester::getGet.
|
|
</dd>
|
|
</dl>
|
|
<h3>class ChannelPutGetRequester</h3>
|
|
<pre>
|
|
class ChannelPutGetRequester : virtual public Requester
|
|
{
|
|
public:
|
|
virtual void channelPutGetConnect(
|
|
const Status& status,
|
|
ChannelPutGetPtr const & channelPutGet,
|
|
Structure::const_shared_pointer const & putStructure,
|
|
Structure::const_shared_pointer const & getStructure) = 0;
|
|
|
|
virtual void putGetDone(
|
|
const Status& status,
|
|
ChannelPutGetPtr const & channelPutGet,
|
|
PVStructurePtr const & pvGetStructure,
|
|
BitSetPtr const & getBitSet) = 0;
|
|
|
|
virtual void getPutDone(
|
|
const Status& status,
|
|
ChannelPutGetPtr const & channelPutGet,
|
|
PVStructurePtr const & pvPutStructure,
|
|
BitSetPtr const & putBitSet) = 0;
|
|
|
|
virtual void getGetDone(
|
|
const Status& status,
|
|
ChannelPutGetPtr const & channelPutGet,
|
|
PVStructurePtr const & pvGetStructure,
|
|
BitSetPtr const & getBitSet) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>channelPutGetConnect</dt>
|
|
<dd>This is called as a result of calling Channel::createChannelPutGet.
|
|
<br />
|
|
If status is OK, then
|
|
putStructure is the introspection interface that 1)
|
|
must be used for the pvStructure passed to each ChannelPutGet::putGet
|
|
and 2) will be used for
|
|
the data returned by every call to ChannelPutGet::getPut.
|
|
<br />
|
|
getStructure is the introspection interface that will be used for
|
|
the data returned by every call to ChannelPutGet::getGet and ChannelPut::putGet.
|
|
<br />
|
|
If status shows a failure then the client should NOT use either channelPut
|
|
or putStructure or getStructure.
|
|
</dd>
|
|
<dt>putGetDone</dt>
|
|
<dd>Called when ChannelPutGet::putGet is acknowledged by the server.
|
|
status shows the result.
|
|
If status is OK then pvGetStructure has the data and getBitSet shows which fields
|
|
have changed since the previous call.
|
|
The data and bitSet "belong" to the client until the next putGet or getGet is issued.
|
|
After that the data may change.
|
|
</dd>
|
|
|
|
<dt>getPutDone</dt>
|
|
<dd>This is called as a result of a call to ChannelPutGet::getPut.
|
|
status shows the result.
|
|
If status is OK then pvPutStructure has the data and putBitSet shows which fields
|
|
have changed since the previous call.
|
|
The data and bitSet "belong" to the client until the next get is issued.
|
|
After that the data may change.
|
|
</dd>
|
|
<dt>getGetDone</dt>
|
|
<dd>Called when ChannelPutGet::getGet is acknowledged by the server.
|
|
status shows the result.
|
|
If status is OK then pvGetStructure has the data and getBitSet shows which fields
|
|
have changed since the previous call.
|
|
The data and bitSet "belong" to the client until the next putGet or getGet is issued.
|
|
After that the data may change.
|
|
</dd>
|
|
|
|
<dt>getPutDone</dt>
|
|
<dd>This is called as a result of a call to ChannelPutGet::getPut.
|
|
status shows the result.
|
|
If status is OK then pvPutStructure has the data and putBitSet shows which fields
|
|
have changed since the previous call.
|
|
The data and bitSet "belong" to the client until the next get is issued.
|
|
After that the data may change.
|
|
</dd>
|
|
</dl>
|
|
<h2>ChannelArray</h2>
|
|
<h3>class ChannelArray</h3>
|
|
<p>Get/Put a subset of an array.
|
|
This works for all of scalarArray, unionArray, and structureArray.</p>
|
|
<pre>
|
|
class ChannelArray : public ChannelRequest
|
|
{
|
|
public:
|
|
virtual void putArray(
|
|
PVArrayPtr const & putArray,
|
|
size_t offset = 0,
|
|
size_t count = 0,
|
|
size_t stride = 1) = 0;
|
|
virtual void getArray(
|
|
size_t offset = 0,
|
|
size_t count = 0,
|
|
size_t stride = 1) = 0;
|
|
virtual void getLength() = 0;
|
|
virtual void setLength(size_t length) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>putArray</dt>
|
|
<dd>The putArray is sent to the server, which changes to specified
|
|
elements of the server array.</dd>
|
|
<dt>getArray</dt>
|
|
<dd>The server selects the specified set of elements in the
|
|
server array and returns the result to the client.
|
|
</dd>
|
|
<dt>getLength</dt>
|
|
<dd>Get the current length of the server array.</dd>
|
|
<dt>setLength</dt>
|
|
<dd>Set the length of the server array.</dd>
|
|
</dl>
|
|
<h3>class ChannelArrayRequester</h3>
|
|
<pre>
|
|
class ChannelArrayRequester : virtual public Requester {
|
|
public:
|
|
virtual void channelArrayConnect(
|
|
const Status& status,
|
|
ChannelArrayPtr const & channelArray,
|
|
Array::const_shared_pointer const & array) = 0;
|
|
virtual void putArrayDone(
|
|
const Status& status,
|
|
ChannelArrayPtr const & channelArray) = 0;
|
|
virtual void getArrayDone(
|
|
const Status& status,
|
|
ChannelArrayPtr const & channelArray,
|
|
PVArrayPtr const & pvArray) = 0;
|
|
virtual void getLengthDone(
|
|
const Status& status,
|
|
ChannelArrayPtr const & channelArray,
|
|
size_t length) = 0;
|
|
virtual void setLengthDone(
|
|
const Status& status,
|
|
ChannelArrayPtr const & channelArray) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>channelArrayConnect</dt>
|
|
<dd>This is called as a result of calling Channel::createChannelArray.
|
|
<br />
|
|
If status is OK, then array is the introspection interface
|
|
that 1) must be used for creating the putArray for ChannelArray::putArray,
|
|
and 2) will be the interface for the result passed to getArrayDone.
|
|
</dd>
|
|
<dt>putArrayDone</dt>
|
|
<dd>The result of calling ChannelArray::putArray.
|
|
status shows the result.
|
|
</dd>
|
|
<dt>getArrayDone</dt>
|
|
<dd>The result of calling ChannelArray::getArray.
|
|
status shows the result.
|
|
<br />
|
|
If status is OK, pvArray has the result.
|
|
</dd>
|
|
<dt>getLengthDone</dt>
|
|
<dd>The result of calling ChannelArray::getLength.
|
|
status shows the result.
|
|
<br />
|
|
If status is OK length is the length of the server array.
|
|
</dd>
|
|
<dt>setLengthDone</dt>
|
|
<dd>The result of calling ChannelArray::setLength.
|
|
status shows the result.
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2>Monitor</h2>
|
|
<p>Described in pvDataCPP.
|
|
See:
|
|
<a
|
|
href="http://epics-pvdata.sourceforge.net/docbuild/pvDataCPP/tip/documentation/pvDataCPP.html">
|
|
EPICS pvDataCPP
|
|
</a>
|
|
</p>
|
|
<p>For convenience the classes are shown here.</p>
|
|
<h3>class MonitorElement</h3>
|
|
<pre>
|
|
class MonitorElement {
|
|
public:
|
|
MonitorElement(){}
|
|
MonitorElement(PVStructurePtr const & pvStructurePtr);
|
|
PVStructurePtr pvStructurePtr;
|
|
BitSetPtr changedBitSet;
|
|
BitSetPtr overrunBitSet;
|
|
};
|
|
</pre>
|
|
<h3>class Monitor</h3>
|
|
<pre>
|
|
class Monitor : public Destroyable{
|
|
public:
|
|
virtual ~Monitor(){}
|
|
virtual Status start() = 0;
|
|
virtual Status stop() = 0;
|
|
virtual MonitorElementPtr poll() = 0;
|
|
virtual void release(MonitorElementPtr const & monitorElement) = 0;
|
|
};
|
|
</pre>
|
|
<h3>class MonitorRequester</h3>
|
|
<pre>
|
|
class MonitorRequester : public virtual Requester {
|
|
public:
|
|
virtual ~MonitorRequester(){}
|
|
virtual void monitorConnect(Status const & status,
|
|
MonitorPtr const & monitor, StructureConstPtr const & structure) = 0;
|
|
virtual void monitorEvent(MonitorPtr const & monitor) = 0;
|
|
virtual void unlisten(MonitorPtr const & monitor) = 0;
|
|
};
|
|
</pre>
|
|
<h2>ChannelRPC</h2>
|
|
<h3>class ChannelRPC</h3>
|
|
<pre>
|
|
class ChannelRPC : public ChannelRequest {
|
|
public:
|
|
virtual void request(PVStructurePtr const & pvArgument) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>request</dt>
|
|
<dd>Issue a request to the server.
|
|
<br />
|
|
pvArgument is sent to the server.
|
|
The server processes the request and returns the result by calling ChannelRPCRequester::requestDone.
|
|
</dd>
|
|
</dl>
|
|
<h3>class ChannelRPCRequester</h3>
|
|
<pre>
|
|
class ChannelRPCRequester : virtual public Requester {
|
|
public:
|
|
virtual void channelRPCConnect(
|
|
const Status& status,
|
|
ChannelRPCPtr const & channelRPC) = 0;
|
|
|
|
virtual void requestDone(
|
|
const Status& status,
|
|
ChannelRPCPtr const & channelRPC,
|
|
PVStructurePtr const & pvResponse) = 0;
|
|
};
|
|
</pre>
|
|
where:
|
|
<dl>
|
|
<dt>channelRPCConnect</dt>
|
|
<dd>Called as a result of Channel::createChannelRPC.
|
|
<br />
|
|
status shows the result.
|
|
</dd>
|
|
<dt>requestDone</dt>
|
|
<dd>Called as a result of ChannelRPC::request.
|
|
<br />
|
|
status shows the result.
|
|
<br />
|
|
If status is OK pvResponse is the result.
|
|
</dd>
|
|
</dl>
|
|
<h2>Client Providers Implemented by pvAccessCPP</h2>
|
|
|
|
<h3>ClientFactory</h3>
|
|
<p>This package provides implementation of the client side of a ChannelProvider that uses
|
|
the pvAccess network protocol to communicate between client and server.
|
|
The provider name is <b>pva</b>.
|
|
</p>
|
|
<pre>
|
|
class ClientFactory {
|
|
static void start();
|
|
static void stop();
|
|
};
|
|
</pre>
|
|
<p>where</p>
|
|
<dl>
|
|
<dt>start</dt>
|
|
<dd>Start the client side of remote pvAccess.</dd>
|
|
<dt>stop</dt>
|
|
<dd>Stop the client side of remote pvAccess.</dd>
|
|
</dl>
|
|
<h3>CAClientFactory</h3>
|
|
<p>This provides an implementation of ChannelProvider that uses the Channel Access
|
|
network protocol.
|
|
It converts between DBR data and pvData.
|
|
The provider name is <b>ca</b>.
|
|
</p>
|
|
<pre>
|
|
class CAClientFactory
|
|
{
|
|
static void start();
|
|
static void stop();
|
|
};
|
|
</pre>
|
|
<p>where</p>
|
|
<dl>
|
|
<dt>start</dt>
|
|
<dd>Start the client side of remote pvAccess.</dd>
|
|
<dt>stop</dt>
|
|
<dd>Stop the client side of remote pvAccess.</dd>
|
|
</dl>
|
|
<h2>Server Context</h2>
|
|
<p>This implements the server side of the <b>pva</b> network protocal and also provides a context for running remote providers.</p>
|
|
<pre>
|
|
class ServerContext
|
|
{
|
|
public:
|
|
virtual ~ServerContext() {};
|
|
virtual const ServerGUID& getGUID() = 0;
|
|
virtual const Version& getVersion() = 0;
|
|
virtual void initialize(ChannelProviderRegistryPtr const & channelProviderRegistry) = 0;
|
|
virtual void run(int32 seconds) = 0;
|
|
virtual void shutdown() = 0;
|
|
virtual void destroy() = 0;
|
|
virtual void printInfo() = 0;
|
|
virtual void printInfo(std::ostream& str) = 0;
|
|
virtual void dispose() = 0;
|
|
virtual epicsTimeStamp& getStartTime() = 0;
|
|
virtual void setBeaconServerStatusProvider(BeaconServerStatusProviderPtr const & beaconServerStatusProvider) = 0;
|
|
|
|
};
|
|
|
|
ServerContextPtr startPVAServer(
|
|
std::string const & providerNames = PVACCESS_ALL_PROVIDERS,
|
|
int timeToRun = 0,
|
|
bool runInSeparateThread = false,
|
|
bool printInfo = false);
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>getGUID</dt>
|
|
<dd>Returns ServerGUID (12-byte array).</dd>
|
|
<dt>getVersion</dt>
|
|
<dd>Get context implementation version.</dd>
|
|
<dt>initialize</dt>
|
|
<dd> Set <code>ChannelProviderRegistry</code> implementation and initialize server.</dd>
|
|
<dt>run</dt>
|
|
<dd>Run server (process events).<br />
|
|
seconds time in seconds the server will process events (method will block),
|
|
if <code>0</code>the method would block until <code>destroy()</code> is called.
|
|
</dd>
|
|
<dt>shutdown</dt>
|
|
<dd>Shutdown (stop executing run() method) of this context.
|
|
* After shutdown Context cannot be rerun again, destroy() has to be called to clear all used resources.
|
|
</dd>
|
|
<dt>destroy</dt>
|
|
<dd>
|
|
Clear all resources attached to this context.
|
|
</dd>
|
|
<dt>printInfo</dt>
|
|
<dd>Prints detailed information about the context to the standard output stream.</dd>
|
|
<dt>dispose</dt>
|
|
<dd>
|
|
Dispose (destroy) server context.
|
|
This calls <code>destroy()</code> and silently handles all exceptions.
|
|
</dd>
|
|
<dt>getStartTime</dt>
|
|
<dd>Get the time when the context was started.</dd>
|
|
<dt>setBeaconServerStatusProvider</dt>
|
|
<dd>Set beacon server status provider.</dd>
|
|
<dt>startPVAServer</dt>
|
|
<dd>
|
|
Called by remote providers to start the remote side of the <b>pva</b> network protocol. This includes providing context.
|
|
</dd>
|
|
</dl>
|
|
<h2>RPC</h2>
|
|
<h3>rpcClient</h3>
|
|
<p>RPCClient is an interface class that is used by a service client.</p>
|
|
<pre>
|
|
class RPCClient
|
|
{
|
|
virtual ~RPCClient() {}
|
|
static shared_pointer create(const string & serviceName);
|
|
static PVStructurePtr sendRequest(const string & serviceName,
|
|
PVStructurePtr const & request, double timeOut = RPCCLIENT_DEFAULT_TIMEOUT);
|
|
void issueConnect();
|
|
bool waitConnect(double timeout = RPCCLIENT_DEFAULT_TIMEOUT);
|
|
PVStructurePtr request(
|
|
PVStructurePtr const & pvArgument,
|
|
double timeout = RPCCLIENT_DEFAULT_TIMEOUT,
|
|
bool lastRequest = false);
|
|
void issueRequest(
|
|
PVStructurePtr const & pvArgument,
|
|
bool lastRequest = false);
|
|
PVStructurePtr waitResponse(double timeout = RPCCLIENT_DEFAULT_TIMEOUT);
|
|
};
|
|
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>sendRequest</dt>
|
|
<dd>
|
|
Performs complete blocking RPC call, opening a channel and connecting to the
|
|
service and sending the request.
|
|
</dd>
|
|
<dt>create</dt>
|
|
<dd>
|
|
Given a serviceName create a RCPClient.
|
|
</dd>
|
|
<dt>issueConnect</dt>
|
|
<dd>
|
|
Issue a connect request and return immediately.
|
|
</dd>
|
|
<dt>waitConnect</dt>
|
|
<dd>
|
|
Wait for the connect request to complete
|
|
</dd>
|
|
<dt>request</dt>
|
|
<dd>
|
|
Sends a request and wait for the response or until timeout occurs.
|
|
</dd>
|
|
<dt>issueRequest</dt>
|
|
<dd>
|
|
Issue a channelRPC request and return immediately.
|
|
</dd>
|
|
<dt>waitResponse</dt>
|
|
<dd>
|
|
Wait for the request to complete.
|
|
</dd>
|
|
</dl>
|
|
<h3>rpcServer</h3>
|
|
<p>Provides the context for the server side of channelRPC.</p>
|
|
<pre>
|
|
class RPCServer :
|
|
{
|
|
RPCServer();
|
|
virtual ~RPCServer();
|
|
void registerService(string const & serviceName, RPCService::shared_pointer const & service);
|
|
void registerService(string const & serviceName, RPCServiceAsync::shared_pointer const & service);
|
|
void unregisterService(string const & serviceName);
|
|
void run(int seconds = 0);
|
|
void runInNewThread(int seconds = 0);
|
|
void destroy();
|
|
void printInfo();
|
|
};
|
|
|
|
// private helper method, will (can) be removed in the future
|
|
ChannelPtr createRPCChannel(ChannelProviderPtr const & provider,
|
|
string const & channelName,
|
|
ChannelRequesterPtr const & channelRequester,
|
|
ServicePtr const & rpcService);
|
|
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>registerService</dt>
|
|
<dd>
|
|
Register a new service. The server can either be synchronous ot asynchonous.
|
|
</dd>
|
|
<dt>unregisterService</dt>
|
|
<dd>
|
|
Unregister the service.
|
|
</dd>
|
|
<dt>run</dt>
|
|
<dd>
|
|
Calls server context run.
|
|
</dd>
|
|
<dt>runInNewThread</dt>
|
|
<dd>
|
|
Starts a new thread.
|
|
</dd>
|
|
<dt>destroy</dt>
|
|
<dd>
|
|
Calls server context destroy.
|
|
</dd>
|
|
<dt>printInfo</dt>
|
|
<dd>
|
|
Shows the channel and connection status.
|
|
</dd>
|
|
</dl>
|
|
<h3>rpcService</h3>
|
|
<p>Base class for channelRPC services. To implement a rpcService you need to implement RPCService or RPCServiceAsync interface.</p>
|
|
<pre>
|
|
class RPCRequestException
|
|
{
|
|
RPCRequestException(Status::StatusType status, string const & message);
|
|
Status::StatusType getStatus() const;
|
|
};
|
|
|
|
|
|
class RPCService
|
|
{
|
|
virtual ~RPCService() {};
|
|
virtual PVStructurePtr request(
|
|
PVStructurePtr const & args
|
|
) = 0;
|
|
};
|
|
|
|
|
|
|
|
class RPCResponseCallback
|
|
{
|
|
virtual ~RPCResponseCallback() {};
|
|
virtual void requestDone(
|
|
Status const & status,
|
|
PVStructurePtr const & result
|
|
) = 0;
|
|
};
|
|
|
|
class epicsShareClass RPCServiceAsync :
|
|
public virtual Service
|
|
{
|
|
virtual ~RPCServiceAsync() {};
|
|
virtual void request(
|
|
PVStructurePtr const & args,
|
|
RPCResponseCallbackPtr const & callback
|
|
) = 0;
|
|
};
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>RPCRequestException</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt>getStatus</dt>
|
|
<dd>
|
|
Get the status type.
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>RPCService</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt>request</dt>
|
|
<dd>
|
|
The client has issued a request.
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>RPCResponseCallback</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt>requestDone</dt>
|
|
<dd>
|
|
This is called by service when a request is done.
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>RPCServiceAsync</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt>request</dt>
|
|
<dd>
|
|
The client has issued a request. A service must call callback->requestDone() method to notify completion.
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2>pipeLineServer</h2>
|
|
<p>A pipeline server supports reliable monitor support.
|
|
This is implemented by allowing the client to make the server delay when the client can not keep up with the server.
|
|
</p>
|
|
<p>The server implememts Channel::createMonitor but none of the other create methods.
|
|
When the client creates a monitor the following request options can be specified:</p>
|
|
<pre>
|
|
"record[pipeline=true,queueSize=size,ackAny=n]"
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>pipeline</dt>
|
|
<dd>This option must be set true.</dd>
|
|
<dt>queueSize</dt>
|
|
<dd>This option is optional.</dd>
|
|
<dt>ackAny</dt>
|
|
<dd>This option is optional. If not specified the value is queueSize/2.</dd>
|
|
</dl>
|
|
<p>Each time the client calls <b>Monitor::release</b> the client sends an <b>ack</b> message to the server every <b>ackAny</b> events.
|
|
The server uses this to delay sending new monitors if the monitor queue is full.</p>
|
|
<p><b>pvAccessCPP/testApp/remote/pipelineServiceExample.cpp</b> Is an example.
|
|
It has an additional record option <b>record[limit=n]</b> which makes the server call unlisten aften <b>n</b> events.
|
|
</p>
|
|
<h3>pipelineServer</h3>
|
|
<p>This is a class used by a pipeline service.
|
|
It implements channelProvider for the service and provides a context for running the service.
|
|
</p>
|
|
<pre>
|
|
class PipelineServer
|
|
{
|
|
void registerService(string const & serviceName, PipelineServicePtr const & service);
|
|
void unregisterService(string const & serviceName);
|
|
void run(int seconds = 0);
|
|
/// Method requires usage of std::tr1::shared_ptr&lt;PipelineServer&gt;. This instance must be
|
|
/// owned by a shared_ptr instance.
|
|
void runInNewThread(int seconds = 0);
|
|
void destroy();
|
|
void printInfo();
|
|
};
|
|
|
|
// private helper method, will (can) be removed in the future
|
|
ChannelPtr createPipelineChannel(ChannelProviderPtr const & provider,
|
|
string const & channelName,
|
|
ChannelRequesterPtr const & channelRequester,
|
|
PipelineServicePtr const & pipelineService);
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>registerService</dt>
|
|
<dd>
|
|
Register a new service.
|
|
</dd>
|
|
<dt>unregisterService</dt>
|
|
<dd>
|
|
Unregister the service.
|
|
</dd>
|
|
<dt>run</dt>
|
|
<dd>
|
|
Calls server context run.
|
|
</dd>
|
|
<dt>runInNewThread</dt>
|
|
<dd>
|
|
Starts a new thread.
|
|
</dd>
|
|
<dt>destroy</dt>
|
|
<dd>
|
|
Calls server context destroy.
|
|
</dd>
|
|
<dt>printInfo</dt>
|
|
<dd>
|
|
Shows the channel and connection status.
|
|
</dd>
|
|
</dl>
|
|
<h3>pipelineService</h3>
|
|
<h4>PipelineControl</h4>
|
|
<p>An instance of <b>PipelineControl</b> is created by PipelineServer and passed to PipelineService::request.</p>
|
|
<pre>
|
|
class PipelineControl
|
|
{
|
|
virtual size_t getFreeElementCount() = 0;
|
|
virtual size_t getRequestedCount() = 0;
|
|
virtual epics::pvData::MonitorElement::shared_pointer getFreeElement() = 0;
|
|
virtual void putElement(epics::pvData::MonitorElement::shared_pointer const & element) = 0;
|
|
virtual void done() = 0;
|
|
};
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>getFreeElementCount</dt>
|
|
<dd>
|
|
The number of free elements in the local queue.<br />
|
|
A service can (should) full up the entire queue.
|
|
</dd>
|
|
<dt>getRequestedCount</dt>
|
|
<dd>
|
|
The total count of requested elements.<br />
|
|
This is the minimum element count that a service should provide.
|
|
</dd>
|
|
<dt>getFreeElement</dt>
|
|
<dd>
|
|
Grab next free element.<br />
|
|
A service should take this element, populate it with the data
|
|
and return it back by calling putElement().
|
|
</dd>
|
|
<dt>putElement</dt>
|
|
<dd>
|
|
Put element on the local queue (an element to be sent to a client).
|
|
</dd>
|
|
<dt>done</dt>
|
|
<dd>
|
|
Call to notify that there is no more data to pipelined.<br />
|
|
This call destroys the pipeline session, i. e. the current monitor.
|
|
The client will have to create a new monitor in order to access the service again.
|
|
</dd>
|
|
</dl>
|
|
<h4>PipelineSession</h4>
|
|
<p>An instance of <b>PipelineSession</b> is created <b>PipelineService</b> for each instance of the service.</p>
|
|
<pre>
|
|
class PipelineSession
|
|
{
|
|
virtual size_t getMinQueueSize() const = 0;
|
|
virtual epics::pvData::Structure::const_shared_pointer getStructure() const = 0;
|
|
virtual void request(PipelineControl::shared_pointer const & control, size_t elementCount) = 0;
|
|
virtual void cancel() = 0;
|
|
};
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>getMinQueueSize</dt>
|
|
<dd>
|
|
Returns (minimum) local queue size.<br />
|
|
The actual local queue size = max( getMinQueueSize(), client queue size );
|
|
</dd>
|
|
<dt>getStructure</dt>
|
|
<dd>
|
|
Description of the structure used by this session.
|
|
</dd>
|
|
<dt>request</dt>
|
|
<dd>
|
|
Request for additional (!) elementCount elements<br />
|
|
The service should eventually call PipelineControl.getFreeElement() and PipelineControl.putElement()
|
|
to provide [PipelineControl.getRequestedCount(), PipelineControl.getFreeElementCount()] elements.
|
|
</dd>
|
|
<dt>cancel</dt>
|
|
<dd>
|
|
Cancel the session (called by the client).
|
|
</dd>
|
|
</dl>
|
|
<h4>PipelineService</h4>
|
|
<p>This is called to create an instance of a service.
|
|
Note that it returns an instance of <b>PipelineSession</b>, which must be implemented by the service.
|
|
</p>
|
|
<pre>
|
|
class PipelineService
|
|
{
|
|
virtual PipelineSessionPtr createPipeline(PVStructurePtr const & pvRequest) = 0;
|
|
};
|
|
</pre>
|
|
where
|
|
<dl>
|
|
<dt>createPipeline</dt>
|
|
<dd>Called to create a new instance of the service.<br />
|
|
</dd>
|
|
</dl>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|