pvAccess C++ Overview

Table of Contents


Preface

This document describes the pvAccess Application Program Interface (API). The reader is assumed to have a basic understanding of EPICS V4 as described in:
EPICS V4 Developer's Guide

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:
pvaClientCPP

If your primary interest is implementing pvAccess services then, before reading this documement read:
pvDatabaseCPP

Introduction

This section 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. Ptr is shorthand for ::shared_pointer For example:

ChannelFindPtr
instead of
ChannelFind::shared_pointer

pvAccess provides network support for structured data as described by pvData.

The main concepts of pvAccess are:

ChannelProvider
A channelProvider creates channels, where a channel instance is a connection between a client and a server.
Channel
A channel has a number of create methods: createChannelGet, createChannelPut, etc. Each of ChannelGet, ChannelPut, etc provides methods to pass data between client and server.

An arbitrary number of channelProviders can be implemented on both the client and server side. A ChannelProviderRegistry allows clients to connect to servers and for Providers to register with the registry.

ChannelProviderRegistry Overview

Three global methods are available:

getChannelProviderRegistry
Get the single instance of ChannelProviderRegistry.
registerChannelProviderFactory
Register a ChannelProvider
unregisterChannelProviderFactory
Remove a ChannelProvider

ChannelProviderRegistry provides the method:

getProvider

ChannelProvider Overview

Provides the following methods:

createChannel
Create a channel.

Channel Overview

Channel provides methods to create the following:

ChannelProcess
Client can make requests to process the channel.
ChannelGet
Client can make requests to get data from a channel.
ChannelPut
Client can make requests to put data to a channel.
ChannelPutGet
Client can make requests to put data to a channel, process the channel, and get data from the channel.
Monitor
Monitor data changes in the channel.
ChannelArray
Get or put data to a sub-array.
ChannelRPC
Similar to ChannelPutGet but data types can change for each request.

ChannelProviders implemented by pvAccessCPP

Client Side

pva network protocal
This connects the client to a server via the pva network protocol, which is a protocol for passing pvData objects. The protocol is described in:
pvAccess Protocol Specification
ca network protocol
This connects the client to a server via the ca 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:
Channel Access Reference Manual
codec
Matej please explain

The client side of pva also allows an arbitrary number of additional providers to register with it.

Server Side

pva network protocal
The server side for pva network protocol. It connects the server side of the network to ChannelProviders.
RPC Server
This is the "glue" code for implementing a ChannelRPC service. An actual service must implement method request.
codec
Matej please explain

The server side of the pva network protocal. allows an arbitrary number of providers to register with it. Existing examples are:

local provider
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.
pvaSrv
This is a ChannelProvider for accessing V3 IOC DBRecords. It transforms the data in a V3 DBRecord to a top level PVStructure.

Command Line Utilities

pvAccessCPP provides the following command line utilities:
pvlist, pvinfo, pvget, pvput, and eget.

In order to use these commands a path to the pvAccessCPP bin directory must exists. For example, on my linux workstation .bash_profile includes the statements:

export EPICSV4=/home/epicsv4
export PATH=$PATH:${EPICSV4}/pvAccessCPP/bin/${EPICS_HOST_ARCH}

This document gives a VERY brief explaination if each command but each provides a -help option. For example:

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

A longer explanation of the commands is in:

EPICS V4 Developer's Guide

pvlist

Shows all servers avaliable via the pva network protocal and also a list of all channels for a particular server.

pvinfo

Shows the connection status and introspection interface for channels.

pvget

Returns data for a channel via channelGet or monitor.

pvput

Puts data to a channel via channelPut.

eget

pvget on steroids. Also has support for channelRPC and some of the normative types.

Include Files

The following are the include files that are of most interest to clients:

pvAccess.h
This document discusses most of the clases described in pvAccess.h. The following are not discussed in this document:
enum AccessRights {none,read,readWrite};
class Lockable...
class ScopedLock...
clientFactory.h
Static methods to start and stop the pva provider.
rpcClient.h
Code for implementing the client side of a channelRPC request.
caProvider.h
Needed to start the provider for the ca network protocol.

The following are of interest to service code:

serverContext.h
Needed to start pvAccess Server Context.
rpcServer.h
Code for implementing the server side of a channelRPC request.
rpcService.h
Matej please explain.

Matej are any others of interest to client or service code?

Starting PVAccess Clients

To start both the pva and ca client providers issue the commands:

ClientFactory::start();
CAClientFactory::start();

Starting pvAccess Server Context

To see examples of how to start a pvAccess server look at the examples provided in exampleDatabasePVA.zip. 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 exampleDatabaseMain.cpp that is in the example:

int main(int argc,char *argv[])
{

...
    ContextLocal::shared_pointer contextLocal = ContextLocal::create();
    contextLocal->start();

...
    contextLocal->waitForExit();
    return 0;
}

ChannelProvider

class ChannelProviderRegistry

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

The global methods are:

getChannelProviderRegistry
Called by both client and services to get the single instance of ChannelProviderRegistry.
registerChannelProviderFactory
Called by a service that implements ChannelProvider. Note that implementing a ChannelProvider is a big task, which is why pvDatabaseCPP exists.
unregisterChannelProviderFactory
Called by a service if it no longer wants the provider to be used.

The methods for ChannelProviderRegistry are:

getProvider
Called by both client and services to get the channelProvider.
The providerName must be the name of a registered provider.
Most clients will use either pva or ca.
Most services will use pvDatabaseCPP, which implements provider local. A service that is also a client can also use local or pvaSrv.
createProvider
Called by a service to start the provider.
getProviderNames
Gets the names of all registered providers.

class ChannelProvider

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);
    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;
};

The methods of ChannelProvider are:

getProviderName
Returns the name of the channel provider.
channelFind
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.
channelList
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.
createChannel
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.
configure
Not called by client, Matej please explain
flush
Not called by client, Matej please explain
poll
Not called by client, Matej please explain

The methods of ChannelFind are:

getChannelProvider
Returns the provider.
cancel
Cancel the current channelFind or channelList request.

The method of ChannelFindRequester are:

channelFindResult
If wasFound is true then status is OK. If not found then status provides reason for failure.

The method of ChannelListRequester are:

channelListResult
If there is a problem with the channelList request status provides the reason. channelNames provides the list of channels the provider is currently providing.
Matej please explain hasDynamic.

Channel

class ChannelRequester

This must be implemented by a client. It shows the result of a ChannelProvider::createChannel request and also the connection state of the channel.

class ChannelRequester : Requester
{
public:
    virtual void channelCreated(
        const Status& status, ChannelPtr const & channel) = 0;
    virtual void channelStateChange(
        ChannelPtr const & channel,
        Channel::ConnectionState connectionState) = 0;
};

The methods of ChannelRequester are:

channelCreated
This is called as a result of a ChannelProvider::createChannel request. It shows if the request was successful. If not successful then channel is null and status shows why the request failed.
channelStateChange
When the client successfuly connects to a channel this is called with ConnectionState=CONNECTED. After successfuly connecting the client can call the channel methods.
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.

class Channel

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;
};
where:
destroy
Destroy all resources belonging to the channel. This includes all channelPuts, channelGets, etc and any remote connections.
getProvider
Get the name of the provider.
getRemoteAddress
Get the remote address of the channel.
getConnectionState
Get the connection state.
getChannelName
Get the channel name.
getChannelRequester
Get the interface to the code that created the channel.
isConnected
Is the channel connected?
getField
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.
getAccessRights
Get the access rights for the caller. The access rights are one of none, read , or readWrite.
createChannelProcess
Create a ChannelProcess, which is described below.
createChannelGet
Create a ChannelGet, which is described below.
createChannelPut
Create a ChannelPut, which is described below.
createChannelPutGet
Create a ChannelPutGet, which is described below.
createChannelRPC
Create a ChannelRPC, which is described below.
createMonitor
Create a Monitor, which is described below.
createChannelArray
Create a ChannelArray, which is described below.
printInfo
Print information about the channel.

class GetFieldRequester

class GetFieldRequester : virtual public Requester {
public:
    virtual void getDone(
        const Status& status,
        FieldConstPtr const & field) = 0;
};
where:
getDone
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.

class ChannelRequest

This is a base class for ChannelGet, ChannelPut, etc.

class ChannelRequest
{
public:
    virtual ChannelPtr getChannel() = 0;
    virtual void cancel() = 0;
    virtual void lastRequest() = 0;
};
where:
getChannel
Get the Channel interface.
cancel
Cancel any outstanding request
lastRequest
The current request is the last request. Allows the implementation to release resources

ChannelGet

This is used to get data from a server.

class ChannelGet

class ChannelGet : public ChannelRequest {
public:
    virtual void get() = 0;
};
where
get
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.

class ChannelGetRequester

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;
};
where:
channelGetConnect
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.
getDone
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.

ChannelPut

This is used to put data to a server.

class ChannelPut

class ChannelPut : public ChannelRequest {
public:
    virtual void put(
            PVStructurePtr const & pvPutStructure,
            BitSetPtr const & putBitSet) = 0;
    virtual void get() = 0;

};
where:
put
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.
get
Get the current data from the server. The result is returned via a call to ChannelPutRequester::getDone.

class ChannelPutRequester

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;
};
where:
channelPutConnect
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.
putDone
Called when ChannelPut::put is acknowledged by the server. status shows the result.
getDone
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.

ChannelPutGet

This is used to:

put data to a server
process
get data from the server

class ChannelPutGet

class ChannelPutGet : public ChannelRequest {
public:
    virtual void putGet(
            PVStructurePtr const & pvPutStructure,
            BitSetPtr const & putBitSet) = 0;
    virtual void getPut() = 0;
    virtual void getGet() = 0;
};
where:
putGet
Put all changed fields of pvPutStructure to the server. putBitSet shows which fields are to be sent.
The server processes and returns data to the client.
When the putGet completes ChannelPutGetRequester::putDone is called with the result.
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.
getPut
Get the current put data from the server.
The result is returned via a call to ChannelPutGetRequester::getPutDone.
getGet
Get the current get data from the server.
The result is returned via a call to ChannelPutGetRequester::getGet.

class ChannelPutGetRequester

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;
};
where:
channelPutGetConnect
This is called as a result of calling Channel::createChannelPutGet.
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.
getStructure is the introspection interface that will be used for the data returned by every call to ChannelPutGet::getGet and ChannelPut::putGet.
If status shows a failure then the client should NOT use either channelPut or putStructure or getStructure.
putGetDone
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.
getPutDone
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.
getGetDone
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.
getPutDone
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.

ChannelArray

class ChannelArray

Get/Put a subset of an array. This works for all of scalarArray, unionArray, and structureArray.

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;
};
where:
putArray
The putArray is sent to the server, which changes to specified elements of the server array.
getArray
The server selects the specified set of elements in the server array and returns the result to the client,
getLength
Get the current length of the server array.
setLength
Set the length of the server array.

class ChannelArrayRequester

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;
};
where:
channelArrayConnect
This is called as a result of calling Channel::createChannelArray.
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.
putArrayDone
The result of calling ChannelArray::putArray. status shows the result.
getArrayDone
The result of calling ChannelArray::getArray. status shows the result.
If status is OK, pvArray has the result.
getLengthDone
The result of calling ChannelArray::getLength. status shows the result.
If status is OK length is the length of the server array.
setLengthDone
The result of calling ChannelArray::setLength. status shows the result.

Monitor

Described in pvDataCPP. See:
EPICS pvDataCPP

For convenience the classes are shown here.

class MonitorElement

class MonitorElement {
public:
    MonitorElement(){}
    MonitorElement(PVStructurePtr const & pvStructurePtr);
    PVStructurePtr pvStructurePtr;
    BitSetPtr changedBitSet;
    BitSetPtr overrunBitSet;
};

class Monitor

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;
};

class MonitorRequester

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;
};

ChannelRPC

class ChannelRPC

class ChannelRPC : public ChannelRequest {
public:
    virtual void request(PVStructurePtr const & pvArgument) = 0;
};
where:
request
Issue a request to the server.
pvArgument is sent to the server. The server processes the request and returns the result by calling ChannelRPCRequester::requestDone.

class ChannelRPCRequester

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;
};
where:
channelRPCConnect
Called as a result of Channel::createChannelRPC.
status shows the result.
requestDone
Called as a result of ChannelRPC::request.
status shows the result.
If status is OK pvResponse is the result.

RPC Server and Service

Matej please explain