diff --git a/src/tools/iostool/iostool.cpp b/src/tools/iostool/iostool.cpp index d0be8ede5e9..e65cae852a4 100644 --- a/src/tools/iostool/iostool.cpp +++ b/src/tools/iostool/iostool.cpp @@ -259,12 +259,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId, if (deviceSession) { int qmlPort = deviceSession->qmljsDebugPort(); if (qmlPort) { - qmlServer = new GenericRelayServer(this, qmlPort, deviceSession); + qmlServer = new QmlRelayServer(this, qmlPort, deviceSession); qmlServer->startServer(); } } if (debug) { - gdbServer = new SingleRelayServer(this, gdbFd); + gdbServer = new GdbRelayServer(this, gdbFd, conn); if (!gdbServer->startServer()) { doExit(-4); return; diff --git a/src/tools/iostool/iostool.h b/src/tools/iostool/iostool.h index 3519982c9b9..a2fd1f040e4 100644 --- a/src/tools/iostool/iostool.h +++ b/src/tools/iostool/iostool.h @@ -34,8 +34,8 @@ namespace Ios { class GdbRunner; -class SingleRelayServer; -class GenericRelayServer; +class GdbRelayServer; +class QmlRelayServer; class IosTool: public QObject { @@ -79,8 +79,8 @@ private: QFile outFile; QString m_qmlPort; QXmlStreamWriter out; - SingleRelayServer *gdbServer; - GenericRelayServer *qmlServer; + GdbRelayServer *gdbServer; + QmlRelayServer *qmlServer; GdbRunner *gdbRunner; bool m_echoRelays = false; friend class GdbRunner; diff --git a/src/tools/iostool/relayserver.cpp b/src/tools/iostool/relayserver.cpp index f952560752a..449f86057db 100644 --- a/src/tools/iostool/relayserver.cpp +++ b/src/tools/iostool/relayserver.cpp @@ -26,6 +26,7 @@ #include "relayserver.h" #include "iostool.h" +#include "mobiledevicelib.h" #ifdef Q_OS_UNIX #include @@ -45,15 +46,7 @@ Relayer::Relayer(RelayServer *parent, QTcpSocket *clientSocket) : Relayer::~Relayer() { - if (m_serverFileDescriptor > 0) { - ::close(m_serverFileDescriptor); - m_serverFileDescriptor = -1; - if (m_serverNotifier) - delete m_serverNotifier; - } - if (m_clientSocket->isOpen()) - m_clientSocket->close(); - delete m_clientSocket; + closeConnection(); } void Relayer::setClientSocket(QTcpSocket *clientSocket) @@ -93,7 +86,7 @@ void Relayer::handleSocketHasData(int socket) m_serverNotifier->setEnabled(false); char buf[255]; while (true) { - qptrdiff rRead = read(socket, &buf, sizeof(buf)-1); + qptrdiff rRead = readData(socket, &buf, sizeof(buf)-1); if (rRead == -1) { if (errno == EINTR) continue; @@ -158,7 +151,7 @@ void Relayer::handleClientHasData() .arg((quintptr)(void *)this), buf, rRead); } while (true) { - qptrdiff written = write(m_serverFileDescriptor, buf + pos, rRead); + qptrdiff written = writeData(m_serverFileDescriptor, buf + pos, rRead); if (written == -1) { if (errno == EINTR) continue; @@ -193,6 +186,32 @@ void Relayer::handleClientHasError(QAbstractSocket::SocketError error) server()->removeRelayConnection(this); } +int Relayer::readData(int socketFd, void *buf, size_t size) +{ + return read(socketFd, buf, size); +} + +int Relayer::writeData(int socketFd, const void *data, size_t size) +{ + return write(socketFd, data, size); +} + +void Relayer::closeConnection() +{ + if (m_serverFileDescriptor > 0) { + ::close(m_serverFileDescriptor); + m_serverFileDescriptor = -1; + if (m_serverNotifier) { + delete m_serverNotifier; + m_serverNotifier = nullptr; + } + } + if (m_clientSocket->isOpen()) + m_clientSocket->close(); + delete m_clientSocket; + m_clientSocket = nullptr; +} + IosTool *Relayer::iosTool() const { return (server() ? server()->iosTool() : 0); @@ -203,7 +222,7 @@ RelayServer *Relayer::server() const return qobject_cast(parent()); } -RemotePortRelayer::RemotePortRelayer(GenericRelayServer *parent, QTcpSocket *clientSocket) : +RemotePortRelayer::RemotePortRelayer(QmlRelayServer *parent, QTcpSocket *clientSocket) : Relayer(parent, clientSocket) { m_remoteConnectTimer.setSingleShot(true); @@ -217,7 +236,7 @@ void RemotePortRelayer::tryRemoteConnect() if (m_serverFileDescriptor > 0) return; ServiceSocket ss; - GenericRelayServer *grServer = qobject_cast(server()); + QmlRelayServer *grServer = qobject_cast(server()); if (!grServer) return; if (grServer->m_deviceSession->connectToPort(grServer->m_remotePort, &ss)) { @@ -294,16 +313,17 @@ void RelayServer::removeRelayConnection(Relayer *relayer) relayer->deleteLater(); } -SingleRelayServer::SingleRelayServer(IosTool *parent, - int serverFileDescriptor) : - RelayServer(parent) +GdbRelayServer::GdbRelayServer(IosTool *parent, + int serverFileDescriptor, ServiceConnRef conn) : + RelayServer(parent), + m_serverFileDescriptor(serverFileDescriptor), + m_serviceConn(conn) { - m_serverFileDescriptor = serverFileDescriptor; if (m_serverFileDescriptor > 0) fcntl(m_serverFileDescriptor, F_SETFL, fcntl(m_serverFileDescriptor, F_GETFL, 0) | O_NONBLOCK); } -void SingleRelayServer::newRelayConnection() +void GdbRelayServer::newRelayConnection() { QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections() ? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection(); @@ -312,13 +332,13 @@ void SingleRelayServer::newRelayConnection() return; } if (clientSocket) { - Relayer *newConnection = new Relayer(this, clientSocket); + Relayer *newConnection = new ServiceConnectionRelayer(this, clientSocket, m_serviceConn); m_connections.append(newConnection); newConnection->startRelay(m_serverFileDescriptor); } } -GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort, +QmlRelayServer::QmlRelayServer(IosTool *parent, int remotePort, Ios::DeviceSession *deviceSession) : RelayServer(parent), m_remotePort(remotePort), @@ -328,7 +348,7 @@ GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort, } -void GenericRelayServer::newRelayConnection() +void QmlRelayServer::newRelayConnection() { QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections() ? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection(); @@ -339,4 +359,42 @@ void GenericRelayServer::newRelayConnection() newConnection->tryRemoteConnect(); } } + +ServiceConnectionRelayer::ServiceConnectionRelayer(RelayServer *parent, QTcpSocket *clientSocket, + ServiceConnRef conn) + : Relayer(parent, clientSocket), + m_serviceConn(conn) +{ + +} + +int ServiceConnectionRelayer::readData(int socketFd, void *buf, size_t size) +{ + Q_UNUSED(socketFd) + if (!buf || !m_serviceConn) + return 0; + MobileDeviceLib &mlib = MobileDeviceLib::instance(); + return mlib.serviceConnectionReceive(m_serviceConn, buf, size); +} + +int ServiceConnectionRelayer::writeData(int socketFd, const void *data, size_t size) +{ + Q_UNUSED(socketFd) + if (!data || !m_serviceConn) + return 0; + MobileDeviceLib &mLib = MobileDeviceLib::instance(); + return mLib.serviceConnectionSend(m_serviceConn, data, size); +} + +void ServiceConnectionRelayer::closeConnection() +{ + Relayer::closeConnection(); + if (m_serviceConn) { + MobileDeviceLib &mLib = MobileDeviceLib::instance(); + mLib.serviceConnectionInvalidate(m_serviceConn); + m_serviceConn = nullptr; + } + +} + } diff --git a/src/tools/iostool/relayserver.h b/src/tools/iostool/relayserver.h index d41932f47d2..0b01b7271e1 100644 --- a/src/tools/iostool/relayserver.h +++ b/src/tools/iostool/relayserver.h @@ -38,7 +38,7 @@ namespace Ios { class DeviceSession; class IosTool; class RelayServer; -class GenericRelayServer; +class QmlRelayServer; class Relayer: public QObject { @@ -55,11 +55,29 @@ public: void handleClientHasError(QAbstractSocket::SocketError error); protected: + virtual int readData(int socketFd, void* buf, size_t size); + virtual int writeData(int socketFd, const void *data, size_t size); + virtual void closeConnection(); + IosTool *iosTool() const; RelayServer *server() const; ServiceSocket m_serverFileDescriptor; - QTcpSocket *m_clientSocket; - QSocketNotifier *m_serverNotifier; + QTcpSocket *m_clientSocket = nullptr; + QSocketNotifier *m_serverNotifier = nullptr; +}; + +class ServiceConnectionRelayer : public Relayer +{ +public: + ServiceConnectionRelayer(RelayServer *parent, QTcpSocket *clientSocket, ServiceConnRef conn); + +protected: + int readData(int socketFd, void* buf, size_t size) override; + int writeData(int socketFd, const void *data, size_t size) override; + void closeConnection() override; + +private: + ServiceConnRef m_serviceConn; }; class RemotePortRelayer: public Relayer @@ -69,11 +87,11 @@ class RemotePortRelayer: public Relayer public: static const int reconnectMsecDelay = 500; static const int maxReconnectAttempts = 2*60*5; // 5 min - RemotePortRelayer(GenericRelayServer *parent, QTcpSocket *clientSocket); + RemotePortRelayer(QmlRelayServer *parent, QTcpSocket *clientSocket); void tryRemoteConnect(); signals: - void didConnect(GenericRelayServer *serv); + void didConnect(QmlRelayServer *serv); private: QTimer m_remoteConnectTimer; @@ -103,27 +121,28 @@ protected: QList m_connections; }; -class SingleRelayServer: public RelayServer +class GdbRelayServer: public RelayServer { Q_OBJECT public: - SingleRelayServer(IosTool *parent, int serverFileDescriptor); + GdbRelayServer(IosTool *parent, int serverFileDescriptor, ServiceConnRef conn); protected: void newRelayConnection() override; private: - int m_serverFileDescriptor; + int m_serverFileDescriptor = -1; + ServiceConnRef m_serviceConn = nullptr; }; -class GenericRelayServer: public RelayServer +class QmlRelayServer: public RelayServer { Q_OBJECT public: - GenericRelayServer(IosTool *parent, int remotePort, - Ios::DeviceSession *deviceSession); + QmlRelayServer(IosTool *parent, int remotePort, + Ios::DeviceSession *deviceSession); protected: void newRelayConnection() override;