/** * @RDE_HEADER@ * AvaComm * $Id$ * $HeadURL$ * $Author$ * Created by Christian Fröbel, SLSE, 2017-06-16 */ #pragma once #include "iava_comm.h" #include "ava_types.h" #include "avm_export.h" #include "logger.h" #include #include #include #include #include class QByteArray; class QString; class QStringList; class QRect; namespace AudioVideoManagement { /** * Implements the client-side of the RCP/AVA-Protocoll -- i.e. the communication with AVS_Workstation. * * The Idea of this class is simply to provide * 1. Methods to issue commands * 2. Signals for incoming replys (defined in IAvaComm). * 3. Possibly reconnecting when the connection got lost. * Observing the connection using KeepAlives is done by AvaSession. * * A command can have multiple replys and thus can trigger multiple signals. * The layer above is then responsible to keep track of certain states in the protocol * and to e.g. assemble the received information into a more abstract format. * * @see AvaControl * @see AvaSession * @author Christian Fröbel */ class AVM_COMMON_EXPORT AvaComm : public IAvaComm { Q_OBJECT public: AvaComm(const QString &avaHost, quint16 avaPort); void start(); void forceDisconnect() override; void switchContext(int exerciseId) override; void setUserProfile(const QString &userName, const QString &langCode, AvaAudioPrio, AvaGuiStyle) override; void setTimezone(QChar tz) override; void setVideoDialogProfile(const QString &dialogId, AvaVisibility) override; void setVideoDialogGeometry(const QString &dialogId, const QRect &geometry) override; void setVideoProfile(const QString &dialogId, const QString &menuDef) override; void setAnnouncementProfile(AvaSumChannel sumChannel, const QString &menuDef, const QString &identityList, const QString &stateList) override; void getStreamList(AvaStreamType, AvaStreamSource) override; void chooseStream(const QString &dialogId, const QString &streamName, bool muted) override; void chooseStreamOverview(const QString &dialogId, const QStringList &streamNames, bool muted) override; void releaseStream(const QString &dialogId, const QString &streamName) override; void queryTimeline(const QString &streamName, const boost::optional &start = {}, const boost::optional &end = {}) override; void setVolume(AvaVolume db) override; void chooseImport(const QString &dialogId, const QString &path, int mode) override; void releaseImport(const QString &dialogId) override; void setScript(const QString &dialogId, const QString &scriptName, AvaScriptSource, const QVector &streams) override; void releaseScript(const QString &dialogId, const QString &scriptName) override; void sendPreparedCommand(const QString &command) override; /** streamControl */ ///@{ void startStream(const QString &dialogId, const QString &streamName, AvaSpeed) override; void stopStream(const QString &dialogId, const QString &streamName) override; void pauseStream(const QString &dialogId, const QString &streamName) override; void setStreamSpeed(const QString &dialogId, const QString &streamName, AvaSpeed) override; void setAbsPosition(const QString &dialogId, const QString &streamName, AvaTimePoint pos) override; void positionUpdate(const QString &dialogId, const QString &streamName, std::chrono::milliseconds updateInterval) override; void setPint(const QString &dialogId, const QString &streamName, bool doSkip) override; ///@} /** scriptControl */ ///@{ void startScript(const QString &dialogId, const QString &scriptName) override; void stopScript(const QString &dialogId, const QString &scriptName) override; void pauseScript(const QString &dialogId, const QString &scriptName) override; void setAbsPositionScript(const QString &dialogId, const QString &scriptName, AvaTimePoint pos) override; ///@} /** ELOKA */ ///@{ void getElokaList(const QString &streamName) override; void chooseEloka(const QString &streamName, const QString &signalName, AvaElokaMode) override; void releaseEloka(const QString &streamName) override; void queryEloka(AvaQueryElokaMode) override; ///@} /** StreamNameMapping */ ///@{ /** For performance reasons we could also implement the command where several mappings can be sent in one go. */ void defineStreamNameMapping(const QString &internalName, const QString &displayName) override; void resetStreamNameMapping() override; ///@} void keepAlive() override; private slots: void onReadyRead(QTcpSocket *socket); protected: AVSocketWrapper m_avSocket; private: enum class Response { Ok = 200, RtChoiceUnitState = 212, SumChannelState = 214, Volume = 215, VideoDialogState = 218, StreamInfo = 220, StreamPos = 221, StreamSpeed = 222, StreamState = 223, StreamMode = 224, StreamAudioMute = 225, StreamAudioState = 226, ElokaState = 227, ScriptInfo = 230, ScriptState = 231, ScriptPos = 233, StreamVolumeChanged = 228, RtVolumeUser = 252, ElokaList = 291, InvalidNameList = 292, StreamList = 293, QueryElokaList = 294, TimelineList = 297, KeepAlive = 298, EndOfParameterList = 299 }; void parseResponse(const QByteArray &line); void parseListValue(const QVector &parts); boost::optional m_pendingList; //!< Contains the type of list currently being read. LOGGER_T m_logger; LOGGER_T m_loggerIO; }; } // namespace AudioVideoManagement