From 3b14d399c8dfe556cd4a253db8e06e4f4ce79633 Mon Sep 17 00:00:00 2001 From: "Maciej J. Karpiuk" Date: Fri, 4 Sep 2015 12:45:38 +0200 Subject: [PATCH] libIpc: doxygen docs added [Feature] libIpc doxygen docs enabled and enhanced [Cause] documentation task in progress, libIpc was not yet included [Solution] write missing docs, create group [Verification] build docs and check libIpc module Change-Id: Ic8e5261200da9714b478461fe830fabbaa3b5bc9 --- libs/ipc/client.hpp | 99 +++++++++++++++++++++++-------- libs/ipc/epoll/event-poll.hpp | 54 ++++++++++++++++- libs/ipc/epoll/events.hpp | 12 +++- libs/ipc/exception.hpp | 36 ++++++++++- libs/ipc/internals/processor.hpp | 17 +++--- libs/ipc/method-result.hpp | 4 ++ libs/ipc/service.hpp | 125 +++++++++++++++++++++++++++++---------- libs/ipc/types.hpp | 54 ++++++++++++++++- 8 files changed, 330 insertions(+), 71 deletions(-) diff --git a/libs/ipc/client.hpp b/libs/ipc/client.hpp index e083166..a26ccbc 100644 --- a/libs/ipc/client.hpp +++ b/libs/ipc/client.hpp @@ -19,6 +19,7 @@ /** * @file * @author Jan Olszak (j.olszak@samsung.com) + * @defgroup libIpc libIpc * @brief Handling client connections */ @@ -36,29 +37,68 @@ namespace ipc { /** - * This class wraps communication via UX sockets for client applications. + * @brief This class wraps communication via UX sockets for client applications. * It uses serialization mechanism from Config. * - * For message format @see ipc::Processor + * @code + * // eventPoll - epoll wrapper class + * // address - server socket address + * ipc::epoll::EventPoll examplePoll; + * ipc::Client myClient(examplePoll, address); + * myClient.start(); // connect to the service + * // call method synchronously + * const auto result = mClient.callSync( + * api::ipc::METHOD_GET_ZONE_ID_LIST, + * std::make_shared()); + * // call method asynchronously + * // first: declare lambda function to call on completion + * auto asyncResult = [result](ipc::Result&& out) { + * if (out.isValid()) { + * // got successful response! + * } + * }; + * std::string id = "example_zone_id"; + * mClient.callAsync(api::ipc::METHOD_DESTROY_ZONE, + * std::make_shared(api::ZoneId{id}), + * asyncResult); + * @endcode + * + * @see libConfig + * @see ipc::Processor + * @see ipc::epoll::EventPoll + * + * @ingroup libIpc */ class Client { public: /** - * @param eventPoll event poll - * @param serverPath path to the server's socket + * Constructs the Client, but doesn't start it. + * Once set-up, call start() to connect client to the server. + * + * @param eventPoll event poll + * @param serverPath path to the server's socket */ Client(epoll::EventPoll& eventPoll, const std::string& serverPath); ~Client(); + /** + * Copying Client class is prohibited. + */ Client(const Client&) = delete; + /** + * Copying Client class is prohibited. + */ Client& operator=(const Client&) = delete; /** * Starts processing + * @note if the Client is already running, it quits immediately (no exception thrown) */ void start(); /** + * Is the communication thread running? + * * @return is the communication thread running */ bool isStarted(); @@ -66,21 +106,23 @@ public: /** * Stops processing * - * @param wait does it block waiting for all internals to stop + * @param wait should the call block while waiting for all internals to stop? By default true - do block. */ void stop(bool wait = true); /** * Set the callback called for each new connection to a peer * - * @param newPeerCallback the callback + * @param newPeerCallback the callback to call on new connection event + * @note if callback is already set, it will be overridden */ void setNewPeerCallback(const PeerCallback& newPeerCallback); /** * Set the callback called when connection to a peer is lost * - * @param removedPeerCallback the callback + * @param removedPeerCallback the callback to call on peer disconnected event + * @note if callback is already set, it will be overridden */ void setRemovedPeerCallback(const PeerCallback& removedPeerCallback); @@ -89,8 +131,10 @@ public: * When a message with the given method id is received * the data will be parsed and passed to this callback. * - * @param methodID API dependent id of the method - * @param method method handling implementation + * @param methodID API dependent id of the method + * @param method method handling implementation + * @tparam SentDataType data type to send + * @tparam ReceivedDataType data type to receive */ template void setMethodHandler(const MethodID methodID, @@ -101,28 +145,32 @@ public: * When a message with the given method id is received * the data will be parsed and passed to this callback. * - * @param methodID API dependent id of the method - * @param signal signal handling implementation - * @tparam ReceivedDataType data type to serialize + * @param methodID API dependent id of the method + * @param signal data processing callback + * @tparam ReceivedDataType data type to receive */ template void setSignalHandler(const MethodID methodID, const typename SignalHandler::type& signal); /** - * Removes the callback + * Removes the callback associated with specific method id. * - * @param methodID API dependent id of the method + * @param methodID API dependent id of the method + * @see setMethodHandler() + * @see setSignalHandler() */ void removeMethod(const MethodID methodID); /** * Synchronous method call. * - * @param methodID API dependent id of the method - * @param data data to send - * @param timeoutMS how long to wait for the return value before throw - * @return result data + * @param methodID API dependent id of the method + * @param data data to send + * @param timeoutMS optional, how long to wait for the return value before throw (milliseconds, default: 5000) + * @tparam SentDataType data type to send + * @tparam ReceivedDataType data type to receive + * @return pointer to the call result data */ template std::shared_ptr callSync(const MethodID methodID, @@ -133,10 +181,11 @@ public: * Asynchronous method call. The return callback will be called on * return data arrival. It will be run in the PROCESSOR thread. * - * - * @param methodID API dependent id of the method - * @param data data to send - * @param resultCallback callback for result serialization and handling + * @param methodID API dependent id of the method + * @param data data to send + * @param resultCallback callback processing the return data + * @tparam SentDataType data type to send + * @tparam ReceivedDataType data type to receive */ template void callAsync(const MethodID methodID, @@ -148,9 +197,9 @@ public: * There is no return value from the peer * Sends any data only if a peer registered this a signal * - * @param methodID API dependent id of the method - * @param data data to sent - * @tparam SentDataType data type to send + * @param methodID API dependent id of the method + * @param data data to send + * @tparam SentDataType data type to send */ template void signal(const MethodID methodID, diff --git a/libs/ipc/epoll/event-poll.hpp b/libs/ipc/epoll/event-poll.hpp index ba82497..ceb5717 100644 --- a/libs/ipc/epoll/event-poll.hpp +++ b/libs/ipc/epoll/event-poll.hpp @@ -35,23 +35,71 @@ namespace ipc { namespace epoll { +/** + * @brief This class waits on registered file descriptor for events. + * It uses epoll mechanism. + * + * @see ipc::epoll::Events + * + * @ingroup Types + */ class EventPoll { public: + /** + * Generic function type used as callback for epoll events. + * + * @param fd descriptor that triggered the event + * @param events event mask that occured + * @see ipc::epoll::Events + */ typedef std::function Callback; + /** + * Constructs the EventPoll and initializes the underlaying epoll mechanism. + * @throw UtilsException thrown if epoll initialization failed + */ EventPoll(); ~EventPoll(); + /** + * Returns epoll handle. + * @return handle or -1 if not initialized + */ int getPollFD() const; + /** + * Add descriptor and it's watched events. + * + * @param fd descriptor to watch + * @param events events to associate with the descriptor + * @param callback callback to call once the event occurs + * @throw UtilsException thrown if descriptor already registered or add fail + * @see ipc::epoll::Events + */ void addFD(const int fd, const Events events, Callback&& callback); + + /** + * Modify watched events for descriptor. + * @param fd watched descriptor, already registered + * @param events events to associate with the descriptor + * @throw UtilsException if descriptor not found or epoll modify fail + * @see ipc::epoll::Events + */ void modifyFD(const int fd, const Events events); + + /** + * Remove descriptor from the watch list. + * @param fd watched descriptor + */ void removeFD(const int fd); /** - * Dispatch at most one signaled FD - * @param timeoutMs how long should wait in case of no pending events - * (0 - return immediately, -1 - wait forever) + * Wait for events on descriptor on the watch list. + * Dispatch at most one signaled FD. + * + * @param timeoutMs how long should wait in case of no pending events + * (0 - return immediately, -1 - wait forever) + * @throw UtilsException if epoll_wait fails * @return false on timeout */ bool dispatchIteration(const int timeoutMs); diff --git a/libs/ipc/epoll/events.hpp b/libs/ipc/epoll/events.hpp index 093542b..219bcd2 100644 --- a/libs/ipc/epoll/events.hpp +++ b/libs/ipc/epoll/events.hpp @@ -31,8 +31,18 @@ namespace ipc { namespace epoll { -typedef unsigned int Events; ///< bitmask of EPOLL* constants +/** + * @brief bitmask of EPOLL* constants + * @ingroup Types + */ +typedef unsigned int Events; +/** + * Convert event mask into readable string. + * Values will be comma separated. + * @param events event type mask to convert + * @return string describing the mask + */ std::string eventsToString(Events events); } // namespace epoll diff --git a/libs/ipc/exception.hpp b/libs/ipc/exception.hpp index 271cf9a..140619c 100644 --- a/libs/ipc/exception.hpp +++ b/libs/ipc/exception.hpp @@ -31,48 +31,82 @@ namespace ipc { /** - * Base class for exceptions in IPC + * @brief Base class for all exceptions in libIpc. + * @ingroup Types + * @defgroup IPCException IPCException */ struct IPCException: public std::runtime_error { IPCException(const std::string& message) : std::runtime_error(message) {} }; +/** + * Exception to indicate error while reading/parsing data from the socket. + * @ingroup IPCException + */ struct IPCParsingException: public IPCException { IPCParsingException(const std::string& message = "Exception during reading/parsing data from the socket") : IPCException(message) {} }; +/** + * Exception to indicate error while writing/serializing data to the socket. + * @ingroup IPCException + */ struct IPCSerializationException: public IPCException { IPCSerializationException(const std::string& message = "Exception during writing/serializing data to the socket") : IPCException(message) {} }; +/** + * Exception to indicate that requested peer is not available, i.e. might got disconnected. + * @ingroup IPCException + */ struct IPCPeerDisconnectedException: public IPCException { IPCPeerDisconnectedException(const std::string& message = "No such peer. Might got disconnected.") : IPCException(message) {} }; +/** + * Exception to indicate that peer performed a forbidden action. + * @ingroup IPCException + */ struct IPCNaughtyPeerException: public IPCException { IPCNaughtyPeerException(const std::string& message = "Peer performed a forbidden action.") : IPCException(message) {} }; +/** + * Exception to indicate error while removing peer + * @ingroup IPCException + */ struct IPCRemovedPeerException: public IPCException { IPCRemovedPeerException(const std::string& message = "Removing peer") : IPCException(message) {} }; +/** + * Exception to indicate error while closing IPC channel + * @ingroup IPCException + */ struct IPCClosingException: public IPCException { IPCClosingException(const std::string& message = "Closing IPC") : IPCException(message) {} }; +/** + * Exception to indicate timeout event error + * @ingroup IPCException + */ struct IPCTimeoutException: public IPCException { IPCTimeoutException(const std::string& message) : IPCException(message) {} }; +/** + * Exception to indicate user error + * @ingroup IPCException + */ struct IPCUserException: public IPCException { IPCUserException(const int code, const std::string& message) : IPCException(message), diff --git a/libs/ipc/internals/processor.hpp b/libs/ipc/internals/processor.hpp index 2706792..e383a57 100644 --- a/libs/ipc/internals/processor.hpp +++ b/libs/ipc/internals/processor.hpp @@ -246,21 +246,24 @@ public: const MessageID messageID); /** - * Removes the callback + * Removes the callback associated with specific method id. * - * @param methodID API dependent id of the method + * @param methodID API dependent id of the method + * @see setMethodHandler() + * @see setSignalHandler() */ void removeMethod(const MethodID methodID); /** * Synchronous method call. * - * @param methodID API dependent id of the method - * @param peerID id of the peer - * @param data data to send - * @param timeoutMS how long to wait for the return value before throw - * @tparam SentDataType data type to send + * @param methodID API dependent id of the method + * @param peerID id of the peer + * @param data data to send + * @param timeoutMS optional, how long to wait for the return value before throw (milliseconds, default: 5000) + * @tparam SentDataType data type to send * @tparam ReceivedDataType data type to receive + * @return call result data */ template std::shared_ptr callSync(const MethodID methodID, diff --git a/libs/ipc/method-result.hpp b/libs/ipc/method-result.hpp index 26369ed..c1729f7 100644 --- a/libs/ipc/method-result.hpp +++ b/libs/ipc/method-result.hpp @@ -33,6 +33,10 @@ namespace ipc { class Processor; +/** + * @brief Class used to obtain method call result code. + * @ingroup Types + */ class MethodResult { public: typedef std::shared_ptr Pointer; diff --git a/libs/ipc/service.hpp b/libs/ipc/service.hpp index 5e73a71..a5f7c86 100644 --- a/libs/ipc/service.hpp +++ b/libs/ipc/service.hpp @@ -38,28 +38,72 @@ namespace ipc { /** - * This class wraps communication via UX sockets. + * @brief This class wraps communication via UX sockets. * It uses serialization mechanism from Config. * - * For message format @see ipc::Processor + * @code + * // eventPoll - epoll wrapper class + * // address - server socket address + * ipc::epoll::EventPoll examplePoll; + * // create callbacks for connected / disconnected events + * ipc::PeerCallback connectedCallback = [this](const ipc::PeerID peerID, + * const ipc::FileDescriptor) { + * // new connection came! + * }; + * ipc::PeerCallback disconnectedCallback = [this](const ipc::PeerID peerID, + * const ipc::FileDescriptor) { + * // connection disconnected! + * }; + * // create the service + * ipc::Service myService(eventPoll, "/tmp/example_service.socket", + * connectedCallback, disconnectedCallback)); + * // add example method handler + * auto exampleMethodHandler = [&](const PeerID, std::shared_ptr& data, MethodResult::Pointer methodResult) { + * // got example method call! Incoming data in "data" argument + * // respond with some data + * auto returnData = std::make_shared(data->intVal); + * methodResult->set(returnData); + * }; + * const MethodID exampleMethodID = 1234; + * myService.setMethodHandler(exampleMethodID, exampleMethodHandler); + * myService.start(); // start the service, clients may connect via /tmp/example_service.socket + * @endcode + * + * @see libConfig + * @see ipc::Processor + * + * @ingroup libIpc */ class Service { public: /** - * @param eventPoll event poll - * @param path path to the socket + * Constructs the Service, but doesn't start it. + * The object is ready to add methods. + * Once set-up, call start() to start the service. + * + * @param eventPoll event poll + * @param path path to the socket + * @param addPeerCallback optional on new peer connection callback + * @param removePeerCallback optional on peer removal callback */ Service(epoll::EventPoll& eventPoll, const std::string& path, const PeerCallback& addPeerCallback = nullptr, const PeerCallback& removePeerCallback = nullptr); - ~Service(); + virtual ~Service(); + /** + * Copying Service class is prohibited. + */ Service(const Service&) = delete; + /** + * Copying Service class is prohibited. + */ Service& operator=(const Service&) = delete; /** * Starts processing + * @note if the service is already running, it quits immediately (no exception thrown) */ void start(); @@ -71,62 +115,79 @@ public: /** * Stops all working threads * - * @param wait does it block waiting for all internals to stop + * @param wait should the call block while waiting for all internals to stop? By default true - do block. */ void stop(bool wait = true); /** * Set the callback called for each new connection to a peer * - * @param newPeerCallback the callback + * @param newPeerCallback the callback to call on new connection event + * @note if callback is already set, it will be overridden */ void setNewPeerCallback(const PeerCallback& newPeerCallback); /** * Set the callback called when connection to a peer is lost * - * @param removedPeerCallback the callback + * @param removedPeerCallback the callback to call on peer disconnected event + * @note if callback is already set, it will be overridden */ void setRemovedPeerCallback(const PeerCallback& removedPeerCallback); /** - * Saves the callback connected to the method id. - * When a message with the given method id is received - * the data will be parsed and passed to this callback. + * Saves the callbacks connected to the method id. + * When a message with the given method id is received, + * the data will be passed to the serialization callback through file descriptor. + * + * Then the process callback will be called with the parsed data. * - * @param methodID API dependent id of the method - * @param method method handling implementation + * @param methodID API dependent id of the method + * @param method data processing callback + * @tparam SentDataType data type to send + * @tparam ReceivedDataType data type to receive */ template void setMethodHandler(const MethodID methodID, const typename MethodHandler::type& method); /** - * Saves the callback connected to the method id. - * When a message with the given method id is received - * the data will be parsed and passed to this callback. + * Saves the callbacks connected to the method id. + * When a message with the given method id is received, + * the data will be passed to the serialization callback through file descriptor. + * + * Then the process callback will be called with the parsed data. + * There is no return data to send back. * - * @param methodID API dependent id of the method - * @param handler handling implementation - * @tparam ReceivedDataType data type to serialize + * Adding signal sends a registering message to all peers + * + * @param methodID API dependent id of the method + * @param handler data processing callback + * @tparam ReceivedDataType data type to receive */ template void setSignalHandler(const MethodID methodID, const typename SignalHandler::type& handler); /** - * Removes the callback + * Removes the callback associated with specific method id. * - * @param methodID API dependent id of the method + * @param methodID API dependent id of the method + * @see setMethodHandler() + * @see setSignalHandler() */ void removeMethod(const MethodID methodID); /** * Synchronous method call. * - * @param methodID API dependent id of the method - * @param data data to send - * @return result data + * @param methodID API dependent id of the method + * @param peerID id of the peer + * @param data data to send + * @param timeoutMS optional, how long to wait for the return value before throw (milliseconds, default: 5000) + * @tparam SentDataType data type to send + * @tparam ReceivedDataType data type to receive + * @return pointer to the call result data */ template std::shared_ptr callSync(const MethodID methodID, @@ -138,10 +199,12 @@ public: * Asynchronous method call. The return callback will be called on * return data arrival. It will be run in the PROCESSOR thread. * - * - * @param methodID API dependent id of the method - * @param data data to send - * @param resultCallback callback for result serialization and handling + * @param methodID API dependent id of the method + * @param peerID id of the peer + * @param data data to send + * @param resultCallback callback processing the return data + * @tparam SentDataType data type to send + * @tparam ReceivedDataType data type to receive */ template void callAsync(const MethodID methodID, @@ -154,9 +217,9 @@ public: * There is no return value from the peer * Sends any data only if a peer registered this a signal * - * @param methodID API dependent id of the method - * @param data data to sent - * @tparam SentDataType data type to send + * @param methodID API dependent id of the method + * @param data data to send + * @tparam SentDataType data type to send */ template void signal(const MethodID methodID, diff --git a/libs/ipc/types.hpp b/libs/ipc/types.hpp index fad01b3..c9b270b 100644 --- a/libs/ipc/types.hpp +++ b/libs/ipc/types.hpp @@ -31,19 +31,67 @@ namespace ipc { +/** + * @brief Generic types used in libIpc. + * + * @ingroup libIpc + * @defgroup Types libIpc tools + */ + typedef int FileDescriptor; typedef unsigned int MethodID; typedef std::string MessageID; typedef std::string PeerID; -typedef std::function PeerCallback; -typedef std::function& data)> SerializeCallback; -typedef std::function(int fd)> ParseCallback; +/** + * Generic function type used as callback for peer events. + * + * @param peerID peer identifier that event relates to + * @param fd event origin + * @ingroup Types + */ +typedef std::function PeerCallback; + +/** + * Generic function type used as callback for serializing and + * saving serialized data to the descriptor. + * + * @param fd descriptor to save the serialized data to + * @param data data to serialize + * @ingroup Types + */ +typedef std::function& data)> SerializeCallback; + +/** + * Generic function type used as callback for reading and parsing data. + * + * @param fd descriptor to read the data from + * @ingroup Types + */ +typedef std::function(ipc::FileDescriptor fd)> ParseCallback; +/** + * Generate an unique message id. + * + * @return new, unique MessageID + * @ingroup Types + */ MessageID getNextMessageID(); + +/** + * Generate an unique peer id. + * + * @return new, unique PeerID + * @ingroup Types + */ PeerID getNextPeerID(); +/** + * Generic type used as a callback function for handling signals. + * @tparam ReceivedDataType type of received data + * @ingroup Types + */ template struct SignalHandler { typedef std::function