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

Base class for PdCom protocol handler. More...

#include <Process.h>

Public Types

enum  LogLevel_t {
  Emergency, Alert, Critical, Error,
  Warn, Info, Debug, Trace
}
 Log levels. 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 (LogLevel_t level, const std::string &path, int index, bool state, uint64_t time_ns, const std::string &text)
 Message event from process. More...
 
void messageHistory (unsigned int limit) const
 Request history of messages from the process. More...
 
virtual void messageHistoryEnd (unsigned int count)
 End of message history block. 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:

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().

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

Examples:
example.cpp.

Member Enumeration Documentation

◆ LogLevel_t

Log levels.

See also
processMessage()
protocolLog()

Constructor & Destructor Documentation

◆ ~Process()

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

Destructor.

The destructor cleans up all internally allocated structures

Member Function Documentation

◆ 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.

◆ 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.

◆ messageHistory()

void PdCom::Process::messageHistory ( unsigned int  limit) const

Request history of messages from the process.

The process stores a configurable history of messages. This method will request the list. Typically it is used once during initial connection.

The messages will arrive in reverse order (back in history), through processMessage().

The number of messages should be limited not to load the network unnecessariy. Typically limit to less than 10 messages.

End of transmission is provided by messageHistoryEnd(). This can be used to trigger another call to messageHistory() to receive another block of messages.

Parameters
limitthe reply length

◆ messageHistoryEnd()

virtual void PdCom::Process::messageHistoryEnd ( unsigned int  count)
virtual

End of message history block.

There may be more messages in the queue, use messageHistory() repeatedly as required or until count is zero.

Parameters
countNumber of messages transferred

◆ 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 ( LogLevel_t  level,
const std::string &  path,
int  index,
bool  state,
uint64_t  time_ns,
const std::string &  text 
)
virtual

Message event from process.

This method is called whenever a message event is generated by the process or in response to a messageHistory() call.

Note that for messages due to messageHistory(), the messages come in reverse order, i.e. back in time.

Reimplement this method to receive them.

A universal implementation shall make any assumption about time_ns or state.

Parameters
levelseverity
pathevent's path
textText of message
indexevent's index in case of a vector; -1 for scalar
statetrue: event raised; false event reset
time_nstime in nanoseconds since epoch

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