diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index b6e9eeb6..836c6483 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -733,6 +733,16 @@ void BusHandler::receiveCompleted() logNotice(lf_update, "unknown MM cmd: %s", m_command.getDataStr().c_str()); else logNotice(lf_update, "unknown MS cmd: %s / %s", m_command.getDataStr().c_str(), m_response.getDataStr().c_str()); + + if (m_grabUnknownMessages) { + string data; + string key = data = m_command.getDataStr(); + if (key.length() > 2*(1+1+2+1+4)) + key = key.substr(0, 2*(1+1+2+1+4)); // QQZZPBSBNN + up to 4 DD bytes + if (dstAddress != BROADCAST && !master) + data += " / " + m_response.getDataStr(); + m_grabbedUnknownMessages[key] = data; + } } else { string circuit = message->getCircuit(); @@ -816,3 +826,25 @@ void BusHandler::formatScanResult(ostringstream& output) } } } + +void BusHandler::enableGrab(bool enable) +{ + m_grabUnknownMessages = enable; + m_grabbedUnknownMessages.clear(); +} + +void BusHandler::formatGrabResult(ostringstream& output) +{ + if (!m_grabUnknownMessages) { + output << "grab disabled"; + } else { + bool first = true; + for (map::iterator it = m_grabbedUnknownMessages.begin(); it != m_grabbedUnknownMessages.end(); it++) { + if (first) + first = false; + else + output << endl; + output << it->second; + } + } +} diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index 021ef1ad..002f54d8 100644 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -279,7 +279,7 @@ public: m_symPerSec(0), m_maxSymPerSec(0), m_state(bs_noSignal), m_repeat(false), m_command(false), m_commandCrcValid(false), m_response(false), m_responseCrcValid(false), - m_scanMessage(NULL) { + m_scanMessage(NULL), m_grabUnknownMessages(false) { memset(m_seenAddresses, 0, sizeof(m_seenAddresses)); } @@ -318,6 +318,18 @@ public: */ void formatScanResult(ostringstream& output); + /** + * Start or stop grabbing unknown messages. + * @param enable true to enable grabbing, false to disable it. + */ + void enableGrab(bool enable=true); + + /** + * Format the grabbed unknown messages to the @a ostringstream. + * @param output the @a ostringstream to format the messages to. + */ + void formatGrabResult(ostringstream& output); + /** * Return true when a signal on the bus is available. * @return true when a signal on the bus is available. @@ -461,6 +473,12 @@ private: /** the scan results by slave address. */ map m_scanResults; + /** whether to grab unknown messages. */ + bool m_grabUnknownMessages; + + /** the grabbed unknown messages by ID prefix (QQZZPBSBNNDD with up to 4 DD bytes).*/ + map m_grabbedUnknownMessages; + }; diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index e3507c13..fa6c37b0 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -101,7 +101,10 @@ void MainLoop::run() result = decodeMessage(data, connected, listening, running); logNotice(lf_main, "<<< %s", result.c_str()); - result += "\n\n"; + if (result.length() == 0) + result = "\n"; + else + result += "\n\n"; } if (listening) { result += getUpdates(since, until); @@ -167,6 +170,8 @@ string MainLoop::decodeMessage(const string& data, bool& connected, bool& listen return executeListen(args, listening); if (strcasecmp(str, "S") == 0 || strcasecmp(str, "STATE") == 0) return executeState(args); + if (strcasecmp(str, "G") == 0 || strcasecmp(str, "GRAB") == 0) + return executeGrab(args); if (strcasecmp(str, "SCAN") == 0) return executeScan(args); if (strcasecmp(str, "LOG") == 0) @@ -590,6 +595,31 @@ string MainLoop::executeState(vector &args) return "no signal"; } +string MainLoop::executeGrab(vector &args) +{ + if (args.size() == 1) { + m_busHandler->enableGrab(); + + return getResultCode(RESULT_OK); + } + + if (args.size() == 2 && strcasecmp(args[1].c_str(), "STOP") == 0) { + m_busHandler->enableGrab(false); + + return getResultCode(RESULT_OK); + } + + if (args.size() == 2 && strcasecmp(args[1].c_str(), "RESULT") == 0) { + ostringstream result; + m_busHandler->formatGrabResult(result); + return result.str(); + } + + return "usage: grab [stop]\n" + " or: grab result\n" + " Grab unknown messages or stop it, or report the seen unknown messages."; +} + string MainLoop::executeScan(vector &args) { if (args.size() == 1) { @@ -699,24 +729,26 @@ string MainLoop::executeQuit(vector &args, bool& connected) string MainLoop::executeHelp() { return "usage:\n" - " read|r Read value(s): read [-v] [-f] [-m SECONDS] [-d ZZ] [-c CIRCUIT] NAME [FIELD[.N]]\n" - " write|w Write value(s): write [-c] CIRCUIT NAME [VALUE[;VALUE]*]\n" - " Write hex message: write -h ZZPBSBNNDx'\n" - " find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CIRCUIT] [NAME]\n" - " listen|l Listen for updates: listen [stop]\n" + " read|r Read value(s): read [-v] [-f] [-m SECONDS] [-d ZZ] [-c CIRCUIT] NAME [FIELD[.N]]\n" + " write|w Write value(s): write [-c] CIRCUIT NAME [VALUE[;VALUE]*]\n" + " Write hex message: write -h ZZPBSBNNDx'\n" + " find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CIRCUIT] [NAME]\n" + " listen|l Listen for updates: listen [stop]\n" " state|s Report bus state\n" - " scan Scan slaves: scan [full]\n" - " Report scan result: scan result\n" - " log Set log area(s): log areas AREA[,AREA*]\n" - " AREA: main|network|bus|update|all\n" - " Set log level: log level LEVEL\n" - " LEVEL: error|notice|info|debug\n" + " grab|g Grab unknown messages: grab [stop]\n" + " Report the messages: grab result\n" + " scan Scan slaves: scan [full]\n" + " Report scan result: scan result\n" + " log Set log area(s): log areas AREA[,AREA*]\n" + " AREA: main|network|bus|update|all\n" + " Set log level: log level LEVEL\n" + " LEVEL: error|notice|info|debug\n" " raw Toggle logging raw bytes\n" " dump Toggle dumping raw bytes\n" " reload Reload CSV config files\n" " stop Stop the daemon\n" " quit|q Close connection\n" - " help|h Print help help [COMMAND]"; + " help|h Print help help [COMMAND]"; } string MainLoop::getUpdates(time_t since, time_t until) diff --git a/src/ebusd/mainloop.h b/src/ebusd/mainloop.h index 96310c2f..4b26b636 100644 --- a/src/ebusd/mainloop.h +++ b/src/ebusd/mainloop.h @@ -129,6 +129,13 @@ private: */ string executeState(vector &args); + /** + * Execute the grab command. + * @param args the arguments passed to the command (starting with the command itself), or empty for help. + * @return the result string. + */ + string executeGrab(vector &args); + /** * Execute the scan command. * @param args the arguments passed to the command (starting with the command itself), or empty for help.