File indexing completed on 2024-04-28 15:40:16
0001 // SPDX-FileCopyrightText: 2014-2022 Jesper K. Pedersen <blackie@kde.org> 0002 // 0003 // SPDX-License-Identifier: GPL-2.0-or-later 0004 0005 #include "RemoteConnection.h" 0006 0007 #include "RemoteCommand.h" 0008 0009 #include <QApplication> 0010 #include <QBuffer> 0011 #include <QTcpSocket> 0012 #include <QThread> 0013 #include <QTime> 0014 0015 #if 0 0016 #define protocolDebug qDebug 0017 #else 0018 #define protocolDebug \ 0019 if (false) \ 0020 qDebug 0021 #endif 0022 0023 using namespace RemoteControl; 0024 0025 RemoteConnection::RemoteConnection(QObject *parent) 0026 : QObject(parent) 0027 { 0028 } 0029 0030 void RemoteConnection::sendCommand(const RemoteCommand &command) 0031 { 0032 protocolDebug() << qPrintable(QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss.zzz"))) 0033 << ": Sending " << QString::number((int)command.commandType()); 0034 Q_ASSERT(QThread::currentThread() == qApp->thread()); 0035 0036 if (!isConnected()) 0037 return; 0038 0039 // Stream into a buffer so we can send length of buffer over 0040 // this is to ensure the remote side gets all data before it 0041 // starts to demarshal the data. 0042 QBuffer buffer; 0043 buffer.open(QIODevice::WriteOnly); 0044 QDataStream stream(&buffer); 0045 0046 // stream a placeholder for the length 0047 stream << (qint32)0; 0048 0049 // Steam the id and the data 0050 stream << (qint32)command.commandType(); 0051 command.encode(stream); 0052 0053 // Wind back and stream the length 0054 stream.device()->seek(0); 0055 stream << (qint32)buffer.size(); 0056 0057 // Send the data. 0058 socket()->write(buffer.data()); 0059 socket()->flush(); 0060 } 0061 0062 void RemoteConnection::dataReceived() 0063 { 0064 QTcpSocket *socket = this->socket(); 0065 if (!socket) 0066 return; 0067 0068 QDataStream stream(socket); 0069 0070 while (socket->bytesAvailable()) { 0071 if (m_state == WaitingForLength) { 0072 if (socket->bytesAvailable() < (qint64)sizeof(qint32)) 0073 return; 0074 0075 stream >> m_length; 0076 m_length -= sizeof(qint32); 0077 m_state = WaitingForData; 0078 } 0079 0080 if (m_state == WaitingForData) { 0081 if (socket->bytesAvailable() < m_length) 0082 return; 0083 0084 m_state = WaitingForLength; 0085 QByteArray data = socket->read(m_length); 0086 Q_ASSERT(data.length() == m_length); 0087 0088 QBuffer buffer(&data); 0089 buffer.open(QIODevice::ReadOnly); 0090 QDataStream stream(&buffer); 0091 qint32 id; 0092 stream >> id; 0093 0094 std::unique_ptr<RemoteCommand> command = RemoteCommand::create(static_cast<CommandType>(id)); 0095 command->decode(stream); 0096 protocolDebug() << qPrintable(QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss.zzz"))) 0097 << ": Received " << id; 0098 0099 Q_EMIT gotCommand(*command); 0100 } 0101 } 0102 } 0103 0104 #include "moc_RemoteConnection.cpp"