poolmanager.h 7.59 KB
/* ****************************************************************************
 * Copyright 2019 Open Systems Development BV                                 *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 * ***************************************************************************/
#ifndef OSDEV_COMPONENTS_CPOOLMANAGER_H
#define OSDEV_COMPONENTS_CPOOLMANAGER_H

/***************************************************************************
 * Global Includes
 ***************************************************************************/
#include <QObject>
#include <QString>
#include <QUuid>
#include <QHash>
#include <QTcpServer>
#include <QList>

/***************************************************************************
 * Local Includes
 ***************************************************************************/
#include "eventcodes.h" // Make the codes known.

#include "socketcontainer.h"
#include "tcpsocket.h"

namespace osdev  {
namespace components {

/**
 * @brief Handles a pool of network connections
 */
class PoolManager : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief Constructor
     * @param bServer True for server-mode, false for client-mode (Server is default).
     * @param ipAddress IP-address to listen at (server-mode) or to connect to
     *                  (client-mode)
     * @param portNumber Portnumber to listen at (server-mode) or to connect to
     *                   (server-mode)
     * @param maxTcpConnections Maximum number of TCP connections accepted
     * @param maxUdpConnections Maximum number of UDP connections accepted
     *                          (currently unused)
     * @param _parent Parent object
     */
    PoolManager(bool    bServer             = false,
                const QString& ipAddress    = "0.0.0.0",
                int     portNumber          = 3500,
                int     maxTcpConnections   = 10,   // The maximum number of connections we accept.
                int     maxUdpConnections   = 10,
                QObject *_parent            = nullptr );

    /// @brief Destructor
    ~PoolManager();

    /// Deleted copy-constructor
    PoolManager(const PoolManager&) = delete;
    /// Deleted assignment operator
    PoolManager& operator=(const PoolManager&) = delete;
    /// Deleted move-constructor
    PoolManager(PoolManager&&) = delete;
    /// Deleted move operator
    PoolManager& operator=(PoolManager&&) = delete;

    /**
     * @brief Get the data for a specified ticket
     * @param sTicket Ticket ID
     * @return Available data
     */
    QString     getData( const QString& sTicket );

    /**
     * @brief Start the actual server (server-mode) or build the client
     *        connection (client-mode)
     * @return True on success, false on failure
     */
    bool        startNetworkLayer();

    /**
     * @brief Send data through the interface
     * @param sData Data to send
     */
    void        sendData( const QString &sData );

public slots:
    /// @brief Slot called when a new server-connection is available
    void        slotNewConnection();

    /**
     * @brief Slot called when data was sent through the specified socket
     * @param pSocket Socket through which data was sent
     */
    void        slotDataSent( TcpSocket *pSocket );

    /**
     * @brief Slot called when data is being received by the specified socket
     * @param pSocket Socket which is receiving data
     */
    void        slotReceivingData( TcpSocket *pSocket );

    /**
     * @brief Slot called when data was received through the specified socket
     * @param sData Data received
     * @param pSocket Socket through which data was sent
     */
    void        slotDataReceived( const QString &sData, TcpSocket *pSocket );

    /**
     * @brief Slot called when the specified socket was connected
     * @param pSocket Socket through which data was sent
     */
    void        slotConnected( TcpSocket *pSocket );

    /**
     * @brief Slot called when the specified socket was disconnected
     * @param pSocket Socket that was disconnected
     *
     * Also removes the socket from the list of known sockets and deletes it
     */
    void        slotDisconnected( TcpSocket *pSocket );

signals:
    /**
     * @brief Signal emitted when data is sent through a specified socket
     * @param sData Data to be sent
     * @param pSocket Socket that sends the data
     */
    void        signalSendData( const QString &sData, TcpSocket *pSocket );

    /**
     * @brief Signal emitted when data is present for the specified ticket
     * @param sTicket Ticket ID
     */
    void        dataPresent( const QString &sTicket );

    /**
     * @brief Relay the message signal to the eventmanager
     * @todo Check parameter meanings!
     * @param i1 sourceID ?
     * @param i2 DestID ?
     * @param i3 Connection status ?
     * @param i4 data ?
     */
    void        message( int i1, int i2, int i3, int i4 );

private:
    /**
     * @brief Create a new unique buffer ticket ID
     * @return New ticket ID
     */
    QString     createBufferTicket();

    /**
     * @brief Connect all signals and slots for the socket
     * @param l_pSocket Socket to connect
     */
    void        connectSocketSignals( TcpSocket *l_pSocket );

    /// @brief Resend messages that are still in the buffer
    void        resendDelayedMessages();

    QTcpServer               *m_pServer;            ///< The pointer to the server object.
    SocketContainer          *m_pSocketContainer;   ///< Administration which keeps track of the Sockets.
    TcpSocket                *m_pSocket;

    QList< QString >          m_inputBuffer;      ///< Messages that can not be send yet will be stored here.
    QHash< QString, QString > m_outputBuffer;     ///< The hashtable we use for databuffering.

    bool        m_bServer;          ///< True for server-mode, false for client-mode
    QString     m_ipAddress;        ///< The ipAddress the clients are connecting to.
    int         m_portNumber;       ///< The portnumber our server is listening on.
    int         m_maxTcpConnections;///< The number of TCP connections we accept and make.
    int         m_maxUdpConnections;///< The number of UDP connections we accept and make.
};

} // End namespace components
} // End namespace osdev 

#endif /* OSDEV_COMPONENTS_CPOOLMANAGER_H */