PdCom  4.2
Process data communication client
Classes | Public Types | Public Member Functions | List of all members
PdCom::Process Class Referenceabstract

Base class for PdCom protocol handler. More...

#include <Process.h>

Classes

struct  Message
 Message structure. More...
 

Public Types

enum  LogLevel_t {
  Reset, Emergency, Alert, Critical,
  Error, Warn, Info, Debug,
  Trace
}
 Log levels used in Message and protocolLog() More...
 

Public Member Functions

 Process ()
 Constructor.
 
virtual ~Process ()
 Destructor. More...
 
std::string name () const
 Remote process name string.
 
std::string version () const
 Remote process version string.
 
void reset ()
 Reset communications and clean up internal buffers.
 
virtual std::string applicationName () const
 Name of application user application. More...
 
virtual std::string hostname () const
 Host name of remote server. More...
 
virtual int read (char *buf, size_t count)=0
 Read data from server. More...
 
virtual void write (const char *buf, size_t count)=0
 Write data to server. More...
 
virtual void flush ()=0
 Flush unsent data in output buffer. More...
 
int asyncData ()
 Library entry point for new data. More...
 
virtual void connected ()=0
 Protocol initialization completed. More...
 
bool list (const std::string &path) const
 List a directory path. More...
 
virtual void listReply (std::list< const Variable *> &variables, std::list< std::string > &directories)
 Reply to list() call. More...
 
bool find (const std::string &path) const
 Find a variable with a corresponding path. More...
 
virtual void findReply (const Variable *variable)
 Reply to find() More...
 
bool login (const char *mech, const char *clientData) const
 Perform SASL login step. More...
 
void logout () const
 Logout from server.
 
virtual void loginReply (const char *mechlist, const char *serverData, int finished)
 SASL server reply to login() More...
 
bool startTLS () const
 Start TLS. More...
 
virtual void startTLSReply ()
 TLS reply. More...
 
void ping () const
 Ping server.
 
virtual void pingReply ()
 Ping reply. More...
 
virtual bool alive ()
 Test from process whether client is alive. More...
 
void subscribe (Subscriber *subscriber, const std::string &path, double interval, int id) const
 Subscribe to a variable. More...
 
void unsubscribe (Subscriber *subscriber) const
 Unsubscribe all subscriptions from subscriber.
 
void parameterMonitor (Subscriber *subscriber, bool state) const
 Turn parameter monitoring on/off. More...
 
virtual void processMessage (const Message &message)
 Message event from process. More...
 
void getMessage (uint32_t seqNo) const
 Request specific message from history. More...
 
virtual void getMessageReply (const Message &message)
 Reply to getMessage() More...
 
void activeMessages () const
 Request a list of all active messages. More...
 
virtual void activeMessagesReply (const std::list< Message > &messageList)
 Reply to activeMessages() More...
 
virtual void protocolLog (LogLevel_t severity, const std::string &message)
 Message event from protocol handler. More...
 
virtual void broadcastReply (const std::string &message, const std::string &attr)
 Server broadcast. More...
 
void broadcast (const std::string &message, const std::string &attr="text")
 Send broadcast to all clients. More...
 
virtual void transmitSemaphore (bool state)
 Client to server communication semaphore. More...
 

Detailed Description

Base class for PdCom protocol handler.

This is the base class to interact with real time process server. The PdCom protocol ist implemented using this class.

For socket input and output, the library completely relies on a derived class where read(), write(), flush() and connected() methods are reimplemented.

When data is available for reading, call asyncData() which in turn calls the reimplemented read() method.

When the protocol is initialized, the reimplemented connected() method is called. Other than startTLS(), login(), none of the command methods listed below may be called prior to connected().

After connected(), the following commands can be issued: * list(): list a directory; returns result in listReply() * find(): find a variable; returns result in findReply() * login(): start a SASL login interaction; returns result in loginReply() * ping(): ping the server; returns result in pingReply() * getMessage(): request a specific message result in multiple calls to processMessage() if required * Variable interactions * Variable::Subscription interactions

startTLS() and login() may only be called prior to connected() when the library has called startTLSReply() or loginReply() previously.

All these commands are non-blocking asynchronous calls and either return the result immediately with the corresponding reply methods or issue a command to the server using excessive (!) calls to write(). Data should be written to a buffer to optimize network communication. To flush the buffer to wire, flush() is issued by the library when required.

The server may query presence of the user by issuing an alive() call. Using this call, certain actions could be undertaken by the server if the user is not active any more.

Certain actions in the real time process, such as alarms, triggers a call to processMessage(). Messages are kept in a ring buffer in the process.

Calling activeMessages() will return a list of all active messages as well as the latest message in activeMessagesReply().

Any message can be recalled with getMessage(), the result returned in getMessageReply(). If the message does not exist, the Message returned will have the requested seqNo with path empty.

The subscribe() method subscribes a variable using the path only.

Examples:
example.cpp.

Member Enumeration Documentation

◆ LogLevel_t

Log levels used in Message and protocolLog()

Enumerator
Reset 

Message is reset.

Emergency 

Emergency log level.

Alert 

Alert log level.

Critical 

Critical log level.

Error 

Error log level.

Warn 

Warn log level.

Info 

Info log level.

Debug 

Debug log level.

Trace 

Trace log level.

Constructor & Destructor Documentation

◆ ~Process()

virtual PdCom::Process::~Process ( )
virtual

Destructor.

The destructor cleans up all internally allocated structures

Member Function Documentation

◆ activeMessages()

void PdCom::Process::activeMessages ( ) const

Request a list of all active messages.

This will return a list of active process messages as well as the last message in activeMessagesReply() if its state is Reset.

◆ activeMessagesReply()

virtual void PdCom::Process::activeMessagesReply ( const std::list< Message > &  messageList)
virtual

Reply to activeMessages()

Reimplement this method to receive the message list.

The process messages received in processMessage() has strictly increasing sequence numbers and time.

Parameters
messageList

◆ alive()

virtual bool PdCom::Process::alive ( )
virtual

Test from process whether client is alive.

In some cases the server may want to know whether the client is still alive. Default implementation is to return true. Reimplement this if you wish to control presence

Returns
true to indicate user presence

◆ applicationName()

virtual std::string PdCom::Process::applicationName ( ) const
virtual

Name of application user application.

The application name is transferred to the server to be able to identify the clients more easily.

Returns
a descriptive name of your application.

◆ asyncData()

int PdCom::Process::asyncData ( )

Library entry point for new data.

Calling this method tells the library that new data has arrived from the server and is waiting to be processed.

The library prepares an input buffer and then calls the reimplemented read() virtual method to read incoming data.

The return value of read() is returned by this method, enabling the user to be able to react to read errors, count bytes or even socket close, etc.

Returns
return value of read() method
Examples:
example.cpp.

◆ broadcast()

void PdCom::Process::broadcast ( const std::string &  message,
const std::string &  attr = "text" 
)

Send broadcast to all clients.

Parameters
messageMessage to send
attrMessage attribute

◆ broadcastReply()

virtual void PdCom::Process::broadcastReply ( const std::string &  message,
const std::string &  attr 
)
virtual

Server broadcast.

Reimplement this method to receive server broadcasts

Parameters
messageMessage
attrAttribute

◆ connected()

virtual void PdCom::Process::connected ( )
pure virtual

Protocol initialization completed.

This is a signal emitted by the library to indicate that protocol initialization has been completed and that library operations can be performed thereafter.

Reimplement this method to get the signal.

Absolutely NO process operations other than asyncData(), startTLS() and login() (and then only due to a previous loginReply() are permitted before this signal has been emitted.

Examples:
example.cpp.

◆ find()

bool PdCom::Process::find ( const std::string &  path) const

Find a variable with a corresponding path.

If the path search is known (be it successful or unsuccessful), the variable is returned in the call to the reimplemented virtual findReply() method immediately and the method returns true;

If unsuccessful, the command is sent to the server to and the call returns immediately with false. Later on during asyncData(), findReply() is called when the server's reply is processed.

Parameters
pathpath of variable to find
Returns
true if path is found immediately (cached)

◆ findReply()

virtual void PdCom::Process::findReply ( const Variable variable)
virtual

Reply to find()

This virtual method is called within the context of asyncData() when the server's reply to a variable discovery is processed.

findReply()ies are called in strict order of find()

Parameters
variablepointer to Variable; NULL if not found
Examples:
example.cpp.

◆ flush()

virtual void PdCom::Process::flush ( )
pure virtual

Flush unsent data in output buffer.

Reimplement this method to flush data in the output buffer.

This method tells the user that it is time to flush the output buffer to the wire. The library only expects that data is sent to the server within this call.

Essentially this method is a little wrapper around your socket's fflush() function:

void MyProcess::flush()
{
if (::fflush(this->socket_file)) {
// react to errors
}
}
Examples:
example.cpp.

◆ getMessage()

void PdCom::Process::getMessage ( uint32_t  seqNo) const

Request specific message from history.

The message is received in getMessageReply().

If the seqNo is not available, getMessageReply() is called with null path and requested seqNo.

Parameters
seqNosequence number of message

◆ getMessageReply()

virtual void PdCom::Process::getMessageReply ( const Message message)
virtual

Reply to getMessage()

Reimplement this method to receive responses to getMessage().

Parameters
message

◆ hostname()

virtual std::string PdCom::Process::hostname ( ) const
virtual

Host name of remote server.

Reimplement this method to return the remote server host name this library connects to. This is especially important in multi-hosted TLS environments, where multiple hosts resolv to the same IP address. TLS needs to know the original server host name.

Returns
server host name

◆ list()

bool PdCom::Process::list ( const std::string &  path) const

List a directory path.

A process command to return all variables and directories within a directory path. The path parameter has typical unix character, with forward slashes '/' separating directories.

listReply() must be reimplemented to receive the reply to this call.

If the directory is cached (for instance a previous call to a similar path, or an entire server listing has been performed), listReply() is called within the context of this call and no server query is performed.

If uncached, the library sends a server query and returns immediately. Later on during asyncData(), the virtual method listReply(), is called when the server's reply is processed.

As a special case, an empty string (std::string()) for path will let the server list all its variables in one go. This possibility must be used with caution, as it can cause heavy network traffic.

Parameters
pathdirectory path
Returns
true if the path was cached

◆ listReply()

virtual void PdCom::Process::listReply ( std::list< const Variable *> &  variables,
std::list< std::string > &  directories 
)
virtual

Reply to list() call.

You must reimplement this method to receive replies to list() calls.

Note that a variable can have the same path as a directory! An example is a vector variable with atomized elements.

Replies are in strict order of list() calls.

Parameters
variableslist of variables
directoriesstring list of directories
Examples:
example.cpp.

◆ login()

bool PdCom::Process::login ( const char *  mech,
const char *  clientData 
) const

Perform SASL login step.

Parameters
mechSASL mechanism
clientDataBase64 encoded SASL output data to server

Setting both mech and clientData to NULL will initate the login process.

Every call to login() is answered by a loginReply(), unless login is not supported. When login is mandatory, loginReply() will be called automatically.

Returns
true if login is not supported
Examples:
example.cpp.

◆ loginReply()

virtual void PdCom::Process::loginReply ( const char *  mechlist,
const char *  serverData,
int  finished 
)
virtual

SASL server reply to login()

loginReply() may be called without calling login() in the case where login is mandatory. In this case, it is called before connected().

Parameters
mechlistSpace separated list of supported mechanisms
serverDataBase64 encoded SASL data from server
finished> 0: Login successful
0: Login process not finished; another login() step is required
< 0: Login failed
Examples:
example.cpp.

◆ parameterMonitor()

void PdCom::Process::parameterMonitor ( Subscriber subscriber,
bool  state 
) const

Turn parameter monitoring on/off.

Turning parameter monitoring automatically subscribes changed parameters.

The value is delivered just as with ordinary subscriptions in newValue(const Variable::Subscription* subscription), with the exception that there was no preceding subscribe() and there is no active() call.

There is no automatic unsubscribing. To save memory, it is safe to cancel() the automatic parameter subscription immediately within newValue().

◆ pingReply()

virtual void PdCom::Process::pingReply ( )
virtual

Ping reply.

You must reimplement this method to receive the reply to a ping() call.

◆ processMessage()

virtual void PdCom::Process::processMessage ( const Message message)
virtual

Message event from process.

This method is called whenever a message event is generated by the process.

Reimplement this method to receive them.

Parameters
message

◆ protocolLog()

virtual void PdCom::Process::protocolLog ( LogLevel_t  severity,
const std::string &  message 
)
virtual

Message event from protocol handler.

Reimplement this method to receive logs from the protocol handler.

All messages <= Error are fatal and the process must be aborted and reset()

Parameters
severity
messageplain text

◆ read()

virtual int PdCom::Process::read ( char *  buf,
size_t  count 
)
pure virtual

Read data from server.

Reimplement this method to transfer data from the server to the library. This method is called within the call to asyncData().

Essentially this method is a little wrapper around your socket's read() function:

int MyProcess::read(char *buf, size_t count)
{
return ::read(this->socket_fd, buf, count);
}

The method must return the number of bytes read, which may of coarse be less than count or even 0. Return values of <= 0 are not interpreted by the protocol handler.

Parameters
bufdata destination
countbuffer size
Returns
return value of read() function, which in turn will be returned by asyncData()
Examples:
example.cpp.

◆ startTLS()

bool PdCom::Process::startTLS ( ) const

Start TLS.

The initial server communication is in plain text. Encryption on the server side is initiated upon reception of a startTLS() command. The client may continue sending commands to the server, although these are still in plain text. Server replies to these commands are delayed in the server till after successful encryption. The server acknowledges reception of the startTLS() command using startTLSReply() whereafter the client must switch to TLS.

Server replies to commands sent by the client between startTLS() and startTLSReply() are stored in a limited buffer. The connection will be closed by the server if it overflows. Thus it is not recommended to send commands during this period, at least not ones where the replies are expected to be quite long!

Reimplement startTLSReply() to be able to use TLS.

Returns
true on error (server does not support TLS)

◆ startTLSReply()

virtual void PdCom::Process::startTLSReply ( )
virtual

TLS reply.

Reimplement this command in the client. Upon reception, TLS must be activated.

See also
startTLS()

◆ subscribe()

void PdCom::Process::subscribe ( Subscriber subscriber,
const std::string &  path,
double  interval,
int  id 
) const

Subscribe to a variable.

The subscription rate is specified using interval. Depending on the type of variable, signal or parameter, the interval has different meanings.

For parameters, the interval is ignored completely. Subscribed parameters are only updated when the value changes. It is available in Subscriber::newValue().

For signals, the interval specifies:

  • < 0: The subscription needs to be poll()ed every time it is required. Typically a timer is used to call poll() on a regular basis. The absolute value of interval is ignored. The subscription value is available in Subscriber::newValue().
  • 0: Server sends the subscription automatically when the value changes. Be careful: quantization variances on an analog signal for example may cause the value to be blasted at a continuous rate with every calculation cycle! The subscription value is available in Subscriber::newValue().
  • > 0: Server sends the subscription continuously at the specified rate. The subscription value is available in Subscriber::newGroupValue().

Usually you would use interval <= 0. It reduces the required bandwidth. Fixed subscription interval > 0 is actually only required for logging purposes, such as an oscilloscope or data recorder.

Parameters
subscriberpointer to subscriber object that will receive the subscription
pathvariable path to subscribe
intervalsee description
idarbitrary user specified subscription id. The id is copied verbatim to the Variable::Subscription::id or during Subscriber::invalid()

◆ transmitSemaphore()

virtual void PdCom::Process::transmitSemaphore ( bool  state)
virtual

Client to server communication semaphore.

Reimplement this method to intercept the transmission semaphore. The default implementation always returns success.

Every interaction from client to server (change a parameter, ping, etc) starts a message tag. If the client is multi-threaded, more than one message tag could be started which would lead to corruption. This semaphore can be used to serialize all client to server interactions.

Parameters
statetrue = lock; false = release

◆ write()

virtual void PdCom::Process::write ( const char *  buf,
size_t  count 
)
pure virtual

Write data to server.

Reimplement this method to transfer data from the library to the server. This method is called when any library operation requires data to be sent to the server.

Note: the library makes many calls to write(), so use buffered output otherwise you're in for performance problems!

Essentially this method is a little wrapper around your socket's write() function:

void MyProcess::write(const char *buf, size_t count)
{
if (count != ::fwrite(buf, 1, count, this->socket_file)) {
// react to errors, set flags, etc
}
}

Note: the library does not have an internal buffer and expects that all data is sent. If your implementation might send less than count, it is your responsibility to buffer the data and send it later.

Parameters
bufdata to be sent
countnumber of bytes to send
Examples:
example.cpp.

The documentation for this class was generated from the following file: