From 0d97462dee761ae8dcefe7a3a09a622ff8dc81bd Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 22 Nov 2015 14:19:38 +0100 Subject: [PATCH] extended "-i" parameter of find command to accept further ID parts --- src/ebusd/mainloop.cpp | 46 ++++++++++++++++++++--------- src/lib/ebus/message.cpp | 62 +++++++++++++++++++++++----------------- src/lib/ebus/message.h | 20 +++++++++---- 3 files changed, 82 insertions(+), 46 deletions(-) diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index da7b217a..2cfa57a9 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -647,7 +647,7 @@ string MainLoop::executeFind(vector &args) bool verbose = false, configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false; vector columns; string circuit; - short pb = -1; + vector id; while (args.size() > argPos && args[argPos][0] == '-') { if (args[argPos] == "-v") verbose = true; @@ -706,16 +706,18 @@ string MainLoop::executeFind(vector &args) onlyWithData = true; else if (args[argPos] == "-i") { argPos++; - if (argPos >= args.size()) { + if (argPos >= args.size() || !id.empty()) { argPos = 0; // print usage break; } - const char* str = args[argPos].c_str(); - result_t result = RESULT_OK; - pb = (short)parseInt(str+2, 16, 0, 0xff, result); + result_t result = Message::parseId(args[argPos], id); if (result != RESULT_OK) { return getResultCode(result); } + if (id.empty()) { + argPos = 0; // print usage + break; + } } else if (args[argPos] == "-c") { argPos++; @@ -732,14 +734,14 @@ string MainLoop::executeFind(vector &args) argPos++; } if (argPos == 0 || args.size() < argPos || args.size() > argPos + 1) - return "usage: find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" + return "usage: find [-v] [-r] [-w] [-p] [-d] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" " Find message(s).\n" " -v be verbose (append destination address and update time)\n" " -r limit to active read messages (default: read + passive)\n" " -w limit to active write messages (default: read + passive)\n" " -p limit to passive messages (default: read + passive)\n" " -d only include messages with actual data\n" - " -i PB limit to messages with primary command byte PB (in hex)\n" + " -i ID limit to messages with ID (in hex, PB, SB and further ID bytes)\n" " -f list messages in CSV configuration file format\n" " -F COL[,COL]* list messages in the specified format\n" " (COL: type,circuit,name,comment,qq,zz,pbsb,id,fields)\n" @@ -748,7 +750,7 @@ string MainLoop::executeFind(vector &args) " NAME the NAME of the messages to find (or a part thereof without '-e')"; deque messages = m_messages->findAll( - circuit, args.size() == argPos ? "" : args[argPos], pb, exact, withRead, withWrite, withPassive + circuit, args.size() == argPos ? "" : args[argPos], exact, withRead, withWrite, withPassive ); bool found = false; @@ -756,6 +758,22 @@ string MainLoop::executeFind(vector &args) char str[32]; for (deque::iterator it = messages.begin(); it < messages.end();) { Message* message = *it++; + if (!id.empty()) { + vector msgId = message->getId(); + if (id.size()>msgId.size()) { + continue; + } + bool mismatch = false; + for (size_t pos = 0; posgetLastUpdateTime(); if (onlyWithData && lastup == 0) continue; @@ -1009,7 +1027,7 @@ string MainLoop::executeHelp() " Read hex message: read [-f] [-m SECONDS] [-c CIRCUIT] -h ZZPBSBNNDx\n" " write|w Write value(s): write [-d ZZ] [-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] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" + " find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" " listen|l Listen for updates: listen [stop]\n" " state|s Report bus state\n" " info|i Report information about the daemon, the configuration, and seen devices.\n" @@ -1039,12 +1057,12 @@ string MainLoop::executeGet(vector &args, bool& connected) int type = -1; if (strncmp(uri.c_str(), "/data/", 6) == 0) { - string clazz = "", name = ""; + string circuit = "", name = ""; size_t pos = uri.find('/', 6); if (pos == string::npos) { - clazz = uri.substr(6); + circuit = uri.substr(6); } else { - clazz = uri.substr(6, pos-6); + circuit = uri.substr(6, pos-6); name = uri.substr(pos+1); } time_t since = 0; @@ -1080,7 +1098,7 @@ string MainLoop::executeGet(vector &args, bool& connected) break; } } - deque messages = m_messages->findAll(clazz, name, -1, exact, true, false, true); + deque messages = m_messages->findAll(circuit, name, exact, true, false, true); bool first = true; result << "{"; @@ -1243,7 +1261,7 @@ string MainLoop::getUpdates(time_t since, time_t until) ostringstream result; deque messages; - messages = m_messages->findAll("", "", -1, false, true, true, true); + messages = m_messages->findAll("", "", false, true, true, true); for (deque::iterator it = messages.begin(); it < messages.end();) { Message* message = *it++; diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index cc6841e2..4287a52d 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -70,10 +70,11 @@ Message::Message(const string circuit, const string name, m_key = key; } -Message::Message(const bool isWrite, const bool isPassive, +Message::Message(const string circuit, const string name, + const bool isWrite, const bool isPassive, const unsigned char pb, const unsigned char sb, DataField* data, const bool deleteData) - : m_circuit(), m_name(), m_isWrite(isWrite), + : m_circuit(circuit), m_name(name), m_isWrite(isWrite), m_isPassive(isPassive), m_comment(), m_srcAddress(SYN), m_dstAddress(SYN), m_data(data), m_deleteData(true), @@ -108,6 +109,31 @@ string getDefault(const string value, vector* defaults, size_t pos) return defaults->at(pos); } +result_t Message::parseId(string input, vector& id) +{ + istringstream in(input); + while (!in.eof()) { + while (in.peek() == ' ') + in.get(); + if (in.eof()) // no more digits + break; + input.clear(); + input.push_back((char)in.get()); + if (in.eof()) { + return RESULT_ERR_INVALID_ARG; // too short hex + } + input.push_back((char)in.get()); + + result_t result; + unsigned char value = (unsigned char)parseInt(input.c_str(), 16, 0, 0xff, result); + if (result != RESULT_OK) { + return result; // invalid hex value + } + id.push_back(value); + } + return RESULT_OK; +} + result_t Message::create(vector::iterator& it, const vector::iterator end, vector< vector >* defaultsRows, Condition* condition, const string& filename, DataFieldTemplates* templates, vector& messages) @@ -226,25 +252,9 @@ result_t Message::create(vector::iterator& it, const vector::ite else token = getDefault("", defaults, defaultPos).append(token); } - istringstream input(token); - while (!input.eof()) { - while (input.peek() == ' ') - input.get(); - if (input.eof()) // no more digits - break; - token.clear(); - token.push_back((char)input.get()); - if (input.eof()) { - return RESULT_ERR_INVALID_ARG; // to short hex - } - token.push_back((char)input.get()); - - unsigned char value = (unsigned char)parseInt(token.c_str(), 16, 0, 0xff, result); - if (result != RESULT_OK) { - return result; // invalid hex value - } - id.push_back(value); - } + result = parseId(token, id); + if (result!=RESULT_OK) + return result; if (pos == 0 && id.size() != 2) return RESULT_ERR_INVALID_ARG; // missing/to short/to long PBSB @@ -1064,7 +1074,7 @@ Message* MessageMap::find(const string& circuit, const string& name, const bool return NULL; } -deque MessageMap::findAll(const string& circuit, const string& name, const short pb, const bool completeMatch, +deque MessageMap::findAll(const string& circuit, const string& name, const bool completeMatch, const bool withRead, const bool withWrite, const bool withPassive) { deque ret; @@ -1074,7 +1084,6 @@ deque MessageMap::findAll(const string& circuit, const string& name, c FileReader::tolower(lname); bool checkCircuit = lcircuit.length() > 0; bool checkName = name.length() > 0; - bool checkPb = pb >= 0; for (map >::iterator it = m_messagesByName.begin(); it != m_messagesByName.end(); it++) { if (it->first[0] == '-') // avoid duplicates: instances stored multiple times have a key starting with "-" continue; @@ -1093,8 +1102,6 @@ deque MessageMap::findAll(const string& circuit, const string& name, c if (completeMatch ? (check != lname) : (check.find(lname) == check.npos)) continue; } - if (checkPb && message->getId()[0] != pb) - continue; if (message->isPassive()) { if (!withPassive) continue; @@ -1184,7 +1191,7 @@ void MessageMap::invalidateCache(Message* message) if (pos!=string::npos) circuit.resize(pos); string name = message->getName(); - deque messages = findAll(circuit, name, -1, false, true, true, true); + deque messages = findAll(circuit, name, false, true, true, true); for (deque::iterator it = messages.begin(); it != messages.end(); it++) { if (*it==message) continue; @@ -1244,7 +1251,8 @@ void MessageMap::clear() for (map >::iterator it = m_messagesByKey.begin(); it != m_messagesByKey.end(); it++) { vector keyMessages = it->second; for (vector::iterator kit = keyMessages.begin(); kit != keyMessages.end(); kit++) { - delete *kit; + Message* message = *kit; + delete message; } keyMessages.clear(); } diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 955b9afb..a590293b 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -94,7 +94,9 @@ public: Condition* condition=NULL); /** - * Construct a new temporary instance. + * Construct a new simple instance (e.g. for scanning). + * @param circuit the circuit name, or empty for not storing by name. + * @param name the message name (unique within the same circuit and type), or empty for not storing by name. * @param isWrite whether this is a write message. * @param isPassive true if message can only be initiated by a participant other than us, * false if message can be initiated by any participant. @@ -103,7 +105,8 @@ public: * @param data the @a DataField for encoding/decoding the message. * @param deleteData whether to delete the @a DataField during destruction. */ - Message(const bool isWrite, const bool isPassive, + Message(const string circuit, const string name, + const bool isWrite, const bool isPassive, const unsigned char pb, const unsigned char sb, DataField* data, const bool deleteData); @@ -112,6 +115,14 @@ public: */ virtual ~Message() { if (m_deleteData) delete m_data; } + /** + * Parse an ID part from the input @a string. + * @param input the input @a string, hex digits optionally separated by space. + * @param id the vector to which to add the parsed values. + * @return @a RESULT_OK on success, or an error code. + */ + static result_t parseId(string input, vector& id); + /** * Factory method for creating new instances. * @param it the iterator to traverse for the definition parts. @@ -644,7 +655,7 @@ public: MessageMap(const bool addAll=false) : FileReader::FileReader(true), m_addAll(addAll), m_maxIdLength(0), m_messageCount(0), m_conditionalMessageCount(0), m_passiveMessageCount(0) { - m_scanMessage = new Message(false, false, 0x07, 0x04, DataFieldSet::getIdentFields(), true); + m_scanMessage = new Message("scan", "ident", false, false, 0x07, 0x04, DataFieldSet::getIdentFields(), true); } /** @@ -720,7 +731,6 @@ public: * Find all active get @a Message instances for the specified circuit and name. * @param circuit the circuit name, or empty for any. * @param name the message name, or empty for any. - * @param pb the primary ID byte, or -1 for any (default any). * @param completeMatch false to also include messages where the circuit and name matches only a part of the given circuit and name (default true). * @param withRead true to include read messages (default true). * @param withWrite true to include write messages (default false). @@ -728,7 +738,7 @@ public: * @return the found @a Message instances. * Note: the caller may not free the returned instances. */ - deque findAll(const string& circuit, const string& name, const short pb=-1, const bool completeMatch=true, + deque findAll(const string& circuit, const string& name, const bool completeMatch=true, const bool withRead=true, const bool withWrite=false, const bool withPassive=false); /**