// ************************************************************************** // // (C) Copyright 2009 Swiss SIMTEC AG // // ************************************************************************** // // $HeadURL$ // $LastChangedBy$ // $LastChangedDate$ // $LastChangedRevision$ // // Implementation of the Class PrtCnvCentralThread // ************************************************************************** #pragma once #include "PrtCnvSocketThread.hpp" #include "PrtCnvDbThread.hpp" #include namespace N_CoPrtCnv { class CoPrtCnvRadioTelegram; } namespace PrtCnv { class PrtCnvRadioThread; class PrtCnvThreadStarter; /** * This class handles the protocoll to central. This includes: * - connection with files instead sockets (configurable) * - send and receive telegrams * * @author * @version 1.0 * @created 05-Jan-2006 13:34:28 */ class PrtCnvCentralThread : public PrtCnv::PrtCnvThread { Q_OBJECT private: public: /** * @author wia * @version 1.0 * @updated 02-Jul-2009 14:32:58 */ ~PrtCnvCentralThread(); /** * @param a_parent The pointer to the starter-thread */ explicit PrtCnvCentralThread(PrtCnvThreadStarter* a_parent); /** * Creates all subcomponents and connects signals to slots */ int32_t create(NGL::Settings *settings) override; int32_t deinit() override; /** * Deallocates subcomponents. */ int32_t destroy() override; /** * Initializes the variables. */ int32_t init() override; /** * Starts the thread and connects to TCP-server */ int32_t start() override; /** * Stops the thread */ int32_t stop() override; // for direct communication void onDirectTextMessageReceived(const QByteArray &baJson); signals: // for direct communication void directTextMessage(const QByteArray &baJson); /** * Signal to start sending a telegram to central */ void checkSendToCentral(); /** * Signal to start sending a telegram to radio */ void checkSendToRadio(); /** * Signal to stop radio */ void stopRadio(); /** * Signal to start cleaning-process of radio-thread */ void cleanRadio(); /** * Signal to restart work of radio-thread */ void startRadio(); protected: /** * For reading/writing json telegrams to socket */ QWebSocket *m_webSocket; /** * The send-counter (only for sockets) */ int32_t m_SendCounter; public slots: /** * Checks whether a telegram must be sent and sends it. */ void checkSend(); /** * Stores that radio-thread has stopped. Cleans the Db and reinitializes when * central-thread has also stopped. */ void radioStopped(); /** * Starts radio-thread and itself for proceeding work after cleaning the Db. */ void radioCleant(); /** * Will be called from Db-thread when telegrams were stored permanent. This * function will then send the ack to central (socket-based) or delete the * telegramfiles (file-based) * * @param a_centralCounter */ void permanentStored(int32_t a_centralCounter); // called from Radio thread to indicate current connection state void onTetraConnectionState(bool bConnected); // called from Radio thread to indicate the license state of an equipment void onPlayerLicencedChanged(int equipNo, N_CoPrtCnv::E_LicensingKind kind); protected slots: // an effect siumlation was (de)activated void onAreaEffectSimulationDeactivated(int wirkfeldKennung); void onAreaEffectSimulationActivated(int wirkfeldKennung); // radio thread completely initialized void onRadioThreadInitDone(); /** * called when websocket is connected */ void connected(); /** * called when websocket is disconnected */ void disconnected(); /** * used to send periodically an ack to central */ void timeoutTick(); /** * see base-class */ void timeoutAliveAndConnection(); void onTextMessageReceived(const QString &msg); void stateChanged(QAbstractSocket::SocketState newState); protected: /** * Sends a ack-telegram to central. */ void sendAck(); /** * Stores a telegram to be sent to radio in volatile radio-list and permanent in * DB. * * @param a_telegram */ void handleTelegram(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_telegram); bool checkAndUpdateReceiveCounter(const int32_t a_counter); /** * Sends a central-telegram to socket or file, depending on configuration. Before * sending, the send-counter will be set. After sending the Db will be updated. * * @param a_telegram The central-telegram to be sent. * @param a_handle The handle assigned to telegram to be sent, we got from Db. */ void sendTelegram(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_telegram, PrtCnvStoredCentralTelegram *a_handle); /** * Processes the telegram AnforderungStatistikBroadcastNachforderugen. The * function fills the answer telegram StatistikBroadNachforderungen with the * actual statistic. * * @param a_umgMldTelegram */ void handleAnforderungStatistikBroadcastNachforderungen(); /** * Removes telegrams from ToCentral-table, if the central acknowledges their * reception * * @param a_ackTelegram */ void handleAck(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_telegram); /** * Calls clean of radio-thread and Db-thread and initializes the variables for * rework. */ void cleanAndReinit(); /** * returns true if telegram should be converted, stored and sent to radio * * @param a_telegram */ bool handleSpecialTelegram(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_telegram); /** * Sends a central-telegram to socket or file, depending on configuration. Before * sending, the send-counter will be set. * * @param a_telegram The central-telegram to be sent. */ void sendTelegram(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_telegram); /** * Connect as client to a TCP-server on ip-address configured as HostName and Port * configured as Port */ void connectSocket(); /** * Disconnects from TCP-server */ void disconnectSocket(); protected: /** * used for periodically send an ack to central */ PrtCnvRadioThread *m_RadioThread; /** * True if radio has stopped work */ bool m_RadioStopped; /** * True if central has stopped work */ bool m_CentralStopped; /** * Used for resending unacked telegrams */ int32_t m_LastSendCounter; /** * The (virtual) identify of the protocol-converter */ uint16_t m_VirtualTeilnehmerId; /** * The maximum equipment-ID for tetra - all telegrams with an higher ID will * be silently ignored */ uint16_t m_maxEqID; // timer to reconnect when no ack from central is coming anymore QTimer *m_aliveTimer; // timer to send ack to central QTimer *m_sendAckTimer; // timer to reconnect to central QTimer *m_reconnectTimer; /** * True if the database has to be cleant up (used for fast empty of signal buffers) */ QAtomicInt m_DoCleanup; PrtCnvDbThread *m_DbThread; // log telegrams in file PrtCnvTelegramLogThread *m_LogThread; // get injected telegrams PrtCnvInjectionThread *m_InjectionThread; /** * Counter of received telegrams (only for sockets) */ int32_t m_ReceiveCounter; /** * Acknowledged telegrams counter (only for sockets) */ int32_t m_ReceiveAckCounter; /** * The state-event-machine state */ PrtCnvSocketThread::E_State m_State; // set with all already deactivated effect simulations to not send deactivate telegram twice QSet m_deactivatedAreaEffectSimulations; // multimap with all mine areas and it's already triggered mines QHash> m_alreadyTriggeredMines; // true when we don't use socket but direct connections (through onDirectTextMessageReceived) bool m_bDirectConnection; bool m_bRadioThreadInitDone; }; }