forked from qt-creator/qt-creator
Debugger[TCF TRK]: Adapt to TCF TRK 4.0.5
- Parse/Format errors correctly (long codes) - Use standard 'Registers' service, fake 'getm' as long as it is unimplemented - Use 'Registers|getChildren' for each thread to activate the context and use the names obtained from there instead of hardcoded register names
This commit is contained in:
@@ -147,17 +147,23 @@ QByteArray Thread::gdbReportRegisters() const
|
|||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray Thread::registerContentsLogMessage() const
|
||||||
|
{
|
||||||
|
QByteArray logMsg;
|
||||||
|
for (int i = 0; i < RegisterCount; ++i) {
|
||||||
|
logMsg += dumpRegister(i, registers[i]);
|
||||||
|
logMsg += ' ';
|
||||||
|
}
|
||||||
|
return logMsg;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray Thread::gdbRegisterLogMessage(bool verbose) const
|
QByteArray Thread::gdbRegisterLogMessage(bool verbose) const
|
||||||
{
|
{
|
||||||
QByteArray logMsg = "REGISTER CONTENTS: (Thread 0x";
|
QByteArray logMsg = "Register contents: (Thread 0x";
|
||||||
logMsg += QByteArray::number(id, 16);
|
logMsg += QByteArray::number(id, 16);
|
||||||
logMsg += " ) ";
|
logMsg += " ) ";
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
for (int i = 0; i < RegisterCount; ++i) {
|
logMsg += registerContentsLogMessage();
|
||||||
logMsg += dumpRegister(i, registers[i]);
|
|
||||||
logMsg += ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return logMsg;
|
return logMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ struct Thread {
|
|||||||
void resetRegisters();
|
void resetRegisters();
|
||||||
// Gdb helpers for reporting values
|
// Gdb helpers for reporting values
|
||||||
QByteArray gdbReportRegisters() const;
|
QByteArray gdbReportRegisters() const;
|
||||||
|
QByteArray registerContentsLogMessage() const;
|
||||||
QByteArray gdbRegisterLogMessage(bool verbose) const;
|
QByteArray gdbRegisterLogMessage(bool verbose) const;
|
||||||
QByteArray gdbReportSingleRegister(unsigned i) const;
|
QByteArray gdbReportSingleRegister(unsigned i) const;
|
||||||
QByteArray gdbSingleRegisterLogMessage(unsigned i) const;
|
QByteArray gdbSingleRegisterLogMessage(unsigned i) const;
|
||||||
|
|||||||
@@ -62,14 +62,6 @@
|
|||||||
|
|
||||||
enum { debug = 0 };
|
enum { debug = 0 };
|
||||||
|
|
||||||
// Register names used by the 'SimpleRegister' service
|
|
||||||
static const char *tcfTrkSimpleRegisterNamesC[] =
|
|
||||||
{"R0", "R1", "R2", "R3",
|
|
||||||
"R4", "R5", "R6", "R7",
|
|
||||||
"R8", "R9", "R10", "R11",
|
|
||||||
"R12", "SP", "LR", "PC",
|
|
||||||
"CPSR"};
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -138,14 +130,6 @@ TcfTrkGdbAdapter::TcfTrkGdbAdapter(GdbEngine *engine) :
|
|||||||
this, SLOT(trkLogMessage(QString)));
|
this, SLOT(trkLogMessage(QString)));
|
||||||
connect(m_trkDevice, SIGNAL(tcfEvent(tcftrk::TcfTrkEvent)),
|
connect(m_trkDevice, SIGNAL(tcfEvent(tcftrk::TcfTrkEvent)),
|
||||||
this, SLOT(tcftrkEvent(tcftrk::TcfTrkEvent)));
|
this, SLOT(tcftrkEvent(tcftrk::TcfTrkEvent)));
|
||||||
|
|
||||||
// Set register mappings
|
|
||||||
const int registerCount = sizeof(tcfTrkSimpleRegisterNamesC)/sizeof(const char*);
|
|
||||||
QVector<QByteArray> registerNames;
|
|
||||||
registerNames.reserve(registerCount);
|
|
||||||
for (int i = 0; i < registerCount; i++)
|
|
||||||
registerNames.push_back(QByteArray(tcfTrkSimpleRegisterNamesC[i]));
|
|
||||||
m_trkDevice->setRegisterNames(registerNames);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TcfTrkGdbAdapter::~TcfTrkGdbAdapter()
|
TcfTrkGdbAdapter::~TcfTrkGdbAdapter()
|
||||||
@@ -282,8 +266,7 @@ void TcfTrkGdbAdapter::tcftrkEvent(const TcfTrkEvent &e)
|
|||||||
static_cast<const TcfTrkRunControlModuleLoadContextSuspendedEvent &>(e));
|
static_cast<const TcfTrkRunControlModuleLoadContextSuspendedEvent &>(e));
|
||||||
break;
|
break;
|
||||||
case TcfTrkEvent::RunControlContextAdded: // Thread/process added
|
case TcfTrkEvent::RunControlContextAdded: // Thread/process added
|
||||||
foreach(const RunControlContext &rc,
|
foreach(const RunControlContext &rc, static_cast<const TcfTrkRunControlContextAddedEvent &>(e).contexts())
|
||||||
static_cast<const TcfTrkRunControlContextAddedEvent &>(e).contexts())
|
|
||||||
if (rc.type() == RunControlContext::Thread)
|
if (rc.type() == RunControlContext::Thread)
|
||||||
addThread(rc.threadId());
|
addThread(rc.threadId());
|
||||||
break;
|
break;
|
||||||
@@ -693,9 +676,11 @@ void TcfTrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
|
|||||||
// FIXME: Assume all goes well.
|
// FIXME: Assume all goes well.
|
||||||
m_snapshot.setRegisterValue(m_session.tid, regnumValue.first, regnumValue.second);
|
m_snapshot.setRegisterValue(m_session.tid, regnumValue.first, regnumValue.second);
|
||||||
logMessage(_("Setting register #%1 to 0x%2").arg(regnumValue.first).arg(regnumValue.second, 0, 16));
|
logMessage(_("Setting register #%1 to 0x%2").arg(regnumValue.first).arg(regnumValue.second, 0, 16));
|
||||||
|
QByteArray registerValue;
|
||||||
|
trk::appendInt(®isterValue, trk::BigEndian); // Registers are big endian
|
||||||
m_trkDevice->sendRegistersSetCommand(
|
m_trkDevice->sendRegistersSetCommand(
|
||||||
TcfTrkCallback(this, &TcfTrkGdbAdapter::handleWriteRegister),
|
TcfTrkCallback(this, &TcfTrkGdbAdapter::handleWriteRegister),
|
||||||
currentThreadContextId(), regnumValue.first, regnumValue.second,
|
currentThreadContextId(), regnumValue.first, registerValue,
|
||||||
QVariant(regnumValue.first));
|
QVariant(regnumValue.first));
|
||||||
// Note that App TRK refuses to write registers 13 and 14
|
// Note that App TRK refuses to write registers 13 and 14
|
||||||
}
|
}
|
||||||
@@ -1016,6 +1001,11 @@ void TcfTrkGdbAdapter::addThread(unsigned id)
|
|||||||
if (m_session.mainTid == 0)
|
if (m_session.mainTid == 0)
|
||||||
m_session.mainTid = id;
|
m_session.mainTid = id;
|
||||||
}
|
}
|
||||||
|
// We cannot retrieve register values unless the registers of that
|
||||||
|
// thread have been retrieved (TCF TRK oddity).
|
||||||
|
const QByteArray contextId = tcftrk::RunControlContext::tcfId(m_session.pid, id);
|
||||||
|
m_trkDevice->sendRegistersGetChildrenCommand(TcfTrkCallback(this, &TcfTrkGdbAdapter::handleRegisterChildren),
|
||||||
|
contextId, QVariant(contextId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1149,9 +1139,48 @@ void TcfTrkGdbAdapter::reportRegisters()
|
|||||||
sendGdbServerMessage(thread.gdbReportRegisters(), thread.gdbRegisterLogMessage(m_verbose));
|
sendGdbServerMessage(thread.gdbReportRegisters(), thread.gdbRegisterLogMessage(m_verbose));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TcfTrkGdbAdapter::handleRegisterChildren(const tcftrk::TcfTrkCommandResult &result)
|
||||||
|
{
|
||||||
|
const QByteArray contextId = result.cookie.toByteArray();
|
||||||
|
if (!result) {
|
||||||
|
logMessage("Error retrieving register children of " + contextId + ": " + result.errorString(), LogError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Parse out registers.
|
||||||
|
// If this is a single 'pid.tid.rGPR' parent entry, recurse to get the actual registers,
|
||||||
|
// ('pid.tid.rGPR.R0'..). At least 'pid.tid.rGPR' must have been retrieved to be
|
||||||
|
// able to access the register contents.
|
||||||
|
QVector<QByteArray> registerNames = tcftrk::TcfTrkDevice::parseRegisterGetChildren(result);
|
||||||
|
if (registerNames.size() == 1) {
|
||||||
|
m_trkDevice->sendRegistersGetChildrenCommand(TcfTrkCallback(this, &TcfTrkGdbAdapter::handleRegisterChildren),
|
||||||
|
registerNames.front(), result.cookie);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// First thread: Set base names in device.
|
||||||
|
if (!m_trkDevice->registerNames().isEmpty())
|
||||||
|
return;
|
||||||
|
// Make sure we get all registers
|
||||||
|
const int registerCount = registerNames.size();
|
||||||
|
if (registerCount != Symbian::RegisterCount) {
|
||||||
|
logMessage(QString::fromLatin1("Invalid number of registers received, expected %1, got %2").
|
||||||
|
arg(Symbian::RegisterCount).arg(registerCount), LogError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Set up register names (strip thread context "pid.tid"+'.')
|
||||||
|
QString msg = QString::fromLatin1("Retrieved %1 register names: ").arg(registerCount);
|
||||||
|
const int contextLength = contextId.size() + 1;
|
||||||
|
for (int i = 0; i < registerCount; i++) {
|
||||||
|
registerNames[i].remove(0, contextLength);
|
||||||
|
if (i)
|
||||||
|
msg += QLatin1Char(',');
|
||||||
|
msg += QString::fromAscii(registerNames[i]);
|
||||||
|
}
|
||||||
|
logMessage(msg);
|
||||||
|
m_trkDevice->setRegisterNames(registerNames);
|
||||||
|
}
|
||||||
|
|
||||||
void TcfTrkGdbAdapter::handleReadRegisters(const TcfTrkCommandResult &result)
|
void TcfTrkGdbAdapter::handleReadRegisters(const TcfTrkCommandResult &result)
|
||||||
{
|
{
|
||||||
logMessage(" REGISTER RESULT: " + result.toString());
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
logMessage("ERROR: " + result.errorString(), LogError);
|
logMessage("ERROR: " + result.errorString(), LogError);
|
||||||
return;
|
return;
|
||||||
@@ -1163,8 +1192,10 @@ void TcfTrkGdbAdapter::handleReadRegisters(const TcfTrkCommandResult &result)
|
|||||||
unsigned i = result.cookie.toUInt();
|
unsigned i = result.cookie.toUInt();
|
||||||
uint *registers = m_snapshot.registers(m_session.tid);
|
uint *registers = m_snapshot.registers(m_session.tid);
|
||||||
QTC_ASSERT(registers, return;)
|
QTC_ASSERT(registers, return;)
|
||||||
foreach (const JsonValue &jr, result.values.front().children())
|
foreach (const JsonValue &jr, result.values.front().children()) {
|
||||||
registers[i++] = jr.data().toUInt(0, 16);
|
QByteArray bigEndianRaw = QByteArray::fromBase64(jr.data());
|
||||||
|
registers[i++] = trk::extractInt(bigEndianRaw);
|
||||||
|
}
|
||||||
m_snapshot.setRegistersValid(m_session.tid, true);
|
m_snapshot.setRegistersValid(m_session.tid, true);
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << "handleReadRegisters: " << m_snapshot.toString();
|
qDebug() << "handleReadRegisters: " << m_snapshot.toString();
|
||||||
@@ -1187,13 +1218,33 @@ void TcfTrkGdbAdapter::handleAndReportReadRegister(const TcfTrkCommandResult &re
|
|||||||
thread.gdbSingleRegisterLogMessage(registerNumber));
|
thread.gdbSingleRegisterLogMessage(registerNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray TcfTrkGdbAdapter::stopMessage() const
|
||||||
|
{
|
||||||
|
QByteArray logMsg = "Stopped with registers in thread 0x";
|
||||||
|
logMsg += QByteArray::number(m_session.tid, 16);
|
||||||
|
if (m_session.tid == m_session.mainTid)
|
||||||
|
logMsg += " [main]";
|
||||||
|
const int idx = m_snapshot.indexOfThread(m_session.tid);
|
||||||
|
if (idx == -1)
|
||||||
|
return logMsg;
|
||||||
|
const Symbian::Thread &thread = m_snapshot.threadInfo.at(idx);
|
||||||
|
logMsg += ", at 0x";
|
||||||
|
logMsg += QByteArray::number(thread.registers[Symbian::RegisterPC], 16);
|
||||||
|
logMsg += ", (loaded at 0x";
|
||||||
|
logMsg += QByteArray::number(m_session.codeseg, 16);
|
||||||
|
logMsg += ", offset 0x";
|
||||||
|
logMsg += QByteArray::number(thread.registers[Symbian::RegisterPC] - m_session.codeseg, 16);
|
||||||
|
logMsg += "), Register contents: ";
|
||||||
|
logMsg += thread.registerContentsLogMessage();
|
||||||
|
return logMsg;
|
||||||
|
}
|
||||||
|
|
||||||
void TcfTrkGdbAdapter::handleAndReportReadRegistersAfterStop(const TcfTrkCommandResult &result)
|
void TcfTrkGdbAdapter::handleAndReportReadRegistersAfterStop(const TcfTrkCommandResult &result)
|
||||||
{
|
{
|
||||||
handleReadRegisters(result);
|
handleReadRegisters(result);
|
||||||
handleReadRegisters(result);
|
handleReadRegisters(result);
|
||||||
const bool reportThread = m_session.tid != m_session.mainTid;
|
const bool reportThread = m_session.tid != m_session.mainTid;
|
||||||
sendGdbServerMessage(m_snapshot.gdbStopMessage(m_session.tid, reportThread),
|
sendGdbServerMessage(m_snapshot.gdbStopMessage(m_session.tid, reportThread), stopMessage());
|
||||||
"Stopped with registers in thread " + QByteArray::number(m_session.tid, 16));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcfTrkGdbAdapter::handleAndReportSetBreakpoint(const TcfTrkCommandResult &result)
|
void TcfTrkGdbAdapter::handleAndReportSetBreakpoint(const TcfTrkCommandResult &result)
|
||||||
@@ -1249,13 +1300,20 @@ void TcfTrkGdbAdapter::handleReadMemoryBuffered(const TcfTrkCommandResult &resul
|
|||||||
const QByteArray memory = TcfTrkDevice::parseMemoryGet(result);
|
const QByteArray memory = TcfTrkDevice::parseMemoryGet(result);
|
||||||
const MemoryRange range = result.cookie.value<MemoryRange>();
|
const MemoryRange range = result.cookie.value<MemoryRange>();
|
||||||
|
|
||||||
if (unsigned(memory.size()) != range.size()) {
|
const bool error = !result;
|
||||||
logMessage(_("TEMPORARY: ") + msgMemoryReadError(range.from, range.size()));
|
const bool insufficient = unsigned(memory.size()) != range.size();
|
||||||
logMessage(_("RETRYING UNBUFFERED"));
|
if (error || insufficient) {
|
||||||
|
QString msg = error ?
|
||||||
|
QString::fromLatin1("Error reading memory: %1").arg(result.errorString()) :
|
||||||
|
QString::fromLatin1("Error reading memory (got %1 of %2): %3").
|
||||||
|
arg(memory.size()).arg(range.size()).arg(msgMemoryReadError(range.from, range.size()));
|
||||||
|
msg += QString::fromLatin1("\n(Retrying unbuffered...)");
|
||||||
|
logMessage(msg, LogError);
|
||||||
// FIXME: This does not handle large requests properly.
|
// FIXME: This does not handle large requests properly.
|
||||||
sendMemoryGetCommand(range, false);
|
sendMemoryGetCommand(range, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_snapshot.insertMemory(range, memory);
|
m_snapshot.insertMemory(range, memory);
|
||||||
tryAnswerGdbMemoryRequest(true);
|
tryAnswerGdbMemoryRequest(true);
|
||||||
}
|
}
|
||||||
@@ -1267,11 +1325,15 @@ void TcfTrkGdbAdapter::handleReadMemoryUnbuffered(const TcfTrkCommandResult &res
|
|||||||
const QByteArray memory = TcfTrkDevice::parseMemoryGet(result);
|
const QByteArray memory = TcfTrkDevice::parseMemoryGet(result);
|
||||||
const MemoryRange range = result.cookie.value<MemoryRange>();
|
const MemoryRange range = result.cookie.value<MemoryRange>();
|
||||||
|
|
||||||
if (unsigned(memory.size()) != range.size()) {
|
const bool error = !result;
|
||||||
logMessage(_("TEMPORARY: ") + msgMemoryReadError(range.from, range.size()));
|
const bool insufficient = unsigned(memory.size()) != range.size();
|
||||||
logMessage(_("RETRYING UNBUFFERED"));
|
if (error || insufficient) {
|
||||||
const QByteArray ba = "E20";
|
QString msg = error ?
|
||||||
sendGdbServerMessage(ba, msgMemoryReadError(32, range.from).toLatin1());
|
QString::fromLatin1("Error reading memory: %1").arg(result.errorString()) :
|
||||||
|
QString::fromLatin1("Error reading memory (got %1 of %2): %3").
|
||||||
|
arg(memory.size()).arg(range.size()).arg(msgMemoryReadError(range.from, range.size()));
|
||||||
|
logMessage(msg, LogError);
|
||||||
|
sendGdbServerMessage(QByteArray("E20"), msgMemoryReadError(32, range.from).toLatin1());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_snapshot.insertMemory(range, memory);
|
m_snapshot.insertMemory(range, memory);
|
||||||
|
|||||||
@@ -112,9 +112,11 @@ private:
|
|||||||
void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result);
|
void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result);
|
||||||
void reportRegisters();
|
void reportRegisters();
|
||||||
void handleReadRegisters(const tcftrk::TcfTrkCommandResult &result);
|
void handleReadRegisters(const tcftrk::TcfTrkCommandResult &result);
|
||||||
|
void handleRegisterChildren(const tcftrk::TcfTrkCommandResult &result);
|
||||||
void handleAndReportReadRegisters(const tcftrk::TcfTrkCommandResult &result);
|
void handleAndReportReadRegisters(const tcftrk::TcfTrkCommandResult &result);
|
||||||
void handleAndReportReadRegister(const tcftrk::TcfTrkCommandResult &result);
|
void handleAndReportReadRegister(const tcftrk::TcfTrkCommandResult &result);
|
||||||
void handleAndReportReadRegistersAfterStop(const tcftrk::TcfTrkCommandResult &result);
|
void handleAndReportReadRegistersAfterStop(const tcftrk::TcfTrkCommandResult &result);
|
||||||
|
QByteArray stopMessage() const;
|
||||||
void handleAndReportSetBreakpoint(const tcftrk::TcfTrkCommandResult &result);
|
void handleAndReportSetBreakpoint(const tcftrk::TcfTrkCommandResult &result);
|
||||||
void handleClearBreakpoint(const tcftrk::TcfTrkCommandResult &result);
|
void handleClearBreakpoint(const tcftrk::TcfTrkCommandResult &result);
|
||||||
void readMemory(uint addr, uint len, bool buffered);
|
void readMemory(uint addr, uint len, bool buffered);
|
||||||
|
|||||||
@@ -90,24 +90,25 @@ bool TcfTrkCommandError::isError() const
|
|||||||
bool TcfTrkCommandError::parse(const QVector<JsonValue> &values)
|
bool TcfTrkCommandError::parse(const QVector<JsonValue> &values)
|
||||||
{
|
{
|
||||||
// Parse an arbitrary hash (that could as well be a command response)
|
// Parse an arbitrary hash (that could as well be a command response)
|
||||||
// and check for error elements.
|
// and check for error elements. It looks like sometimes errors are appended
|
||||||
|
// to other values.
|
||||||
unsigned errorKeyCount = 0;
|
unsigned errorKeyCount = 0;
|
||||||
clear();
|
clear();
|
||||||
do {
|
do {
|
||||||
if (values.isEmpty() || values.front().type() != JsonValue::Object)
|
if (values.isEmpty() || values.back().type() != JsonValue::Object)
|
||||||
break;
|
break;
|
||||||
foreach (const JsonValue &c, values.front().children()) {
|
foreach (const JsonValue &c, values.back().children()) {
|
||||||
if (c.name() == "Time") {
|
if (c.name() == "Time") {
|
||||||
timeMS = c.data().toULongLong();
|
timeMS = c.data().toULongLong();
|
||||||
errorKeyCount++;
|
errorKeyCount++;
|
||||||
} else if (c.name() == "Code") {
|
} else if (c.name() == "Code") {
|
||||||
code = c.data().toInt();
|
code = c.data().toLongLong();
|
||||||
errorKeyCount++;
|
errorKeyCount++;
|
||||||
} else if (c.name() == "Format") {
|
} else if (c.name() == "Format") {
|
||||||
format = c.data();
|
format = c.data();
|
||||||
errorKeyCount++;
|
errorKeyCount++;
|
||||||
} else if (c.name() == "AltCode") {
|
} else if (c.name() == "AltCode") {
|
||||||
alternativeCode = c.data().toInt();
|
alternativeCode = c.data().toULongLong();
|
||||||
errorKeyCount++;
|
errorKeyCount++;
|
||||||
} else if (c.name() == "AltOrg") {
|
} else if (c.name() == "AltOrg") {
|
||||||
alternativeOrganization = c.data();
|
alternativeOrganization = c.data();
|
||||||
@@ -121,7 +122,7 @@ bool TcfTrkCommandError::parse(const QVector<JsonValue> &values)
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug("TcfTrkCommandError::parse: Found error %d (%u): ", errorFound, errorKeyCount);
|
qDebug("TcfTrkCommandError::parse: Found error %d (%u): ", errorFound, errorKeyCount);
|
||||||
if (!values.isEmpty())
|
if (!values.isEmpty())
|
||||||
qDebug() << values.front().toString();
|
qDebug() << values.back().toString();
|
||||||
}
|
}
|
||||||
return errorFound;
|
return errorFound;
|
||||||
}
|
}
|
||||||
@@ -166,6 +167,7 @@ QString TcfTrkCommandResult::errorString() const
|
|||||||
return rc;
|
return rc;
|
||||||
case FailReply:
|
case FailReply:
|
||||||
str << "NAK";
|
str << "NAK";
|
||||||
|
return rc;
|
||||||
case CommandErrorReply:
|
case CommandErrorReply:
|
||||||
commandError.write(str);
|
commandError.write(str);
|
||||||
break;
|
break;
|
||||||
@@ -211,6 +213,11 @@ QString TcfTrkCommandResult::toString() const
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entry for send queue.
|
||||||
|
enum SpecialHandlingFlags { None =0,
|
||||||
|
FakeRegisterGetMIntermediate = 0x1,
|
||||||
|
FakeRegisterGetMFinal = 0x2 };
|
||||||
|
|
||||||
struct TcfTrkSendQueueEntry
|
struct TcfTrkSendQueueEntry
|
||||||
{
|
{
|
||||||
typedef TcfTrkDevice::MessageType MessageType;
|
typedef TcfTrkDevice::MessageType MessageType;
|
||||||
@@ -218,10 +225,12 @@ struct TcfTrkSendQueueEntry
|
|||||||
explicit TcfTrkSendQueueEntry(MessageType mt,
|
explicit TcfTrkSendQueueEntry(MessageType mt,
|
||||||
int tok,
|
int tok,
|
||||||
Services s,
|
Services s,
|
||||||
const QByteArray &d,
|
const QByteArray &d,
|
||||||
const TcfTrkCallback &cb= TcfTrkCallback(),
|
const TcfTrkCallback &cb= TcfTrkCallback(),
|
||||||
const QVariant &ck = QVariant()) :
|
const QVariant &ck = QVariant(),
|
||||||
messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb) {}
|
unsigned sh = 0) :
|
||||||
|
messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb),
|
||||||
|
specialHandling(sh) {}
|
||||||
|
|
||||||
MessageType messageType;
|
MessageType messageType;
|
||||||
Services service;
|
Services service;
|
||||||
@@ -229,6 +238,7 @@ struct TcfTrkSendQueueEntry
|
|||||||
int token;
|
int token;
|
||||||
QVariant cookie;
|
QVariant cookie;
|
||||||
TcfTrkCallback callback;
|
TcfTrkCallback callback;
|
||||||
|
unsigned specialHandling;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TcfTrkDevicePrivate {
|
struct TcfTrkDevicePrivate {
|
||||||
@@ -246,6 +256,7 @@ struct TcfTrkDevicePrivate {
|
|||||||
QQueue<TcfTrkSendQueueEntry> m_sendQueue;
|
QQueue<TcfTrkSendQueueEntry> m_sendQueue;
|
||||||
TokenWrittenMessageMap m_writtenMessages;
|
TokenWrittenMessageMap m_writtenMessages;
|
||||||
QVector<QByteArray> m_registerNames;
|
QVector<QByteArray> m_registerNames;
|
||||||
|
QVector<QByteArray> m_fakeGetMRegisterValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
TcfTrkDevicePrivate::TcfTrkDevicePrivate() :
|
TcfTrkDevicePrivate::TcfTrkDevicePrivate() :
|
||||||
@@ -454,7 +465,8 @@ int TcfTrkDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tok
|
|||||||
return 236;
|
return 236;
|
||||||
}
|
}
|
||||||
// No callback: remove entry from map, happy
|
// No callback: remove entry from map, happy
|
||||||
if (!it.value().callback) {
|
const unsigned specialHandling = it.value().specialHandling;
|
||||||
|
if (!it.value().callback && specialHandling == 0u) {
|
||||||
d->m_writtenMessages.erase(it);
|
d->m_writtenMessages.erase(it);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -474,13 +486,53 @@ int TcfTrkDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tok
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct result and invoke callback, remove entry from map.
|
// Construct result and invoke callback, remove entry from map.
|
||||||
TcfTrkCallback callback = it.value().callback;
|
|
||||||
TcfTrkCommandResult result(type, it.value().service, it.value().data,
|
TcfTrkCommandResult result(type, it.value().service, it.value().data,
|
||||||
values, it.value().cookie);
|
values, it.value().cookie);
|
||||||
|
|
||||||
|
// Check special handling
|
||||||
|
if (specialHandling) {
|
||||||
|
if (!result) {
|
||||||
|
qWarning("Error in special handling: %s", qPrintable(result.errorString()));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
// Fake 'Registers:getm': Store single register values in cache
|
||||||
|
if ((specialHandling & FakeRegisterGetMIntermediate)
|
||||||
|
|| (specialHandling & FakeRegisterGetMFinal)) {
|
||||||
|
if (result.values.size() == 1) {
|
||||||
|
const int index = int(specialHandling) >> 16;
|
||||||
|
if (index >= 0 && index < d->m_fakeGetMRegisterValues.size()) {
|
||||||
|
const QByteArray base64 = result.values.front().data();
|
||||||
|
d->m_fakeGetMRegisterValues[index] = base64;
|
||||||
|
if (d->m_verbose) {
|
||||||
|
const QString msg = QString::fromLatin1("Caching register value #%1 '%2' 0x%3 (%4)").
|
||||||
|
arg(index).arg(QString::fromAscii(d->m_registerNames.at(index))).
|
||||||
|
arg(QString::fromAscii(QByteArray::fromBase64(base64).toHex())).
|
||||||
|
arg(QString::fromAscii(base64));
|
||||||
|
emitLogMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fake 'Registers:getm' final value: Reformat entries as array and send off
|
||||||
|
if (specialHandling & FakeRegisterGetMFinal) {
|
||||||
|
QByteArray str;
|
||||||
|
str.append('[');
|
||||||
|
foreach(const QByteArray &rval, d->m_fakeGetMRegisterValues)
|
||||||
|
if (!rval.isEmpty()) {
|
||||||
|
if (str.size() > 1)
|
||||||
|
str.append(',');
|
||||||
|
str.append('"');
|
||||||
|
str.append(rval);
|
||||||
|
str.append('"');
|
||||||
|
}
|
||||||
|
str.append(']');
|
||||||
|
result.values[0] = JsonValue(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (it.value().callback)
|
||||||
|
it.value().callback(result);
|
||||||
d->m_writtenMessages.erase(it);
|
d->m_writtenMessages.erase(it);
|
||||||
callback(result);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,9 +611,20 @@ bool TcfTrkDevice::checkOpen()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command,
|
void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command,
|
||||||
const char *commandParameters, int commandParametersLength,
|
const char *commandParameters, // may contain '\0'
|
||||||
|
int commandParametersLength,
|
||||||
const TcfTrkCallback &callBack,
|
const TcfTrkCallback &callBack,
|
||||||
const QVariant &cookie)
|
const QVariant &cookie)
|
||||||
|
{
|
||||||
|
sendTcfTrkMessage(mt, service, command, commandParameters, commandParametersLength,
|
||||||
|
callBack, cookie, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service,
|
||||||
|
const char *command,
|
||||||
|
const char *commandParameters, int commandParametersLength,
|
||||||
|
const TcfTrkCallback &callBack, const QVariant &cookie,
|
||||||
|
unsigned specialHandling)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!checkOpen())
|
if (!checkOpen())
|
||||||
@@ -580,7 +643,7 @@ void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const cha
|
|||||||
data.append('\0');
|
data.append('\0');
|
||||||
if (commandParametersLength)
|
if (commandParametersLength)
|
||||||
data.append(commandParameters, commandParametersLength);
|
data.append(commandParameters, commandParametersLength);
|
||||||
const TcfTrkSendQueueEntry entry(mt, token, service, data, callBack, cookie);
|
const TcfTrkSendQueueEntry entry(mt, token, service, data, callBack, cookie, specialHandling);
|
||||||
d->m_sendQueue.enqueue(entry);
|
d->m_sendQueue.enqueue(entry);
|
||||||
checkSendQueue();
|
checkSendQueue();
|
||||||
}
|
}
|
||||||
@@ -867,7 +930,7 @@ QByteArray TcfTrkDevice::parseMemoryGet(const TcfTrkCommandResult &r)
|
|||||||
// R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"}
|
// R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"}
|
||||||
// Not sure what to make of it.
|
// Not sure what to make of it.
|
||||||
if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object)
|
if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object)
|
||||||
qWarning("Error retrieving memory: %s", r.values.at(1).toString(false).constData());
|
qWarning("TcfTrkDevice::parseMemoryGet(): Error retrieving memory: %s", r.values.at(1).toString(false).constData());
|
||||||
// decode
|
// decode
|
||||||
const QByteArray memory = QByteArray::fromBase64(memoryV.data());
|
const QByteArray memory = QByteArray::fromBase64(memoryV.data());
|
||||||
if (memory.isEmpty())
|
if (memory.isEmpty())
|
||||||
@@ -877,16 +940,97 @@ QByteArray TcfTrkDevice::parseMemoryGet(const TcfTrkCommandResult &r)
|
|||||||
return memory;
|
return memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse register children (array of names)
|
||||||
|
QVector<QByteArray> TcfTrkDevice::parseRegisterGetChildren(const TcfTrkCommandResult &r)
|
||||||
|
{
|
||||||
|
QVector<QByteArray> rc;
|
||||||
|
if (!r || r.values.size() < 1 || r.values.front().type() != JsonValue::Array)
|
||||||
|
return rc;
|
||||||
|
const JsonValue &front = r.values.front();
|
||||||
|
rc.reserve(front.childCount());
|
||||||
|
foreach(const JsonValue &v, front.children())
|
||||||
|
rc.push_back(v.data());
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcfTrkDevice::sendRegistersGetChildrenCommand(const TcfTrkCallback &callBack,
|
||||||
|
const QByteArray &contextId,
|
||||||
|
const QVariant &cookie)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
JsonInputStream str(data);
|
||||||
|
str << contextId;
|
||||||
|
sendTcfTrkMessage(MessageWithReply, RegistersService, "getChildren", data, callBack, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format id of register get request (needs contextId containing process and thread)
|
||||||
|
static inline QByteArray registerId(const QByteArray &contextId, QByteArray id)
|
||||||
|
{
|
||||||
|
QByteArray completeId = contextId;
|
||||||
|
if (!completeId.isEmpty())
|
||||||
|
completeId.append('.');
|
||||||
|
completeId.append(id);
|
||||||
|
return completeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format parameters of register get request
|
||||||
|
static inline QByteArray registerGetData(const QByteArray &contextId, QByteArray id)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
JsonInputStream str(data);
|
||||||
|
str << registerId(contextId, id);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcfTrkDevice::sendRegistersGetCommand(const TcfTrkCallback &callBack,
|
||||||
|
const QByteArray &contextId,
|
||||||
|
QByteArray id,
|
||||||
|
const QVariant &cookie)
|
||||||
|
{
|
||||||
|
sendTcfTrkMessage(MessageWithReply, RegistersService, "get",
|
||||||
|
registerGetData(contextId, id), callBack, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
void TcfTrkDevice::sendRegistersGetMCommand(const TcfTrkCallback &callBack,
|
void TcfTrkDevice::sendRegistersGetMCommand(const TcfTrkCallback &callBack,
|
||||||
const QByteArray &contextId,
|
const QByteArray &contextId,
|
||||||
const QVector<QByteArray> &ids,
|
const QVector<QByteArray> &ids,
|
||||||
const QVariant &cookie)
|
const QVariant &cookie)
|
||||||
{
|
{
|
||||||
// TODO: use "Registers" (which uses base64-encoded values)
|
// TODO: use "Registers" (which uses base64-encoded values)
|
||||||
|
#if 0 // Once 'getm' is supported:
|
||||||
|
// Manually format the complete register ids as an array
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
JsonInputStream str(data);
|
JsonInputStream str(data);
|
||||||
str << contextId << '\0' << ids;
|
str << '[';
|
||||||
sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "get", data, callBack, cookie);
|
const int count = ids.size();
|
||||||
|
for (int r = 0; r < count; r++) {
|
||||||
|
if (r)
|
||||||
|
str << ',';
|
||||||
|
str << registerId(contextId, ids.at(r));
|
||||||
|
}
|
||||||
|
str << ']';
|
||||||
|
sendTcfTrkMessage(MessageWithReply, RegistersService, "getm", data, callBack, cookie);
|
||||||
|
#else
|
||||||
|
// TCF TRK 4.0.5: Fake 'getm' by sending all requests, pass on callback to the last
|
||||||
|
// @Todo: Hopefully, we get 'getm'?
|
||||||
|
const int last = ids.size() - 1;
|
||||||
|
d->m_fakeGetMRegisterValues = QVector<QByteArray>(ids.size(), QByteArray());
|
||||||
|
for (int r = 0; r <= last; r++) {
|
||||||
|
const QByteArray data = registerGetData(contextId, ids.at(r));
|
||||||
|
// Determine special flags along with index
|
||||||
|
unsigned specialFlags = r == last ? FakeRegisterGetMFinal : FakeRegisterGetMIntermediate;
|
||||||
|
const int index = d->m_registerNames.indexOf(ids.at(r));
|
||||||
|
if (index == -1) { // Should not happen
|
||||||
|
qWarning("Invalid register name %s", ids.at(r).constData());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
specialFlags |= unsigned(index) << 16;
|
||||||
|
sendTcfTrkMessage(MessageWithReply, RegistersService, "get",
|
||||||
|
data.constData(), data.size(),
|
||||||
|
r == last ? callBack : TcfTrkCallback(),
|
||||||
|
cookie, specialFlags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
|
void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
|
||||||
@@ -909,23 +1053,25 @@ void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
|
|||||||
// Set register
|
// Set register
|
||||||
void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
||||||
const QByteArray &contextId,
|
const QByteArray &contextId,
|
||||||
const QByteArray &id,
|
QByteArray id,
|
||||||
unsigned value,
|
const QByteArray &value,
|
||||||
const QVariant &cookie)
|
const QVariant &cookie)
|
||||||
{
|
{
|
||||||
// TODO: use "Registers" (which uses base64-encoded values)
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
JsonInputStream str(data);
|
JsonInputStream str(data);
|
||||||
str << contextId << '\0' << QVector<QByteArray>(1, id)
|
if (!contextId.isEmpty()) {
|
||||||
<< '\0' << QVector<QByteArray>(1, QByteArray::number(value, 16));
|
id.prepend('.');
|
||||||
sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "set", data, callBack, cookie);
|
id.prepend(contextId);
|
||||||
|
}
|
||||||
|
str << id << '\0' << value.toBase64();
|
||||||
|
sendTcfTrkMessage(MessageWithReply, RegistersService, "set", data, callBack, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set register
|
// Set register
|
||||||
void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
||||||
const QByteArray &contextId,
|
const QByteArray &contextId,
|
||||||
unsigned registerNumber,
|
unsigned registerNumber,
|
||||||
unsigned value,
|
const QByteArray &value,
|
||||||
const QVariant &cookie)
|
const QVariant &cookie)
|
||||||
{
|
{
|
||||||
if (registerNumber >= (unsigned)d->m_registerNames.size()) {
|
if (registerNumber >= (unsigned)d->m_registerNames.size()) {
|
||||||
|
|||||||
@@ -70,11 +70,11 @@ struct SYMBIANUTILS_EXPORT TcfTrkCommandError {
|
|||||||
bool parse(const QVector<JsonValue> &values);
|
bool parse(const QVector<JsonValue> &values);
|
||||||
|
|
||||||
quint64 timeMS; // Since 1.1.1970
|
quint64 timeMS; // Since 1.1.1970
|
||||||
int code;
|
qint64 code;
|
||||||
QByteArray format; // message
|
QByteArray format; // message
|
||||||
// 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno>
|
// 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno>
|
||||||
QByteArray alternativeOrganization;
|
QByteArray alternativeOrganization;
|
||||||
int alternativeCode;
|
qint64 alternativeCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Answer to a Tcf command passed to the callback. */
|
/* Answer to a Tcf command passed to the callback. */
|
||||||
@@ -112,6 +112,12 @@ http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specific
|
|||||||
http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html
|
http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html
|
||||||
* Commands can be sent along with callbacks that are passed a
|
* Commands can be sent along with callbacks that are passed a
|
||||||
* TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted.
|
* TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted.
|
||||||
|
*
|
||||||
|
* Note: As of 11.8.2010, TCF Trk 4.0.5 does not currently support 'Registers::getm'
|
||||||
|
* (get multiple registers). So, TcfTrkDevice emulates it by sending a sequence of
|
||||||
|
* single commands. As soon as 'Registers::getm' is natively supported, all code
|
||||||
|
* related to 'FakeRegisterGetm' should be removed. The workaround requires that
|
||||||
|
* the register name is known.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject
|
class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject
|
||||||
@@ -130,7 +136,9 @@ public:
|
|||||||
|
|
||||||
unsigned verbose() const;
|
unsigned verbose() const;
|
||||||
|
|
||||||
// Mapping of register names for indices
|
// Mapping of register names to indices for multi-requests.
|
||||||
|
// Register names can be retrieved via 'Registers:getChildren' (requires
|
||||||
|
// context id to be stripped).
|
||||||
QVector<QByteArray> registerNames() const;
|
QVector<QByteArray> registerNames() const;
|
||||||
void setRegisterNames(const QVector<QByteArray>& n);
|
void setRegisterNames(const QVector<QByteArray>& n);
|
||||||
|
|
||||||
@@ -138,6 +146,7 @@ public:
|
|||||||
IODevicePtr takeDevice();
|
IODevicePtr takeDevice();
|
||||||
void setDevice(const IODevicePtr &dp);
|
void setDevice(const IODevicePtr &dp);
|
||||||
|
|
||||||
|
// Send with parameters from string (which may contain '\0').
|
||||||
void sendTcfTrkMessage(MessageType mt, Services service,
|
void sendTcfTrkMessage(MessageType mt, Services service,
|
||||||
const char *command,
|
const char *command,
|
||||||
const char *commandParameters, int commandParametersLength,
|
const char *commandParameters, int commandParametersLength,
|
||||||
@@ -225,7 +234,18 @@ public:
|
|||||||
quint64 start, const QByteArray& data,
|
quint64 start, const QByteArray& data,
|
||||||
const QVariant &cookie = QVariant());
|
const QVariant &cookie = QVariant());
|
||||||
|
|
||||||
// Reply is an array of hexvalues
|
// Get register names (children of context).
|
||||||
|
// It is possible to recurse from thread id down to single registers.
|
||||||
|
void sendRegistersGetChildrenCommand(const TcfTrkCallback &callBack,
|
||||||
|
const QByteArray &contextId,
|
||||||
|
const QVariant &cookie = QVariant());
|
||||||
|
|
||||||
|
// Register get
|
||||||
|
void sendRegistersGetCommand(const TcfTrkCallback &callBack,
|
||||||
|
const QByteArray &contextId,
|
||||||
|
QByteArray id,
|
||||||
|
const QVariant &cookie);
|
||||||
|
|
||||||
void sendRegistersGetMCommand(const TcfTrkCallback &callBack,
|
void sendRegistersGetMCommand(const TcfTrkCallback &callBack,
|
||||||
const QByteArray &contextId,
|
const QByteArray &contextId,
|
||||||
const QVector<QByteArray> &ids,
|
const QVector<QByteArray> &ids,
|
||||||
@@ -240,20 +260,21 @@ public:
|
|||||||
// Set register
|
// Set register
|
||||||
void sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
void sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
||||||
const QByteArray &contextId,
|
const QByteArray &contextId,
|
||||||
const QByteArray &ids,
|
QByteArray ids,
|
||||||
unsigned value,
|
const QByteArray &value, // binary value
|
||||||
const QVariant &cookie = QVariant());
|
const QVariant &cookie = QVariant());
|
||||||
// Set register
|
// Set register
|
||||||
void sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
void sendRegistersSetCommand(const TcfTrkCallback &callBack,
|
||||||
const QByteArray &contextId,
|
const QByteArray &contextId,
|
||||||
unsigned registerNumber,
|
unsigned registerNumber,
|
||||||
unsigned value,
|
const QByteArray &value, // binary value
|
||||||
const QVariant &cookie = QVariant());
|
const QVariant &cookie = QVariant());
|
||||||
|
|
||||||
void sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
|
void sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
|
||||||
const QVariant &cookie = QVariant());
|
const QVariant &cookie = QVariant());
|
||||||
|
|
||||||
static QByteArray parseMemoryGet(const TcfTrkCommandResult &r);
|
static QByteArray parseMemoryGet(const TcfTrkCommandResult &r);
|
||||||
|
static QVector<QByteArray> parseRegisterGetChildren(const TcfTrkCommandResult &r);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value);
|
void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value);
|
||||||
@@ -278,6 +299,12 @@ private:
|
|||||||
int parseMessage(const QByteArray &);
|
int parseMessage(const QByteArray &);
|
||||||
int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens);
|
int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens);
|
||||||
int parseTcfEvent(const QVector<QByteArray> &tokens);
|
int parseTcfEvent(const QVector<QByteArray> &tokens);
|
||||||
|
// Send with parameters from string (which may contain '\0').
|
||||||
|
void sendTcfTrkMessage(MessageType mt, Services service,
|
||||||
|
const char *command,
|
||||||
|
const char *commandParameters, int commandParametersLength,
|
||||||
|
const TcfTrkCallback &callBack, const QVariant &cookie,
|
||||||
|
unsigned specialHandling);
|
||||||
|
|
||||||
TcfTrkDevicePrivate *d;
|
TcfTrkDevicePrivate *d;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
// Names matching the enum
|
// Names matching the enum
|
||||||
static const char *serviceNamesC[] =
|
static const char *serviceNamesC[] =
|
||||||
{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints",
|
{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints",
|
||||||
"Registers", "SimpleRegisters", "Logging",
|
"Registers", "Logging",
|
||||||
"UnknownService"};
|
"UnknownService"};
|
||||||
|
|
||||||
namespace tcftrk {
|
namespace tcftrk {
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ enum Services {
|
|||||||
SettingsService, // non-standard, trk specific
|
SettingsService, // non-standard, trk specific
|
||||||
BreakpointsService,
|
BreakpointsService,
|
||||||
RegistersService,
|
RegistersService,
|
||||||
SimpleRegistersService, // non-standard, trk specific
|
|
||||||
LoggingService, // non-standard, trk specific
|
LoggingService, // non-standard, trk specific
|
||||||
UnknownService
|
UnknownService
|
||||||
}; // Note: Check string array 'serviceNamesC' of same size when modifying this.
|
}; // Note: Check string array 'serviceNamesC' of same size when modifying this.
|
||||||
|
|||||||
Reference in New Issue
Block a user