AgentXcpp  Version:0.3
Internals Documentation
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Pages
agentxcpp::UnixDomainConnector Class Reference

Connect to a unix domain socket. More...

#include <UnixDomainConnector.hpp>

Inheritance diagram for agentxcpp::UnixDomainConnector:
Collaboration diagram for agentxcpp::UnixDomainConnector:

Signals

void pduArrived (QSharedPointer< PDU >)
 Emitted when a PDU arrived. More...
 

Public Member Functions

 UnixDomainConnector (const std::string &unix_domain_socket="/var/agentx/master", unsigned timeout=1000)
 Standard constructor. More...
 
virtual ~UnixDomainConnector ()
 Destructor. More...
 
bool connect ()
 Connect to the remote entity. More...
 
void disconnect ()
 Disconnect from the remote entity. More...
 
bool is_connected ()
 Find out whether the object is currently connected. More...
 
void send (QSharedPointer< PDU > pdu)
 Send a PDU. More...
 
QSharedPointer< ResponsePDUrequest (QSharedPointer< PDU > pdu)
 Send a PDU and wait for the response. More...
 

Private Slots

void do_receive ()
 Internal slot to receive data. More...
 
void do_send (QSharedPointer< PDU > pdu)
 Internal slot to send data. More...
 
void do_connect ()
 Connect to the remote entity. More...
 
void do_disconnect ()
 Disconnect from a remote entity. More...
 

Private Attributes

QLocalSocket m_socket
 The socket used internally for networking. More...
 
QString m_filename
 The filename of the unix domain socket. More...
 
unsigned m_timeout
 The timeout in milliseconds. More...
 
QMutex m_connection_mutex
 Needed for m_connection_waitcondition. More...
 
QWaitCondition m_connection_waitcondition
 A waitcondition to synchronize connect actions. More...
 
bool m_is_connected
 Whether the object is currently connected. More...
 
QMutex m_mutex_is_connected
 A mutex to protect m_is_connected. More...
 
std::map< quint32,
QSharedPointer< ResponsePDU > > 
m_responses
 Storage for ResponsePDU's. More...
 
QMutex m_response_mutex
 Used to protect m_responses and for m_response_arrived. More...
 
QWaitCondition m_response_arrived
 A waitcondition to inform waiters of ResponsePDU's. More...
 

Detailed Description

Connect to a unix domain socket.

This class connects to a unix domain socket and provides the following services:

  • Methods to connect and disconnect to the unix domain socket, and a method to obtain the current state,
  • A QT signal which is emitted when a PDU arrives (with an exception, see below),
  • A request service which sends a PDU and then blocks until the corresponding ResponsePDU arrived,
  • A send service which just sends a PDU.

An object of this class is intended to run in its own thread, like so:

QThread thread;
connection->moveToThread(&thread);
thread.start();

The UnixDomainConnector object communicates with its "outside world" via the QT signal/slot mechanism (which is thread-safe). In addition, the class offers methods which can directly be called from any thread and which are also thread-safe (and often use the signal/slot mechanism internally).

Connection handling

The UnixDomainConnector class uses QLocalSocket to communicate over a unix domain socket. It always starts in disconnected state, which means that the QLocalSocket is disconnected. The private slots do_connect() and do_disconnect() are invoked to connect resp. disconnect the socket. However, these slots should not be invoked from outside the object (therefore they are private slots). The methods connect() and disconnect() are offered to handle connection. These methods invoke do_connect() resp. do_disconnect().

The connect() method blocks until the connection is established or a timeout is detected. It does so by invoking do_connect(), then waiting for a QWaitCondition to be triggered. The disconnect() method works the same way.

The connection state is tracked with the m_is_connected member, which is protected by a mutex. The is_connected() method can access m_is_connected to inspect the state.

Sending and Receiving PDU's

AgentX is a protocol based on a request-response model. A subagent can send a request and wait for a response, while the master can also send requests and expect a response. Furthermore, a subagent or a master can send multiple requests, then wait for all the responses. All those PDU's can be interleaved.

The UnixDomainConnector class handles sending and receiving PDU's separately. Sending is done using the do_send() slot, which works for all types of PDU: all request-PDU's (such as OpenPDU) can be send without considering special cases, and ResponsePDU's also are no exception. Received PDU's are forwarded using the pduArrived() signal to whoever is listening, which works for PDU's except ResponsePDU's: these are the answer to a sent request-PDU and must be routed differently.

Received ResponsePDU's are transmitted via the m_responses map. This map assigns a packetID a ResponsePDU. Each time a request is sent, do_send() adds an entry to the map with the packetID of the request and a NULL ResponsePDU (i.e. a NULL pointer). This entry indicates that a ResponsePDU with the same packetID is awaited. The do_receive() slot then adds the ResponsePDU to the map, when it arrived. However, when a ResponsePDU arrives which is not awaited, it is discarded.

Todo:
Improve error handling in all functions.

Definition at line 114 of file UnixDomainConnector.hpp.

Constructor & Destructor Documentation

UnixDomainConnector::UnixDomainConnector ( const std::string &  unix_domain_socket = "/var/agentx/master",
unsigned  timeout = 1000 
)

Standard constructor.

This constructor initializes the connector object to be in disconnected state.

Parameters
unix_domain_socketThe path to the unix_domain_socket.
timeoutThe timeout, in milliseconds, used for for connecting, disconnecting, sending and receiving PDU's. See the documentation of the respective methods for details.

Definition at line 34 of file UnixDomainConnector.cpp.

References do_receive(), and m_socket.

UnixDomainConnector::~UnixDomainConnector ( )
virtual

Destructor.

Definition at line 148 of file UnixDomainConnector.cpp.

Member Function Documentation

bool UnixDomainConnector::connect ( )

Connect to the remote entity.

This function connects to the remote entity and starts receiving PDU's. If the object is already connected, the function does nothing.

For the attempt to connect, the configured timeout is used.

This function invokes the do_connect() slot and then wait until m_connection_waitcondition is triggered (or a timeout is detected).

Returns
True on success (i.e. if the object is in connected state), false otherwise.

Definition at line 94 of file UnixDomainConnector.cpp.

References is_connected(), m_connection_mutex, m_connection_waitcondition, and m_timeout.

Referenced by agentxcpp::MasterProxy::connect(), and agentxcpp::MasterProxy::reconnect().

void UnixDomainConnector::disconnect ( )

Disconnect from the remote entity.

Stops receiving PDU's and disconnects the remote entity.

For the attempt to disconnect, the configured timeout is used.

This function invokes the do_disconnect() slot and then waits until m_connection_waitcondition is triggered (or a timeout is detected).

The object will be in disconnected state after this method, no matter whether disconnecting times out or not.

Definition at line 129 of file UnixDomainConnector.cpp.

References m_connection_mutex, m_connection_waitcondition, and m_timeout.

Referenced by do_receive(), and agentxcpp::MasterProxy::reconnect().

void UnixDomainConnector::do_connect ( )
privateslot

Connect to the remote entity.

This function connects to the remote entity and waits until connection is established, or until the timeout expires.

If the UnixDomainConnector is already connected, this function does nothing. If the socket was disconnected, and the disconnect operation is still in progress, this function also does nothing.

If connecting times out, m_is_connected is set to false.

If connecting succeeds, m_is_connected is set to true.

After the work is done, m_connection_waitcondition.wakeAll() is invoked in any case.

Note
Don't invoke this slot from outside the object!

Definition at line 51 of file UnixDomainConnector.cpp.

References m_connection_waitcondition, m_filename, m_is_connected, m_mutex_is_connected, m_socket, and m_timeout.

void UnixDomainConnector::do_disconnect ( )
privateslot

Disconnect from a remote entity.

This function disconnects from the remote entity and waits until the operation finished, or until the timeout expires.

If disconnecting times out, m_socket may be left in state ClosingState.

m_is_connected is set to false in any case.

conjunction with m_c After the work is done, m_connection_waitcondition.wakeAll() is invoked in any case.

Note
Don't invoke this slot from outside the object!

Definition at line 109 of file UnixDomainConnector.cpp.

References m_connection_waitcondition, m_is_connected, m_mutex_is_connected, m_socket, and m_timeout.

void UnixDomainConnector::do_receive ( )
privateslot

Internal slot to receive data.

This slot is connected to QLocalSocket::readyRead() and thus called when data arrives on the socket.

The function reads as many complete PDU's from the socket, parses them and invokes the pduArrived() signal for each PDU, except for ResponsePDU's.

ResponsePDU's are stored to the m_responses map, if the map has an entry for the packetID of the received ResponsePDU. Otherwise, the ResponsePDU is discarded.

Certain errors cause the UnixDomainConnector object to disconnect. Other errors are ignored and the respective PDU is discarded.

Note
Don't invoke this slot from outside the object!

Definition at line 153 of file UnixDomainConnector.cpp.

References disconnect(), m_response_arrived, m_response_mutex, m_responses, m_socket, agentxcpp::PDU::parse_pdu(), pduArrived(), and agentxcpp::read32().

Referenced by UnixDomainConnector().

void UnixDomainConnector::do_send ( QSharedPointer< PDU pdu)
privateslot

Internal slot to send data.

This slot is invoked when data must be sent. It serializes the given PDU and sends it. Errors are ignored.

Note
Don't invoke this slot from outside the object!

Definition at line 299 of file UnixDomainConnector.cpp.

References m_socket.

bool UnixDomainConnector::is_connected ( )

Find out whether the object is currently connected.

Returns
True if the object is connected, false otherwise.

Definition at line 140 of file UnixDomainConnector.cpp.

References m_is_connected, and m_mutex_is_connected.

Referenced by connect(), and agentxcpp::MasterProxy::is_connected().

void agentxcpp::UnixDomainConnector::pduArrived ( QSharedPointer< PDU )
signal

Emitted when a PDU arrived.

This signal is emitted once for every arrived PDU, except for ResponsePDU's.

Referenced by do_receive().

QSharedPointer< ResponsePDU > UnixDomainConnector::request ( QSharedPointer< PDU pdu)

Send a PDU and wait for the response.

This method sends a PDU. Then, it adds an entry to m_responses to indicate that a ResponsePDU is awaited. Finally, it waits until that ResponsePDU arrives and returns it (it is removed from m_responses).

Todo:
Add timeout. Currently, the method does not time out.

Definition at line 276 of file UnixDomainConnector.cpp.

References m_response_arrived, m_response_mutex, and m_responses.

Referenced by agentxcpp::MasterProxy::connect(), agentxcpp::MasterProxy::disconnect(), agentxcpp::MasterProxy::do_registration(), agentxcpp::MasterProxy::send_notification(), and agentxcpp::MasterProxy::undo_registration().

void UnixDomainConnector::send ( QSharedPointer< PDU pdu)

Send a PDU.

This function enqueues a PDU for sending, by invoking do_send(). This means the this function returns before the PDU is actually sent.

Note
Don't invoke do_send() yourself.

Definition at line 308 of file UnixDomainConnector.cpp.

Referenced by agentxcpp::MasterProxy::handle_pdu().

Member Data Documentation

QMutex agentxcpp::UnixDomainConnector::m_connection_mutex
private

Needed for m_connection_waitcondition.

Definition at line 138 of file UnixDomainConnector.hpp.

Referenced by connect(), and disconnect().

QWaitCondition agentxcpp::UnixDomainConnector::m_connection_waitcondition
private

A waitcondition to synchronize connect actions.

This condition is used to synchronize connect() and do_connect() respectively disconnect() and do_disconnect(). It is used in conjunction with m_connection_mutex.

Definition at line 147 of file UnixDomainConnector.hpp.

Referenced by connect(), disconnect(), do_connect(), and do_disconnect().

QString agentxcpp::UnixDomainConnector::m_filename
private

The filename of the unix domain socket.

Definition at line 128 of file UnixDomainConnector.hpp.

Referenced by do_connect().

bool agentxcpp::UnixDomainConnector::m_is_connected
private

Whether the object is currently connected.

The member is protected by m_mutex_is_connected.

Definition at line 154 of file UnixDomainConnector.hpp.

Referenced by do_connect(), do_disconnect(), and is_connected().

QMutex agentxcpp::UnixDomainConnector::m_mutex_is_connected
private

A mutex to protect m_is_connected.

Definition at line 159 of file UnixDomainConnector.hpp.

Referenced by do_connect(), do_disconnect(), and is_connected().

QWaitCondition agentxcpp::UnixDomainConnector::m_response_arrived
private

A waitcondition to inform waiters of ResponsePDU's.

The m_response_mutex is used for synchronization.

Definition at line 182 of file UnixDomainConnector.hpp.

Referenced by do_receive(), and request().

QMutex agentxcpp::UnixDomainConnector::m_response_mutex
private

Used to protect m_responses and for m_response_arrived.

Definition at line 175 of file UnixDomainConnector.hpp.

Referenced by do_receive(), and request().

std::map< quint32, QSharedPointer<ResponsePDU> > agentxcpp::UnixDomainConnector::m_responses
private

Storage for ResponsePDU's.

This map contains entries with packetID as key and ResponsePDU's as values. An entry with a NULL pointer value means that a ResponsePDU with the given packetID is awaited.

This member is protected by m_response_mutex.

Definition at line 170 of file UnixDomainConnector.hpp.

Referenced by do_receive(), and request().

QLocalSocket agentxcpp::UnixDomainConnector::m_socket
private

The socket used internally for networking.

Definition at line 123 of file UnixDomainConnector.hpp.

Referenced by do_connect(), do_disconnect(), do_receive(), do_send(), and UnixDomainConnector().

unsigned agentxcpp::UnixDomainConnector::m_timeout
private

The timeout in milliseconds.

Definition at line 133 of file UnixDomainConnector.hpp.

Referenced by connect(), disconnect(), do_connect(), and do_disconnect().


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