diff --git a/tests/manual/trk/README b/tests/manual/trk/README deleted file mode 100644 index f8b12329459d0ee12767e77b221dfb8af2045773..0000000000000000000000000000000000000000 --- a/tests/manual/trk/README +++ /dev/null @@ -1,47 +0,0 @@ -Run ./run.sh in one terminal. -Run ./welsh-gdb or ./symbianelf-gdb in a second terminal. -Note that welsh-gdb does not handle 'set remote noack-packet on' - -The following items "work": - -- "stop" at E32Main -- manual relocation on the gdb side using - add-symbol-file filebrowseapp.sym 0x786A4000 -- disassembly at stopped location -- p <functionname> -- p $pc -- one level of 'bt' - -To do: - -- figure out why the result of the qOffsets query is not honoured - _or_ how to have gdb doing the relocation automatically -- setting breakpoints by filename:line -- signaling of stopped/single step end. SIGTRAP? SIGSTOP? -- run it against the red brick - - -Setting up TRK on Linux with Bluetooth - -Enter the following commands in a terminal (all as root, adjust device -permissions as required to work as user): - - -sdptool add SP # announce Serial Port Profile via Service Discovery Protocol -sudo mknod --mode=666 /dev/rfcomm0 c 216 0 # Creates a Bluetooth Serial Device - -rfcomm listen /dev/rfcomm0 1 $PWD/trklauncher -v -f {} - -#This should print the Trk/CPU versions. The option -f tells the command to -#disable the serial frames message encapsulation for BlueTooth. - -#The same with the debug adapter: - -rfcomm listen /dev/rfcomm0 1 $PWD/run.pl -af -av -w {} -rfcomm listen /dev/rfcomm0 1 $PWD/runner -af -av -w {} - -#Important options: -w wait for adapter, -af omit serial frame. - -cp /data5/dev/debugger/symbian-codesourcery-welsh/cs-gdb/build/gdb/gdb cs-gdb -cp /data5/dev/trk/filebrowseapp* . -cp /home/f*/dev/creator/tests/manual/trk/*.bin . diff --git a/tests/manual/trk/run.pl b/tests/manual/trk/run.pl deleted file mode 100755 index 2a3993fe5ffe9b1a7a477662cfcc6ed1c8f8ef75..0000000000000000000000000000000000000000 --- a/tests/manual/trk/run.pl +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use English; # gives us $OSNAME -use File::Temp; -use File::Spec; -use Cwd; - -my @ADAPTER_OPTIONS = (); -my @TRKSERVEROPTIONS = (); -my $DUMP_POSTFIX ='.bin'; -my $ENDIANESS ='little'; - -my $isUnix = $OSNAME eq 'linux' ? 1 : 0; -my $MAKE= $isUnix ? 'make' : 'nmake'; -my $trkservername; -my $runTrkServer = 1; -my $waitAdapter = 0; - -my $usage=<<EOF; -Usage: run.pl -w -av -aq -au -tv -tq -l [COM] -Options: - -av Adapter verbose - -aq Adapter quiet - -au Adapter turn off buffered memory read - -af Adapter turn off serial frame - -w Wait for termination of Adapter (Bluetooth) - -tv TrkServer verbose - -tq TrkServer quiet - - trkserver simulator will be run unless COM is specified - -Bluetooth: - rfcomm listen /dev/rfcomm0 1 \$PWD/run.pl -av -af -w {} - -EOF - -# ------- Parse arguments -my $argCount = scalar(@ARGV); -for (my $i = 0; $i < $argCount; $i++) { - my $a = $ARGV[$i]; - if ($a =~ /^-/) { - if ($a eq '-av') { - push(@ADAPTER_OPTIONS, '-v'); - } elsif ($a eq '-aq') { - push(@ADAPTER_OPTIONS, '-q'); - } elsif ($a eq '-af') { - push(@ADAPTER_OPTIONS, '-f'); - } elsif ($a eq '-au') { - push(@ADAPTER_OPTIONS, '-u'); - } elsif ($a eq '-w') { - $waitAdapter = 1; - } elsif ($a eq '-tv') { - push(@TRKSERVEROPTIONS, '-v'); - } elsif ($a eq '-tq') { - push(@TRKSERVEROPTIONS, '-q'); - } elsif ($a eq '-h') { - print $usage; - exit(0); - } else { - print $usage; - exit(1); - } - } else { - $trkservername = $a; - $runTrkServer = 0; - } -} - -# ------- Ensure build is up to date -print "### Building\n"; -system($MAKE); -die('Make failed: ' . $!) unless $? == 0; - -if ($isUnix != 0) { - system('killall', '-s', 'USR1', 'adapter', 'trkserver'); - system('killall', 'adapter', 'trkserver'); -} - -my $userid=$>; -$trkservername = ('TRKSERVER-' . $userid) unless defined $trkservername; -my $gdbserverip= '127.0.0.1'; -my $gdbserverport= 2222 + $userid; - -print "Serverport: $gdbserverport\n" ; - -system('fuser', '-n', 'tcp', '-k', $gdbserverport) if ($isUnix); - -# Who writes that? -my $tempFile = File::Spec->catfile(File::Temp::tempdir(), $trkservername); -unlink ($tempFile) if -f $tempFile; - -# ------- Launch trkserver -if ($runTrkServer) { - my $MEMORYDUMP='TrkDump-78-6a-40-00' . $DUMP_POSTFIX; - my @ADDITIONAL_DUMPS=('0x00402000' . $DUMP_POSTFIX, '0x786a4000' . $DUMP_POSTFIX, '0x00600000' . $DUMP_POSTFIX); - - my @TRKSERVER_ARGS; - if ($isUnix) { - push(@TRKSERVER_ARGS, File::Spec->catfile(File::Spec->curdir(), 'trkserver')); - } else { - push(@TRKSERVER_ARGS, 'cmd.exe', '/c', 'start', File::Spec->catfile(File::Spec->curdir(), 'debug', 'trkserver.exe')); - } - - push(@TRKSERVER_ARGS, @TRKSERVEROPTIONS, $trkservername, $MEMORYDUMP, @ADDITIONAL_DUMPS); - - print '### Executing: ', join(' ', @TRKSERVER_ARGS), "\n"; - my $trkserverpid = fork(); - if ($trkserverpid == 0) { - exec(@TRKSERVER_ARGS); - exit(0); - } - - push(@ADAPTER_OPTIONS, '-s'); - - sleep(1); -} - -# ------- Launch adapter -my @ADAPTER_ARGS; -if ($isUnix) { - push(@ADAPTER_ARGS, File::Spec->catfile(File::Spec->curdir(), 'adapter')); -} else { - push(@ADAPTER_ARGS, 'cmd.exe', '/c', 'start', File::Spec->catfile(File::Spec->curdir(), 'debug', 'adapter.exe')); -} - -push(@ADAPTER_ARGS, @ADAPTER_OPTIONS, $trkservername, $gdbserverip . ':' . $gdbserverport); -print '### Executing: ', join(' ', @ADAPTER_ARGS), "\n"; -my $adapterpid=fork(); -if ($adapterpid == 0) { - exec(@ADAPTER_ARGS); - exit(0); -} -die ('Unable to launch adapter') if $adapterpid == -1; - -if ($waitAdapter > 0) { - print '### kill -USR1 ',$adapterpid,"\n"; - waitpid($adapterpid, 0); -} -# ------- Write out .gdbinit -my $gdbInit = <<EOF; -# This is generated. Changes will be lost. -#set remote noack-packet on -set confirm off -set endian $ENDIANESS -#set debug remote 1 -#target remote $gdbserverip:$gdbserverport -target extended-remote $gdbserverip:$gdbserverport -#file filebrowseapp.sym -add-symbol-file filebrowseapp.sym 0x786A4000 -symbol-file filebrowseapp.sym -print E32Main -break E32Main -#continue -#info files -#file filebrowseapp.sym -readnow -#add-symbol-file filebrowseapp.sym 0x786A4000 -EOF - -my $gdbInitFile = '.gdbinit'; -print '### Writing: ',$gdbInitFile, "\n"; -open (GDB_INIT, '>' . $gdbInitFile) or die ('Cannot write to ' . $gdbInitFile . ' ' . $!); -print GDB_INIT $gdbInit; -close( GDB_INIT); diff --git a/tests/manual/trk/runner.cpp b/tests/manual/trk/runner.cpp deleted file mode 100755 index 4216b696591eb2cc666697f796fad2b89551fa20..0000000000000000000000000000000000000000 --- a/tests/manual/trk/runner.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 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://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "trkgdbadapter.h" -#include "trkoptions.h" - -#include <QtCore/QDebug> - -#include <QtGui/QAction> -#include <QtGui/QApplication> -#include <QtGui/QMainWindow> -#include <QtGui/QKeyEvent> -#include <QtGui/QTextBlock> -#include <QtGui/QTextEdit> -#include <QtGui/QToolBar> -#include <QtCore/QSharedPointer> -#include <QtCore/QTimer> -#include <QtCore/QDir> - -/////////////////////////////////////////////////////////////////////// -// -// RunnerGui -// -/////////////////////////////////////////////////////////////////////// - -class TextEdit : public QTextEdit -{ - Q_OBJECT - -signals: - void executeCommand(QString); - -public slots: - void handleOutput(const QString &str0) - { - QString str = str0; - str.replace("\\t", QString(QChar(0x09))); - str.replace("\\n", QString("\n")); - append(str); - - QTextCursor tc = textCursor(); - tc.movePosition(QTextCursor::End); - setTextCursor(tc); - /* - int pos1 = str.indexOf("#"); - int pos2 = str.indexOf(")", pos1); - if (pos1 != -1 && pos2 != -1) - str = str.left(pos1) + "<b>" + str.mid(pos1, pos2 - pos1 + 1) - + "</b> " + str.mid(pos2 + 1); - insertHtml(str + "\n"); - */ - setCurrentCharFormat(QTextCharFormat()); - ensureCursorVisible(); - } - - void keyPressEvent(QKeyEvent *ev) - { - if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Return) - emit executeCommand(textCursor().block().text()); - else - QTextEdit::keyPressEvent(ev); - } -}; - -/////////////////////////////////////////////////////////////////////// -// -// RunnerGui -// -/////////////////////////////////////////////////////////////////////// - -using namespace Debugger::Internal; - -class RunnerGui : public QMainWindow -{ - Q_OBJECT - -public: - RunnerGui(TrkGdbAdapter *adapter); - -private slots: - void executeStepICommand() { executeCommand("-exec-step-instruction"); } - void executeStepCommand() { executeCommand("-exec-step"); } - void executeNextICommand() { executeCommand("-exec-next-instruction"); } - void executeNextCommand() { executeCommand("-exec-next"); } - void executeContinueCommand() { executeCommand("-exec-continue"); } - void executeDisassICommand() { executeCommand("disass $pc $pc+4"); } - void executeStopCommand() { executeCommand("I"); } - - void handleReadyReadStandardError(); - void handleReadyReadStandardOutput(); - - void run(); - void started(); - -private: - void executeCommand(const QString &cmd) { m_adapter->executeCommand(cmd); } - void connectAction(QAction *&, QString name, const char *slot); - - TrkGdbAdapter *m_adapter; - TextEdit m_textEdit; - QToolBar m_toolBar; - QAction *m_stopAction; - QAction *m_stepIAction; - QAction *m_stepAction; - QAction *m_nextIAction; - QAction *m_nextAction; - QAction *m_disassIAction; - QAction *m_continueAction; -}; - -RunnerGui::RunnerGui(TrkGdbAdapter *adapter) - : m_adapter(adapter) -{ - resize(1200, 1000); - setCentralWidget(&m_textEdit); - - addToolBar(&m_toolBar); - - connectAction(m_stepIAction, "Step Inst", SLOT(executeStepICommand())); - connectAction(m_stepAction, "Step", SLOT(executeStepCommand())); - connectAction(m_nextIAction, "Next Inst", SLOT(executeNextICommand())); - connectAction(m_nextAction, "Next", SLOT(executeNextCommand())); - connectAction(m_disassIAction, "Disass Inst", SLOT(executeDisassICommand())); - connectAction(m_continueAction, "Continue", SLOT(executeContinueCommand())); - connectAction(m_stopAction, "Stop", SLOT(executeStopCommand())); - - connect(adapter, SIGNAL(output(QString)), - &m_textEdit, SLOT(handleOutput(QString))); - connect(&m_textEdit, SIGNAL(executeCommand(QString)), - m_adapter, SLOT(executeCommand(QString))); - - connect(adapter, SIGNAL(readyReadStandardError()), - this, SLOT(handleReadyReadStandardError())); - connect(adapter, SIGNAL(readyReadStandardOutput()), - this, SLOT(handleReadyReadStandardOutput())); - connect(adapter, SIGNAL(started()), - this, SLOT(started())); -} - -void RunnerGui::connectAction(QAction *&action, QString name, const char *slot) -{ - action = new QAction(this); - action->setText(name); - m_toolBar.addAction(action); - connect(action, SIGNAL(triggered()), this, slot); -} - -void RunnerGui::handleReadyReadStandardError() -{ - QByteArray ba = m_adapter->readAllStandardError(); - qDebug() << ba; - m_textEdit.handleOutput(ba); -} - -void RunnerGui::handleReadyReadStandardOutput() -{ - QByteArray ba = m_adapter->readAllStandardOutput(); - qDebug() << ba; - m_textEdit.handleOutput("-> GDB: " + ba); -} - -void RunnerGui::run() -{ - m_adapter->run(); -} - -void RunnerGui::started() -{ - qDebug() << "\nSTARTED\n"; - executeCommand("set confirm off"); // confirm potentially dangerous operations? - executeCommand("set endian little"); - executeCommand("set remotebreak on"); - executeCommand("set breakpoint pending on"); - executeCommand("set trust-readonly-sections on"); - //executeCommand("mem 0 ~0ll rw 8 cache"); - - // FIXME: "remote noack" does not seem to be supported on cs-gdb? - //executeCommand("set remote noack-packet"); - - // FIXME: creates a lot of noise a la '&"putpkt: Junk: Ack " &' - // even though the communication seems sane - //executeCommand("set debug remote 1"); // creates l - - executeCommand("add-symbol-file filebrowseapp.sym " - + trk::hexxNumber(m_adapter->session().codeseg)); - executeCommand("symbol-file filebrowseapp.sym"); - - //executeCommand("info address CFileBrowseAppUi::HandleCommandL", - // GdbCB(handleInfoMainAddress)); - - executeCommand("-break-insert filebrowseappui.cpp:39"); - executeCommand("target remote " + m_adapter->gdbServerName()); - executeCommand("-exec-continue"); -} - -/////////////////////////////////////////////////////////////////////// -// -// main -// -/////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QSharedPointer<TrkOptions> options(new TrkOptions); - options->gdb = QDir::currentPath() + QLatin1String("/cs-gdb"); - TrkGdbAdapter adapter(options); - adapter.setVerbose(2); - RunnerGui gui(&adapter); - gui.show(); - QTimer::singleShot(0, &gui, SLOT(run())); - return app.exec(); -} - -#include "runner.moc" diff --git a/tests/manual/trk/runner.pro b/tests/manual/trk/runner.pro deleted file mode 100644 index 91a27d01c021c8de6d09d575927dbf08ff4ce57e..0000000000000000000000000000000000000000 --- a/tests/manual/trk/runner.pro +++ /dev/null @@ -1,24 +0,0 @@ - -TEMPLATE = app - -TRK_DIR=../../../src/shared/trk -include($$TRK_DIR/trk.pri) -DEBUGGERHOME = ../../../src/plugins/debugger/gdb -INCLUDEPATH *= $$TRK_DIR -INCLUDEPATH *= $$DEBUGGERHOME - -DEFINES += STANDALONE_RUNNER - -QT += network - -win32:CONFIG+=console - -HEADERS += \ - $$DEBUGGERHOME/abstractgdbadapter.h \ - $$DEBUGGERHOME/trkoptions.h \ - $$DEBUGGERHOME/trkgdbadapter.h \ - -SOURCES += \ - $$DEBUGGERHOME/trkgdbadapter.cpp \ - $$DEBUGGERHOME/trkoptions.cpp \ - $$PWD/runner.cpp \ diff --git a/tests/manual/trk/swapendian.cpp b/tests/manual/trk/swapendian.cpp deleted file mode 100644 index 4b6dd5cb1c7c30e52ca14c685e270a79010bfdf5..0000000000000000000000000000000000000000 --- a/tests/manual/trk/swapendian.cpp +++ /dev/null @@ -1,23 +0,0 @@ - - -#include <QtCore> - -int main(int argc, char *argv[]) -{ - QFile file1(argv[1]); - file1.open(QIODevice::ReadOnly); - - QByteArray ba = file1.readAll(); - file1.close(); - - for (int i = 0; i < ba.size(); i += 4) { - char c = ba[i]; ba[i] = ba[i + 3]; ba[i + 3] = c; - c = ba[i + 1]; ba[i + 1] = ba[i + 2]; ba[i + 2] = c; - } - - QFile file2(argv[2]); - file2.open(QIODevice::WriteOnly); - file2.write(ba); - file2.close(); -} - diff --git a/tests/manual/trk/swapendian.pro b/tests/manual/trk/swapendian.pro deleted file mode 100644 index 2290f2b5331239298335fd4d4c29c3a5e26646db..0000000000000000000000000000000000000000 --- a/tests/manual/trk/swapendian.pro +++ /dev/null @@ -1,9 +0,0 @@ - -TEMPLATE = app -MAKEFILE = Makefile.swapendian -QT = core - -HEADERS += \ - -SOURCES += \ - swapendian.cpp diff --git a/tests/manual/trk/trk.pro b/tests/manual/trk/trk.pro deleted file mode 100644 index c859c905c2f408d0dad2ee077a74a9678035a08b..0000000000000000000000000000000000000000 --- a/tests/manual/trk/trk.pro +++ /dev/null @@ -1,7 +0,0 @@ - -TEMPLATE = subdirs - -SUBDIRS = trkserver swapendian runner.pro - -trkserver.file = trkserver.pro -swapendian.file = swapendian.pro diff --git a/tests/manual/trk/trklauncher.pri b/tests/manual/trk/trklauncher.pri deleted file mode 100644 index a9abc53895de8e242cffb2232597c1cbb736eabc..0000000000000000000000000000000000000000 --- a/tests/manual/trk/trklauncher.pri +++ /dev/null @@ -1,15 +0,0 @@ -DEFINES += DEBUG_TRK=0 -TRK_DIR = ../../../src/plugins/debugger/gdb - -INCLUDEPATH *= $$PWD $$TRK_DIR - -SOURCES += \ - $$TRK_DIR/trkutils.cpp \ - $$PWD/trkdevice.cpp \ - $$PWD/launcher.cpp \ - -HEADERS += \ - $$TRK_DIR/trkutils.h \ - $$TRK_DIR/callback.h \ - $$PWD/trkdevice.h \ - $$PWD/launcher.h diff --git a/tests/manual/trk/trkolddevice.cpp b/tests/manual/trk/trkolddevice.cpp deleted file mode 100644 index 0be0c9511f66ce5be5eafb1cc4dfd6e3b1f01f0e..0000000000000000000000000000000000000000 --- a/tests/manual/trk/trkolddevice.cpp +++ /dev/null @@ -1,690 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 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://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "trkolddevice.h" -#include "trkutils.h" - -#include <QtCore/QString> -#include <QtCore/QDebug> -#include <QtCore/QQueue> -#include <QtCore/QHash> -#include <QtCore/QMap> -#include <QtCore/QSharedPointer> - -#ifdef Q_OS_WIN -# include <windows.h> -#else -# include <QtCore/QFile> - -# include <stdio.h> -# include <sys/ioctl.h> -# include <termios.h> -# include <errno.h> -# include <string.h> -# include <unistd.h> -#endif - -enum { TimerInterval = 100 }; - -#ifdef Q_OS_WIN - -// Format windows error from GetLastError() value: TODO: Use the one provided by the utisl lib. -static QString winErrorMessage(unsigned long error) -{ - QString rc = QString::fromLatin1("#%1: ").arg(error); - ushort *lpMsgBuf; - - const int len = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); - if (len) { - rc = QString::fromUtf16(lpMsgBuf, len); - LocalFree(lpMsgBuf); - } else { - rc += QString::fromLatin1("<unknown error>"); - } - return rc; -} - -// Non-blocking replacement for win-api ReadFile function -static BOOL WINAPI TryReadFile(HANDLE hFile, - LPVOID lpBuffer, - DWORD nNumberOfBytesToRead, - LPDWORD lpNumberOfBytesRead, - LPOVERLAPPED lpOverlapped) -{ - COMSTAT comStat; - if (!ClearCommError(hFile, NULL, &comStat)){ - qDebug()<<("ClearCommError() failed"); - return FALSE; - } - if (comStat.cbInQue == 0) { - *lpNumberOfBytesRead = 0; - return FALSE; - } - return ReadFile(hFile, - lpBuffer, - qMin(comStat.cbInQue, nNumberOfBytesToRead), - lpNumberOfBytesRead, - lpOverlapped); -} -#endif - -namespace trkold { - -struct TrkDevicePrivate { - TrkDevicePrivate(); -#ifdef Q_OS_WIN - HANDLE hdevice; -#else - QFile file; -#endif - - QByteArray trkReadBuffer; - bool trkWriteBusy; - int timerId; - bool serialFrame; - bool verbose; - QString errorString; -}; - -TrkDevicePrivate::TrkDevicePrivate() : -#ifdef Q_OS_WIN - hdevice(INVALID_HANDLE_VALUE), -#endif - trkWriteBusy(false), - timerId(-1), - serialFrame(true), - verbose(false) -{ - -} - -TrkDevice::TrkDevice(QObject *parent) : - QObject(parent), - d(new TrkDevicePrivate) -{ -} - -bool TrkDevice::open(const QString &port, QString *errorMessage) -{ - close(); -#ifdef Q_OS_WIN - d->hdevice = CreateFile(port.toStdWString().c_str(), - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (INVALID_HANDLE_VALUE == d->hdevice) { - *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port, winErrorMessage(GetLastError())); - return false; - } - d->timerId = startTimer(TimerInterval); - return true; -#else - d->file.setFileName(port); - if (!d->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->file.errorString()); - return false; - } - - struct termios termInfo; - if (tcgetattr(d->file.handle(), &termInfo) < 0) { - *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); - return false; - } - // Turn off terminal echo as not get messages back, among other things - termInfo.c_cflag|=CREAD|CLOCAL; - termInfo.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); - termInfo.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); - termInfo.c_oflag&=(~OPOST); - termInfo.c_cc[VMIN]=0; - termInfo.c_cc[VINTR] = _POSIX_VDISABLE; - termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; - termInfo.c_cc[VSTART] = _POSIX_VDISABLE; - termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; - termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; - if (tcsetattr(d->file.handle(), TCSAFLUSH, &termInfo) < 0) { - *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); - return false; - } - d->timerId = startTimer(TimerInterval); - return true; -#endif -} - - -TrkDevice::~TrkDevice() -{ - close(); - delete d; -} - -void TrkDevice::close() -{ - if (!isOpen()) - return; - if (d->timerId != -1) { - killTimer(d->timerId); - d->timerId = -1; - } -#ifdef Q_OS_WIN - CloseHandle(d->hdevice); - d->hdevice = INVALID_HANDLE_VALUE; -#else - d->file.close(); -#endif - if (verbose()) - logMessage("Close"); -} - -bool TrkDevice::isOpen() const -{ -#ifdef Q_OS_WIN - return d->hdevice != INVALID_HANDLE_VALUE; -#else - return d->file.isOpen(); -#endif -} - -QString TrkDevice::errorString() const -{ - return d->errorString; -} - -bool TrkDevice::serialFrame() const -{ - return d->serialFrame; -} - -void TrkDevice::setSerialFrame(bool f) -{ - d->serialFrame = f; -} - -bool TrkDevice::verbose() const -{ - return true || d->verbose; -} - -void TrkDevice::setVerbose(bool b) -{ - d->verbose = b; -} - -bool TrkDevice::write(const QByteArray &data, QString *errorMessage) -{ - if (verbose()) - logMessage("XWRITE " + data.toHex()); -#ifdef Q_OS_WIN - DWORD charsWritten; - if (!WriteFile(d->hdevice, data.data(), data.size(), &charsWritten, NULL)) { - *errorMessage = QString::fromLatin1("Error writing data: %1").arg(winErrorMessage(GetLastError())); - return false; - } - FlushFileBuffers(d->hdevice); - return true; -#else - if (d->file.write(data) == -1 || !d->file.flush()) { - *errorMessage = QString::fromLatin1("Cannot write: %1").arg(d->file.errorString()); - return false; - } - return true; -#endif -} - -#ifndef Q_OS_WIN -static inline int bytesAvailable(int fileNo) -{ - int numBytes; - const int rc = ioctl(fileNo, FIONREAD, &numBytes); - if (rc < 0) - numBytes=0; - return numBytes; -} -#endif - -void TrkDevice::tryTrkRead() -{ -#ifdef Q_OS_WIN - const DWORD BUFFERSIZE = 1024; - char buffer[BUFFERSIZE]; - DWORD charsRead; - DWORD totalCharsRead = 0; - - while (TryReadFile(d->hdevice, buffer, BUFFERSIZE, &charsRead, NULL)) { - totalCharsRead += charsRead; - d->trkReadBuffer.append(buffer, charsRead); - if (isValidTrkResult(d->trkReadBuffer, d->serialFrame)) - break; - } - if (verbose() && totalCharsRead) - logMessage("Read" + d->trkReadBuffer.toHex()); - if (!totalCharsRead) - return; - const ushort len = trk::isValidTrkResult(d->trkReadBuffer, d->serialFrame); - if (!len) { - const QString msg = QString::fromLatin1("Partial message: %1").arg(stringFromArray(d->trkReadBuffer)); - emitError(msg); - return; - } -#else - const int size = bytesAvailable(d->file.handle()); - if (!size) - return; - const QByteArray data = d->file.read(size); - if (verbose()) - logMessage("READ " + data.toHex()); - d->trkReadBuffer.append(data); - const ushort len = trk::isValidTrkResult(d->trkReadBuffer, d->serialFrame); - if (!len) { - if (d->trkReadBuffer.size() > 10) { - const QString msg = QString::fromLatin1("Unable to extract message from '%1' '%2'"). - arg(QLatin1String(d->trkReadBuffer.toHex())).arg(QString::fromAscii(d->trkReadBuffer)); - emitError(msg); - } - return; - } -#endif // Q_OS_WIN - trk::TrkResult r; - QByteArray rawData; - while (extractResult(&d->trkReadBuffer, d->serialFrame, &r, &rawData)) { - if (verbose()) - logMessage("Read TrkResult " + r.data.toHex()); - emit messageReceived(r); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); - } -} - -void TrkDevice::timerEvent(QTimerEvent *) -{ - tryTrkRead(); -} - -void TrkDevice::emitError(const QString &s) -{ - d->errorString = s; - qWarning("%s\n", qPrintable(s)); - emit error(s); -} - -/* A message to be send to TRK, triggering a callback on receipt - * of the answer. */ -typedef trk::Callback<const trk::TrkResult &> TrkCallback; -struct TrkMessage { - explicit TrkMessage(unsigned char code = 0u, - unsigned char token = 0u, - TrkCallback callback = TrkCallback()); - - unsigned char code; - unsigned char token; - QByteArray data; - QVariant cookie; - TrkCallback callback; - bool invokeOnNAK; -}; - -TrkMessage::TrkMessage(unsigned char c, - unsigned char t, - TrkCallback cb) : - code(c), - token(t), - callback(cb), - invokeOnNAK(false) -{ -} - -// ------- TrkWriteQueueDevice -typedef QSharedPointer<TrkMessage> SharedPointerTrkMessage; - -/* Mixin class that manages a write queue of Trk messages. */ - -class TrkWriteQueue { -public: - TrkWriteQueue(); - - // Enqueue messages. - void queueTrkMessage(unsigned char code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie, - bool invokeOnNAK); - void queueTrkInitialPing(); - - // Call this from the device read notification with the results. - void slotHandleResult(const trk::TrkResult &result); - - // This can be called periodically in a timer to retrieve - // the pending messages to be sent. - bool pendingMessage(SharedPointerTrkMessage *message = 0); - // Notify the queue about the success of the write operation - // after taking the pendingMessage off. - void notifyWriteResult(bool ok); - - // Factory function for ack message - static SharedPointerTrkMessage trkAck(unsigned char token); - -private: - typedef QMap<unsigned char, SharedPointerTrkMessage> TokenMessageMap; - - unsigned char nextTrkWriteToken(); - - unsigned char trkWriteToken; - QQueue<SharedPointerTrkMessage> trkWriteQueue; - TokenMessageMap writtenTrkMessages; - bool trkWriteBusy; -}; - -TrkWriteQueue::TrkWriteQueue() : - trkWriteToken(0), - trkWriteBusy(false) -{ -} - -unsigned char TrkWriteQueue::nextTrkWriteToken() -{ - ++trkWriteToken; - if (trkWriteToken == 0) - ++trkWriteToken; - return trkWriteToken; -} - -void TrkWriteQueue::queueTrkMessage(unsigned char code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie, - bool invokeOnNAK) -{ - const unsigned char token = code == TRK_WRITE_QUEUE_NOOP_CODE ? - (unsigned char)(0) : nextTrkWriteToken(); - SharedPointerTrkMessage msg(new TrkMessage(code, token, callback)); - msg->data = data; - msg->cookie = cookie; - msg->invokeOnNAK = invokeOnNAK; - trkWriteQueue.append(msg); -} - -bool TrkWriteQueue::pendingMessage(SharedPointerTrkMessage *message) -{ - // Invoked from timer, try to flush out message queue - if (trkWriteBusy || trkWriteQueue.isEmpty()) - return false; - // Handle the noop message, just invoke CB - if (trkWriteQueue.front()->code == TRK_WRITE_QUEUE_NOOP_CODE) { - const SharedPointerTrkMessage noopMessage = trkWriteQueue.dequeue(); - if (noopMessage->callback) { - trk::TrkResult result; - result.code = noopMessage->code; - result.token = noopMessage->token; - result.data = noopMessage->data; - result.cookie = noopMessage->cookie; - noopMessage->callback(result); - } - } - // Check again for real messages - if (trkWriteQueue.isEmpty()) - return false; - if (message) - *message = trkWriteQueue.front(); - return true; -} - -void TrkWriteQueue::notifyWriteResult(bool ok) -{ - // On success, dequeue message and await result - if (ok) { - const SharedPointerTrkMessage firstMsg = trkWriteQueue.dequeue(); - writtenTrkMessages.insert(firstMsg->token, firstMsg); - trkWriteBusy = true; - } -} - -void TrkWriteQueue::slotHandleResult(const trk::TrkResult &result) -{ - trkWriteBusy = false; - if (result.code != trk::TrkNotifyAck && result.code != trk::TrkNotifyNak) - return; - // Find which request the message belongs to and invoke callback - // if ACK or on NAK if desired. - const TokenMessageMap::iterator it = writtenTrkMessages.find(result.token); - if (it == writtenTrkMessages.end()) - return; - const bool invokeCB = it.value()->callback - && (result.code == trk::TrkNotifyAck || it.value()->invokeOnNAK); - - if (invokeCB) { - trk::TrkResult result1 = result; - result1.cookie = it.value()->cookie; - it.value()->callback(result1); - } - writtenTrkMessages.erase(it); -} - -SharedPointerTrkMessage TrkWriteQueue::trkAck(unsigned char token) -{ - SharedPointerTrkMessage msg(new TrkMessage(0x80, token)); - msg->token = token; - msg->data.append('\0'); - return msg; -} - -void TrkWriteQueue::queueTrkInitialPing() -{ - const SharedPointerTrkMessage msg(new TrkMessage(0, 0)); // Ping, reset sequence count - trkWriteQueue.append(msg); -} - -// ----------------------- -TrkWriteQueueDevice::TrkWriteQueueDevice(QObject *parent) : - TrkDevice(parent), - qd(new TrkWriteQueue) -{ - connect(this, SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(slotHandleResult(trk::TrkResult))); -} - -TrkWriteQueueDevice::~TrkWriteQueueDevice() -{ - delete qd; -} - -void TrkWriteQueueDevice::sendTrkMessage(unsigned char code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie, - bool invokeOnNAK) -{ - qd->queueTrkMessage(code, callback, data, cookie, invokeOnNAK); -} - -void TrkWriteQueueDevice::sendTrkInitialPing() -{ - qd->queueTrkInitialPing(); -} - -bool TrkWriteQueueDevice::sendTrkAck(unsigned char token) -{ - // The acknowledgement must not be queued! - const SharedPointerTrkMessage ack = TrkWriteQueue::trkAck(token); - return trkWriteRawMessage(*ack); - // 01 90 00 07 7e 80 01 00 7d 5e 7e -} - -void TrkWriteQueueDevice::tryTrkWrite() -{ - if (!qd->pendingMessage()) - return; - SharedPointerTrkMessage message; - qd->pendingMessage(&message); - const bool success = trkWriteRawMessage(*message); - qd->notifyWriteResult(success); -} - -bool TrkWriteQueueDevice::trkWriteRawMessage(const TrkMessage &msg) -{ - const QByteArray ba = trk::frameMessage(msg.code, msg.token, msg.data, serialFrame()); - if (verbose()) - logMessage("WRITE: " + trk::stringFromArray(ba)); - QString errorMessage; - const bool rc = write(ba, &errorMessage); - if (!rc) - emitError(errorMessage); - return rc; -} - -void TrkWriteQueueDevice::timerEvent(QTimerEvent *ev) -{ - tryTrkWrite(); - TrkDevice::timerEvent(ev); -} - -void TrkWriteQueueDevice::slotHandleResult(const trk::TrkResult &result) -{ - qd->slotHandleResult(result); -} - -// ----------- TrkWriteQueueDevice - -struct TrkWriteQueueIODevicePrivate { - TrkWriteQueueIODevicePrivate(const QSharedPointer<QIODevice> &d); - - const QSharedPointer<QIODevice> device; - TrkWriteQueue queue; - QByteArray readBuffer; - bool serialFrame; - bool verbose; -}; - -TrkWriteQueueIODevicePrivate::TrkWriteQueueIODevicePrivate(const QSharedPointer<QIODevice> &d) : - device(d), - serialFrame(true), - verbose(false) -{ -} - -TrkWriteQueueIODevice::TrkWriteQueueIODevice(const QSharedPointer<QIODevice> &device, - QObject *parent) : - QObject(parent), - d(new TrkWriteQueueIODevicePrivate(device)) -{ - startTimer(TimerInterval); -} - -TrkWriteQueueIODevice::~TrkWriteQueueIODevice() -{ - delete d; -} - -bool TrkWriteQueueIODevice::serialFrame() const -{ - return d->serialFrame; -} - -void TrkWriteQueueIODevice::setSerialFrame(bool f) -{ - d->serialFrame = f; -} - -bool TrkWriteQueueIODevice::verbose() const -{ - return true || d->verbose; -} - -void TrkWriteQueueIODevice::setVerbose(bool b) -{ - d->verbose = b; -} - -void TrkWriteQueueIODevice::sendTrkMessage(unsigned char code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie, - bool invokeOnNAK) -{ - d->queue.queueTrkMessage(code, callback, data, cookie, invokeOnNAK); -} - -void TrkWriteQueueIODevice::sendTrkInitialPing() -{ - d->queue.queueTrkInitialPing(); -} - -bool TrkWriteQueueIODevice::sendTrkAck(unsigned char token) -{ - // The acknowledgement must not be queued! - const SharedPointerTrkMessage ack = TrkWriteQueue::trkAck(token); - return trkWriteRawMessage(*ack); - // 01 90 00 07 7e 80 01 00 7d 5e 7e -} - - -void TrkWriteQueueIODevice::timerEvent(QTimerEvent *) -{ - tryTrkWrite(); - tryTrkRead(); -} - -void TrkWriteQueueIODevice::tryTrkWrite() -{ - if (!d->queue.pendingMessage()) - return; - SharedPointerTrkMessage message; - d->queue.pendingMessage(&message); - const bool success = trkWriteRawMessage(*message); - d->queue.notifyWriteResult(success); -} - -bool TrkWriteQueueIODevice::trkWriteRawMessage(const TrkMessage &msg) -{ - const QByteArray ba = trk::frameMessage(msg.code, msg.token, msg.data, serialFrame()); - if (verbose()) - logMessage("WRITE: " + trk::stringFromArray(ba)); - const bool ok = d->device->write(ba) != -1; - if (!ok) { - const QString msg = QString::fromLatin1("Unable to write %1 bytes: %2:").arg(ba.size()).arg(d->device->errorString()); - qWarning("%s\n", qPrintable(msg)); - } - return ok; -} - -void TrkWriteQueueIODevice::tryTrkRead() -{ - const quint64 bytesAvailable = d->device->bytesAvailable(); - if (!bytesAvailable) - return; - const QByteArray newData = d->device->read(bytesAvailable); - //if (verbose()) - logMessage("READ " + newData.toHex()); - d->readBuffer.append(newData); - trk::TrkResult r; - QByteArray rawData; - while (trk::extractResult(&(d->readBuffer), d->serialFrame, &r, &rawData)) { - d->queue.slotHandleResult(r); - emit messageReceived(r); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); - } -} - -} // namespace trkold diff --git a/tests/manual/trk/trkolddevice.h b/tests/manual/trk/trkolddevice.h deleted file mode 100644 index 5b8a6cb799f02b0586795ab01529974708637fd6..0000000000000000000000000000000000000000 --- a/tests/manual/trk/trkolddevice.h +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 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://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef TRKOLDDEVICE_H -#define TRKOLDDEVICE_H - -#include "callback.h" - -#include <QtCore/QObject> -#include <QtCore/QVariant> -#include <QtCore/QByteArray> -#include <QtCore/QSharedPointer> - -QT_BEGIN_NAMESPACE -class QIODevice; -QT_END_NAMESPACE - - -namespace trk { - struct TrkResult; -} - -namespace trkold { - -struct TrkMessage; -struct TrkDevicePrivate; -class TrkWriteQueue; -struct TrkWriteQueueIODevicePrivate; - -/* TrkDevice: Implements a Windows COM or Linux device for - * Trk communications. Provides synchronous write and asynchronous - * read operation. - * The serialFrames property specifies whether packets are encapsulated in - * "0x90 <length>" frames, which is currently the case for serial ports. */ - -class TrkDevice : public QObject -{ - Q_DISABLE_COPY(TrkDevice) - Q_OBJECT - Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) - Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) -public: - explicit TrkDevice(QObject *parent = 0); - virtual ~TrkDevice(); - - bool open(const QString &port, QString *errorMessage); - bool isOpen() const; - void close(); - - QString errorString() const; - - bool serialFrame() const; - void setSerialFrame(bool f); - - bool verbose() const; - void setVerbose(bool b); - - bool write(const QByteArray &data, QString *errorMessage); - -signals: - void messageReceived(const trk::TrkResult &result); - // Emitted with the contents of messages enclosed in 07e, not for log output - void rawDataReceived(const QByteArray &data); - void error(const QString &msg); - void logMessage(const QString &msg); - -protected: - void emitError(const QString &msg); - virtual void timerEvent(QTimerEvent *ev); - -private: - void tryTrkRead(); - - TrkDevicePrivate *d; -}; - -/* TrkWriteQueueDevice: Extends TrkDevice by write message queue allowing - * for queueing messages with a notification callback. If the message receives - * an ACK, the callback is invoked. - * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronization. - * The respective message will not be sent, the callback is just invoked. */ - -enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; - -class TrkWriteQueueDevice : public TrkDevice -{ - Q_OBJECT -public: - explicit TrkWriteQueueDevice(QObject *parent = 0); - virtual ~TrkWriteQueueDevice(); - - // Construct as 'TrkWriteQueueDevice::TrkCallback(instance, &Class::method);' - typedef trk::Callback<const trk::TrkResult &> TrkCallback; - - // Enqueue a message with a notification callback. - void sendTrkMessage(unsigned char code, - TrkCallback callBack = TrkCallback(), - const QByteArray &data = QByteArray(), - const QVariant &cookie = QVariant(), - // Invoke callback on receiving NAK, too. - bool invokeOnNAK = false); - - // Enqeue an initial ping - void sendTrkInitialPing(); - - // Send an Ack synchronously, bypassing the queue - bool sendTrkAck(unsigned char token); - -signals: - void logMessage(const QString &msg); - -private slots: - void slotHandleResult(const trk::TrkResult &); - -protected: - virtual void timerEvent(QTimerEvent *ev); - -private: - void tryTrkWrite(); - bool trkWriteRawMessage(const TrkMessage &msg); - - TrkWriteQueue *qd; -}; - -/* A Trk queueing device wrapping around a QIODevice (otherwise - * mimicking TrkWriteQueueDevice). - * Can be used to forward Trk over a network or to simulate things. */ - -class TrkWriteQueueIODevice : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(TrkWriteQueueIODevice) - Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) - Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) -public: - typedef trk::Callback<const trk::TrkResult &> TrkCallback; - - explicit TrkWriteQueueIODevice(const QSharedPointer<QIODevice> &device, - QObject *parent = 0); - virtual ~TrkWriteQueueIODevice(); - - bool serialFrame() const; - void setSerialFrame(bool f); - - bool verbose() const; - void setVerbose(bool b); - - void sendTrkMessage(unsigned char code, - TrkCallback callback = TrkCallback(), - const QByteArray &data = QByteArray(), - const QVariant &cookie = QVariant(), - bool invokeOnNAK = false); - void sendTrkInitialPing(); - bool sendTrkAck(unsigned char token); - -signals: - void messageReceived(const trk::TrkResult&); - // Emitted with the contents of messages enclosed in 07e, not for log output - void rawDataReceived(const QByteArray &data); - void logMessage(const QString &msg); - - -protected: - virtual void timerEvent(QTimerEvent *ev); - -private: - void tryTrkRead(); - void tryTrkWrite(); - bool trkWriteRawMessage(const TrkMessage &msg); - - TrkWriteQueueIODevicePrivate *d; -}; - -} // namespace trkold - -#endif // TRKOLDDEVICE_H diff --git a/tests/manual/trk/trkserver.cpp b/tests/manual/trk/trkserver.cpp deleted file mode 100644 index 295fb93e570741450a2ccfc1864ea23a205041d3..0000000000000000000000000000000000000000 --- a/tests/manual/trk/trkserver.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 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://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "trkutils.h" - -#include <QtCore/QCoreApplication> -#include <QtCore/QFile> -#include <QtCore/QStringList> -#include <QtCore/QFileInfo> - -#include <QtNetwork/QLocalServer> -#include <QtNetwork/QLocalSocket> - - -#ifdef Q_OS_UNIX - -#include <signal.h> - -void signalHandler(int) -{ - qApp->exit(1); -} - -#endif - -using namespace trk; - -struct TrkOptions { - TrkOptions() : verbose(1), serialFrame(true) {} - - int verbose; - bool serialFrame; - QString serverName; - QString dumpName; - QStringList additionalDumps; -}; - - -// Format of the replay source is something like -// ---IDE------------------------------------------------------ -// Command: 0x05 Support Mask -// [05 02] -//---TRK------------------------------------------------------ -// Command: 0x80 Acknowledge -// Error: 0x0 -// [80 02 00 7E 00 4F 5F 01 00 00 00 0F 1F 00 00 00 -// 00 00 00 01 00 11 00 03 00 00 00 00 00 03 00 00...] - -struct MemorySegment { - MemorySegment(const QString &n = QString()) : name(n), address(0) {} - - bool readDump(const QString &fileName, uint address /* = 0*/, QString *errorMessage); - bool readMemory(uint addr, ushort len, QByteArray *ba) const; - - QString name; - uint address; - QByteArray data; -}; - -// Determine address from filename using the "0xa5453.bin" convention - -static int addressFromFileName(const QString &fn) -{ - QString baseName = QFileInfo(fn).fileName(); - if (!baseName.startsWith(QLatin1String("0x"))) - return -1; - baseName.remove(0, 2); - int sepPos = baseName.indexOf(QLatin1Char('_')); - if (sepPos == -1) - sepPos = baseName.indexOf(QLatin1Char('-')); - if (sepPos == -1) - sepPos = baseName.indexOf(QLatin1Char('.')); - if (sepPos == -1) - return -1; - baseName.truncate(sepPos); - bool ok; - const int value = baseName.toInt(&ok, 16); - return ok ? value : -1; -} - -// Read a chunk of memory from file. Use address unless it is 0, -// in which case the filename is used for matching "0xa5453.bin" -bool MemorySegment::readDump(const QString &fileName, uint addressIn /* = 0*/, QString *errorMessage) -{ - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) { - *errorMessage = QString::fromLatin1("Unable to read %1: %2").arg(fileName, file.errorString()); - return false; - } - data = file.readAll(); - file.close(); - if (addressIn) { - address = addressIn; - } else { - const int addressInt = addressFromFileName(fileName); - if (addressInt == -1) { - *errorMessage = QString::fromLatin1("Unable to determine address from %1").arg(fileName); - return false; - } - address = addressInt; - } - *errorMessage = QString::fromLatin1("Read %1 bytes of data starting at 0x%2 from %3").arg(data.size()).arg(address, 0, 16).arg(fileName); - return true; -} - -bool MemorySegment::readMemory(uint addr, ushort len, QByteArray *ba) const -{ - if (addr < address) - return false; - const int requestStart = addr - address; - const int requestEnd = requestStart + len; - if (requestEnd > data.size()) - return false; - for (int i = requestStart; i != requestEnd; ++i) - appendByte(ba, data.at(i)); - return true; -} - -struct Inferior -{ - Inferior(); - uint pid; - uint tid; - uint codeseg; - uint dataseg; - - uint registers[RegisterCount]; - QList<MemorySegment> memorySegments; -}; - -Inferior::Inferior() -{ - pid = 0x000008F5; - tid = 0x000008F6; - - codeseg = 0x786A4000; - dataseg = 0x00400000; - - registers[0] = 0x00000000; - registers[1] = 0xC92D7FBC; - registers[2] = 0x00000000; - registers[3] = 0x00600000; - registers[4] = 0x00000000; - registers[5] = 0x786A7970; - registers[6] = 0x00000000; - registers[7] = 0x00000000; - registers[8] = 0x00000012; - registers[9] = 0x00000040; - registers[10] = 0xC82AF210; - registers[11] = 0x00000000; - registers[12] = 0xC8000548; - registers[13] = 0x00403ED0; - registers[14] = 0x786A6BD8; - registers[15] = 0x786A4CC8; - registers[16] = 0x68000010; // that's reg 25 on chip? -} - -class TrkServer : public QObject -{ - Q_OBJECT - -public: - TrkServer(); - ~TrkServer(); - - void setServerName(const QString &name) { m_serverName = name; } - void setMemoryDumpName(const QString &source) { m_memoryDumpName = source; } - void setVerbose(int v) { m_verbose = v; } - void setSerialFrame(bool b) { m_serialFrame = b; } - bool readDump(const QString &fn); - bool startServer(); - -private slots: - void handleConnection(); - void readFromAdapter(); - void writeToAdapter(byte command, byte token, const QByteArray &data); - - void handleAdapterMessage(const TrkResult &result); - -private: - void logMessage(const QString &msg, bool force = 0) const; - bool handleMemoryRequest(uint addr, ushort len, byte option, QByteArray *ba) const; - byte nextNotificationToken(); - - QString m_serverName; - QString m_memoryDumpName; - - QByteArray m_adapterReadBuffer; - - QByteArray m_memoryData; - QLocalServer m_server; - int m_lastSent; - QLocalSocket *m_adapterConnection; - Inferior m_inferior; - byte m_notificationToken; - int m_verbose; - bool m_serialFrame; -}; - -TrkServer::TrkServer() : - m_adapterConnection(0), - m_notificationToken(0), - m_verbose(1), - m_serialFrame(true) -{ -} - -TrkServer::~TrkServer() -{ - logMessage("Shutting down.\n"); - m_server.close(); -} - -bool TrkServer::readDump(const QString &fn) -{ - QString msg; - MemorySegment segment(QLatin1String("data")); - if (!segment.readDump(fn, 0, &msg)) { - logMessage(msg, true); - return false; - } - m_inferior.memorySegments.push_back(segment); - logMessage(msg, true); - return true; -} - -bool TrkServer::startServer() -{ - QString msg; - MemorySegment codeSegment(QLatin1String("code")); - if (!codeSegment.readDump(m_memoryDumpName, 0x786A4000, &msg)) { - logMessage(msg, true); - return false; - } - m_inferior.memorySegments.push_front(codeSegment); - logMessage(msg, true); - - m_lastSent = 0; - if (!m_server.listen(m_serverName)) { - logMessage(QString("Error: Unable to start the TRK server %1: %2.") - .arg(m_serverName).arg(m_server.errorString()), true); - return false; - } - - logMessage("The TRK server '" + m_serverName + "'is running. Run the adapter now.", true); - connect(&m_server, SIGNAL(newConnection()), this, SLOT(handleConnection())); - return true; -} - -void TrkServer::logMessage(const QString &msg, bool force) const -{ - if (m_verbose || force) - qDebug("TRKSERVER: %s", qPrintable(msg)); -} - -void TrkServer::handleConnection() -{ - m_adapterConnection = m_server.nextPendingConnection(); - connect(m_adapterConnection, SIGNAL(disconnected()), - m_adapterConnection, SLOT(deleteLater())); - connect(m_adapterConnection, SIGNAL(readyRead()), - this, SLOT(readFromAdapter())); -} - -void TrkServer::readFromAdapter() -{ - QByteArray packet = m_adapterConnection->readAll(); - m_adapterReadBuffer.append(packet); - - logMessage("trk: -> " + stringFromArray(packet)); - - if (packet != m_adapterReadBuffer) - logMessage("buffer: " + stringFromArray(m_adapterReadBuffer)); - - while (!m_adapterReadBuffer.isEmpty()) { - TrkResult r; - while (extractResult(&m_adapterReadBuffer, m_serialFrame, &r)) - handleAdapterMessage(r); - } -} - -void TrkServer::writeToAdapter(byte command, byte token, const QByteArray &data) -{ - QByteArray msg = frameMessage(command, token, data, m_serialFrame); - logMessage("trk: <- " + stringFromArray(msg)); - m_adapterConnection->write(msg); -} - -bool TrkServer::handleMemoryRequest(uint addr, ushort len, byte option, QByteArray *ba) const -{ - Q_UNUSED(option); - foreach (const MemorySegment &s, m_inferior.memorySegments) { - if (s.readMemory(addr, len, ba)) { - if (m_verbose) - logMessage(QString::fromLatin1("Read memory %1 bytes from 0x%2 from segment %3.").arg(len).arg(addr, 0, 16).arg(s.name)); - return true; - } - } - logMessage(QString::fromLatin1("ADDRESS OUTSIDE ANY SEGMENTS: 0X%1").arg(addr, 0, 16), true); - return false; -} - -void TrkServer::handleAdapterMessage(const TrkResult &result) -{ - QByteArray data; - data.append(char(0x00)); // No error - switch (result.code) { - case 0x00: { // Ping - m_notificationToken = 0; - writeToAdapter(0x80, 0x00, data); - break; - } - case 0x01: { // Connect - writeToAdapter(0x80, result.token, data); - break; - } - case 0x10: { // Read Memory - const char *p = result.data.data(); - byte option = p[0]; - Q_UNUSED(option); - const ushort len = extractShort(p + 1); - const uint addr = extractInt(p + 3);; - if (handleMemoryRequest(addr, len, option, &data)) { - writeToAdapter(0x80, result.token, data); - } else { - data[0] = 32; // NAK, bad hair day - writeToAdapter(0x80, result.token, data); - } - break; - } - case 0x12: { // Read Registers - for (int i = 0; i < RegisterCount; ++i) - appendInt(&data, m_inferior.registers[i], BigEndian); - writeToAdapter(0x80, result.token, data); - break; - } - case 0x18: { // Continue - writeToAdapter(0x80, result.token, data); // ACK Package - - if (1) { // Fake "Stop" - QByteArray note; - appendInt(¬e, 0); // FIXME: use proper address - appendInt(¬e, m_inferior.pid); - appendInt(¬e, m_inferior.tid); - appendByte(¬e, 0x00); - appendByte(¬e, 0x00); - writeToAdapter(0x90, nextNotificationToken(), note); - } - - break; - } - case 0x19: { // Step - const char *p = result.data.data(); - //byte option = *p; - uint startaddr = extractInt(p + 1); - uint endaddr = extractInt(p + 5); - uint pid = extractInt(p + 9); - //uint tid = extractInt(p + 13); - if (startaddr != m_inferior.registers[RegisterPC]) - logMessage("addr mismatch:" + hexNumber(startaddr) + " " + - hexNumber(m_inferior.registers[RegisterPC])); - if (pid != m_inferior.pid) - logMessage("pid mismatch:" + hexNumber(pid) + " " + - hexNumber(m_inferior.pid)); - writeToAdapter(0x80, result.token, data); - - // Fake "step" - m_inferior.registers[RegisterPC] = endaddr; - - if (1) { // Fake "Stop" - QByteArray note; - appendInt(¬e, 0); // FIXME: use proper address - appendInt(¬e, m_inferior.pid); - appendInt(¬e, m_inferior.tid); - appendByte(¬e, 0x00); - appendByte(¬e, 0x00); - writeToAdapter(0x90, nextNotificationToken(), note); - } - break; - } - case 0x40: { // Create Item - appendInt(&data, m_inferior.pid, BigEndian); - appendInt(&data, m_inferior.tid, BigEndian); - appendInt(&data, m_inferior.codeseg, BigEndian); - appendInt(&data, m_inferior.dataseg, BigEndian); - writeToAdapter(0x80, result.token, data); - break; - } - case 0x41: { // Delete Item - writeToAdapter(0x80, result.token, data); - // A Process? - // Command: 0xA1 Notify Deleted - //[A1 02 00 00 00 00 00 00 00 00 01 B5] - QByteArray note; // FIXME - appendByte(¬e, 0); - appendByte(¬e, 0); - appendInt(¬e, 0); - appendInt(¬e, m_inferior.pid); - writeToAdapter(0xA1, nextNotificationToken(), note); - break; - } - case 0x1B: { // Set Break - static int breakpointNumber = 10; // Trk does that - appendInt(&data, breakpointNumber++); - writeToAdapter(0x80, result.token, data); - break; - } - default: { - data[0] = 0x10; // Command not supported - writeToAdapter(0xff, result.token, data); - break; - } - } -} - -byte TrkServer::nextNotificationToken() -{ - ++m_notificationToken; - if (m_notificationToken == 0) - ++m_notificationToken; - return m_notificationToken; -} - -static bool readTrkArgs(const QStringList &args, TrkOptions *o) -{ - int argNumber = 0; - const QStringList::const_iterator cend = args.constEnd(); - QStringList::const_iterator it = args.constBegin(); - for (++it; it != cend; ++it) { - if (it->startsWith(QLatin1Char('-'))) { - if (*it == QLatin1String("-v")) { - o->verbose++; - } else if (*it == QLatin1String("-q")) { - o->verbose = 0; - } else if (*it == QLatin1String("-f")) { - o->serialFrame= false; - } - - } else { - switch (argNumber++) { - case 0: - o->serverName = *it; - break; - case 1: - o->dumpName = *it; - break; - default: - o->additionalDumps.push_back(*it); - break; - } - } - } - return !o->dumpName.isEmpty(); -} - -int main(int argc, char *argv[]) -{ -#ifdef Q_OS_UNIX - signal(SIGUSR1, signalHandler); -#endif - - QCoreApplication app(argc, argv); - TrkOptions options; - if (!readTrkArgs(app.arguments(), &options)) { - qWarning("Usage: %s [-v|-q] <trkservername> <replaysource> [additional dumps]\n" - "Options: -v verbose\n" - " -f Turn serial message frame off\n" - " -q quiet\n" - " Additional dump names must follow the naming convention '0x4AD.bin", argv[0]); - return 1; - } - - TrkServer server; - server.setServerName(options.serverName); - server.setMemoryDumpName(options.dumpName); - server.setSerialFrame(options.serialFrame); - foreach(const QString &ad, options.additionalDumps) - if (!server.readDump(ad)) - return -1; - server.setVerbose(options.verbose); - if (!server.startServer()) - return -1; - - return app.exec(); -} - -#include "trkserver.moc" diff --git a/tests/manual/trk/trkserver.pro b/tests/manual/trk/trkserver.pro deleted file mode 100644 index 17f7c91741035a62970ce850dd402b64ab47d12d..0000000000000000000000000000000000000000 --- a/tests/manual/trk/trkserver.pro +++ /dev/null @@ -1,10 +0,0 @@ - -TEMPLATE = app - -include(../../../src/shared/trk/trk.pri) - -QT = core network -win32:CONFIG+=console - -SOURCES += \ - $$PWD/trkserver.cpp