diff --git a/tests/manual/trk/adapter.cpp b/tests/manual/trk/adapter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c14878b3b12ef48f99974e16b23f12f12a752087 --- /dev/null +++ b/tests/manual/trk/adapter.cpp @@ -0,0 +1,289 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include <QtCore/QCoreApplication> +#include <QtCore/QTimer> + +#include <QtNetwork/QTcpServer> +#include <QtNetwork/QTcpSocket> +#include <QtNetwork/QLocalServer> +#include <QtNetwork/QLocalSocket> + +#ifdef Q_OS_UNIX + +#include <signal.h> + +void signalHandler(int) +{ + qApp->exit(1); +} + +#endif + + +class Adapter : public QObject +{ + Q_OBJECT + +public: + Adapter(); + ~Adapter(); + void setGdbServerName(const QString &name); + void setTrkServerName(const QString &name) { m_trkServerName = name; } + void startServer(); + +public slots: + void handleGdbConnection(); + void readFromGdb(); + void readFromTrk(); + +private: + void handleGdbResponse(const QByteArray &ba); + void writeToGdb(const QByteArray &msg); + void writeAckToGdb(); + void logMessage(const QString &msg); + + QLocalSocket *m_trkClient; + QTcpServer *m_gdbServer; + QTcpSocket *m_gdbConnection; + QString m_trkServerName; + QString m_gdbServerName; + quint16 m_gdbServerPort; + QByteArray m_gdbReadBuffer; + QByteArray m_trkReadBuffer; +}; + +Adapter::Adapter() +{ + m_trkClient = new QLocalSocket(this); + m_gdbServer = new QTcpServer(this); + m_gdbConnection = 0; +} + +Adapter::~Adapter() +{ + m_gdbServer->close(); + logMessage("Shutting down"); +} + +void Adapter::setGdbServerName(const QString &name) +{ + int pos = name.indexOf(':'); + if (pos == -1) { + m_gdbServerPort = 0; + m_gdbServerName = name; + } else { + m_gdbServerPort = name.mid(pos + 1).toInt(); + m_gdbServerName = name.left(pos); + } +} + +void Adapter::startServer() +{ + if (!m_gdbServer->listen(QHostAddress(m_gdbServerName), m_gdbServerPort)) { + logMessage(QString("Unable to start the gdb server at %1:%2: %3.") + .arg(m_gdbServerName).arg(m_gdbServerPort) + .arg(m_gdbServer->errorString())); + return; + } + + logMessage(QString("Gdb server runnung on port %1. Run the Gdb Client now.") + .arg(m_gdbServer->serverPort())); + + connect(m_gdbServer, SIGNAL(newConnection()), this, SLOT(handleGdbConnection())); +} + +void Adapter::logMessage(const QString &msg) +{ + qDebug() << "ADAPTER: " << qPrintable(msg); +} + +void Adapter::handleGdbConnection() +{ + logMessage("HANDLING GDB CONNECTION"); + + m_gdbConnection = m_gdbServer->nextPendingConnection(); + connect(m_gdbConnection, SIGNAL(disconnected()), + m_gdbConnection, SLOT(deleteLater())); + connect(m_gdbConnection, SIGNAL(readyRead()), + this, SLOT(readFromGdb())); +} + +void Adapter::readFromGdb() +{ + QByteArray packet = m_gdbConnection->readAll(); + m_gdbReadBuffer.append(packet); + + logMessage("gdb: -> " + packet); + if (packet != m_gdbReadBuffer) + logMessage("buffer: " + m_gdbReadBuffer); + + QByteArray &ba = m_gdbReadBuffer; + while (ba.size()) { + char code = ba.at(0); + ba = ba.mid(1); + + if (code == '+') { + logMessage("ACK"); + continue; + } + + if (code == '-') { + logMessage("NAK: Retransmission requested"); + continue; + } + + if (code != '$') { + logMessage("Broken package (2) " + ba); + continue; + } + + int pos = ba.indexOf('#'); + if (pos == -1) { + logMessage("Invalid checksum format in " + ba); + continue; + } + + bool ok = false; + uint checkSum = ba.mid(pos + 1, 2).toInt(&ok, 16); + if (!ok) { + logMessage("Invalid checksum format 2 in " + ba); + return; + } + + logMessage(QString("Packet checksum: %1").arg(checkSum)); + uint sum = 0; + for (int i = 0; i < pos; ++i) + sum += ba.at(i); + + if (sum % 256 != checkSum) { + logMessage(QString("Packet checksum wrong: %1 %2 in " + ba) + .arg(checkSum).arg(sum % 256)); + } + + QByteArray response = ba.left(pos); + ba = ba.mid(pos + 3); + handleGdbResponse(response); + } +} + +void Adapter::writeAckToGdb() +{ + QByteArray packet = "+"; + logMessage("gdb: <- " + packet); + m_gdbConnection->write(packet); +} + +void Adapter::writeToGdb(const QByteArray &msg) +{ + uint sum = 0; + for (int i = 0; i != msg.size(); ++i) + sum += msg.at(i); + QByteArray checkSum = QByteArray::number(sum % 256, 16); + //logMessage(QString("Packet checksum: %1").arg(sum)); + + QByteArray packet; + packet.append("+$"); + packet.append(msg); + packet.append('#'); + if (checkSum.size() < 2) + packet.append('0'); + packet.append(checkSum); + logMessage("gdb: <- " + packet); + m_gdbConnection->write(packet); +} + +void Adapter::handleGdbResponse(const QByteArray &response) +{ + // http://sourceware.org/gdb/current/onlinedocs/gdb_34.html + if (response == "qSupported") { + //$qSupported#37 + logMessage("Handling 'qSupported'"); + writeAckToGdb(); + writeToGdb(QByteArray()); + } + + else if (response.startsWith("Hc")) { + // Set thread for subsequent operations (`m', `M', `g', `G', et.al.). + // for step and continue operations + writeAckToGdb(); + } + + else if (response.startsWith("Hg")) { + // Set thread for subsequent operations (`m', `M', `g', `G', et.al.). + // for 'other operations + //$Hg0#df + writeAckToGdb(); + } + + + else if (response.startsWith("?")) { + // Indicate the reason the target halted. + // The reply is the same as for step and continue. + + //$?#3f + //$Hc-1#09 + //$qC#b4 + //$qAttached#8f + //$qOffsets#4b + //$qOffsets#4b + + else { + logMessage("FIXME unknown" + response); + } +} + +void Adapter::readFromTrk() +{ + //QByteArray ba = m_gdbConnection->readAll(); + //logMessage("Read from gdb: " + ba); +} + +int main(int argc, char *argv[]) +{ + if (argc < 3) { + qDebug() << "Usage: " << argv[0] << " <trkservername> <gdbserverport>"; + return 1; + } + +#ifdef Q_OS_UNIX + signal(SIGUSR1, signalHandler); +#endif + + QCoreApplication app(argc, argv); + + Adapter adapter; + adapter.setTrkServerName(argv[1]); + adapter.setGdbServerName(argv[2]); + adapter.startServer(); + + return app.exec(); +} + +#include "adapter.moc" diff --git a/tests/manual/trk/adapter.pro b/tests/manual/trk/adapter.pro new file mode 100644 index 0000000000000000000000000000000000000000..fb8cadede6ac464796aac00b0d853c6a5d999f5e --- /dev/null +++ b/tests/manual/trk/adapter.pro @@ -0,0 +1,6 @@ + +TEMPLATE = app + +QT = core network + +SOURCES += adapter.cpp diff --git a/tests/manual/trk/run.sh b/tests/manual/trk/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..66d5dc97d5c528630299556911c3a90faa832686 --- /dev/null +++ b/tests/manual/trk/run.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +make || exit 1 + +killall -s USR1 adapter trkserver > /dev/null 2>&1 +killall adapter trkserver > /dev/null 2>&1 + +trkservername="TRKSERVER-2"; +gdbserverip=127.0.0.1 +gdbserverport=2225 + +./trkserver ${trkservername} & +trkserverpid=$! + +sleep 1 + +./adapter ${trkservername} ${gdbserverip}:${gdbserverport} & +adapterpid=$! + +echo " +file filebrowseapp.sym +target remote ${gdbserverip}:${gdbserverport} +quit +" > gdb.txt + +./arm-gdb -x gdb.txt + +#sleep 4 + +kill -s USR1 ${adapterpid} +kill -s USR1 ${trkserverpid} + +echo + +#killall arm-gdb diff --git a/tests/manual/trk/trk.pro b/tests/manual/trk/trk.pro new file mode 100644 index 0000000000000000000000000000000000000000..7d5f33e4eabf7502a6625ddb12fdb2f2a5bfbbc6 --- /dev/null +++ b/tests/manual/trk/trk.pro @@ -0,0 +1,7 @@ + +TEMPLATE = subdirs + +SUBDIRS = trkserver adapter + +trkserver.file = trkserver.pro +adapter.file = adapter.pro diff --git a/tests/manual/trk/trkserver.cpp b/tests/manual/trk/trkserver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67a0fc5476aa1e5d5c48e6e25fd7da4c6492212c --- /dev/null +++ b/tests/manual/trk/trkserver.cpp @@ -0,0 +1,136 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include <QtCore/QCoreApplication> +#include <QtCore/QFile> + +#include <QtNetwork/QLocalServer> +#include <QtNetwork/QLocalSocket> + + +#ifdef Q_OS_UNIX + +#include <signal.h> + +void signalHandler(int) +{ + qApp->exit(1); +} + +#endif + + +class TrkServer : public QObject +{ + Q_OBJECT + +public: + TrkServer(const QString &serverName); + ~TrkServer(); + +private slots: + void handleConnection(); + +private: + void logMessage(const QString &msg); + + QList<QByteArray> m_data; + QLocalServer *m_server; + int m_lastSent; +}; + +TrkServer::TrkServer(const QString &serverName) +{ + QFile file("dump.pro"); + m_data = file.readAll().split('\n'); + logMessage(QString("Read %1 lines of data").arg(m_data.size())); + + m_server = new QLocalServer(this); + m_lastSent = 0; + if (!m_server->listen(serverName)) { + logMessage(QString("Error: Unable to start the TRK server %1: %2.") + .arg(serverName).arg(m_server->errorString())); + return; + } + + logMessage("The TRK server is running. Run the adapter now."); + connect(m_server, SIGNAL(newConnection()), this, SLOT(handleConnection())); +} + +TrkServer::~TrkServer() +{ + logMessage("Shutting down"); + m_server->close(); +} + +void TrkServer::logMessage(const QString &msg) +{ + qDebug() << "TRKSERV: " << qPrintable(msg); +} + +void TrkServer::handleConnection() +{ + QByteArray block; + + QByteArray msg = m_data[m_lastSent ++]; + + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_0); + out << (quint16)0; + out << m_data; + out.device()->seek(0); + out << (quint16)(block.size() - sizeof(quint16)); + + QLocalSocket *clientConnection = m_server->nextPendingConnection(); + connect(clientConnection, SIGNAL(disconnected()), + clientConnection, SLOT(deleteLater())); + + clientConnection->write(block); + clientConnection->flush(); + //clientConnection->disconnectFromHost(); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + qDebug() << "Usage: " << argv[0] << " <trkservername>"; + return 1; + } + +#ifdef Q_OS_UNIX + signal(SIGUSR1, signalHandler); +#endif + + QCoreApplication app(argc, argv); + QString serverName = argv[1]; + TrkServer server(serverName); + return app.exec(); +} + +#include "trkserver.moc" diff --git a/tests/manual/trk/trkserver.pro b/tests/manual/trk/trkserver.pro new file mode 100644 index 0000000000000000000000000000000000000000..e782ab2d230f222016da35bacb31c10a0a9b0d54 --- /dev/null +++ b/tests/manual/trk/trkserver.pro @@ -0,0 +1,6 @@ + +TEMPLATE = app + +QT = core network + +SOURCES += trkserver.cpp