From c0c1cf3966f0bc2b29108d977756f3428a1b3bf9 Mon Sep 17 00:00:00 2001 From: john30 Date: Sat, 6 Dec 2014 23:41:14 +0100 Subject: [PATCH] allow passive messages to be found as well, added leadingSeparator to decode(), fixed default part for passive set --- src/lib/ebus/message.cpp | 61 +++++++++++++++--------------- src/lib/ebus/message.h | 6 ++- src/lib/ebus/test/test_message.cpp | 3 +- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index d233c5a7..1ac94290 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -113,7 +113,7 @@ result_t Message::create(vector::iterator& it, const vector::ite defaultsChar = 'r'; } else { // any other: passive set/get isPassive = true; - isSet = strncasecmp(str+1, "R", 1) == 0; + isSet = strncasecmp(str+1, "W", 1) == 0; defaultsChar = str[0]; } @@ -272,14 +272,14 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma } result_t Message::decode(const PartType partType, SymbolString& data, - ostringstream& output, char separator) + ostringstream& output, bool leadingSeparator, char separator) { unsigned char offset; if (partType == pt_masterData) offset = m_id.size() - 2; else offset = 0; - result_t result = m_data->read(partType, data, offset, output, false, false, separator); + result_t result = m_data->read(partType, data, offset, output, leadingSeparator, false, separator); if (result != RESULT_OK) return result; /*if (m_isPassive == false && answer == true) { @@ -294,35 +294,36 @@ result_t Message::decode(const PartType partType, SymbolString& data, result_t MessageMap::add(Message* message) { - if (message->isPassive() == false) { - bool isSet = message->isSet(); - string clazz = message->getClass(); - string name = message->getName(); - string key = string(isSet ? "W" : "R") + clazz + ";" + name; - map::iterator nameIt = m_messagesByName.find(key); - if (nameIt != m_messagesByName.end()) { + unsigned long long pkey = message->getKey(); + bool isPassive = message->isPassive(); + if (isPassive == true) { + map::iterator keyIt = m_passiveMessagesByKey.find(pkey); + if (keyIt != m_passiveMessagesByKey.end()) { return RESULT_ERR_DUPLICATE; // duplicate key } - - m_messagesByName[key] = message; - - key = string(isSet ? "-W" : "-R") + name; // also store without class - m_messagesByName[key] = message; - return RESULT_OK; } - - unsigned long long key = message->getKey(); - map::iterator keyIt = m_passiveMessagesByKey.find(key); - if (keyIt != m_passiveMessagesByKey.end()) { + bool isSet = message->isSet(); + string clazz = message->getClass(); + string name = message->getName(); + string key = string(isPassive ? "P" : (isSet ? "W" : "R")) + clazz + ";" + name; + map::iterator nameIt = m_messagesByName.find(key); + if (nameIt != m_messagesByName.end()) { return RESULT_ERR_DUPLICATE; // duplicate key } - unsigned char idLength = message->getId().size() - 2; - if (idLength < m_minIdLength) - m_minIdLength = idLength; - if (idLength > m_maxIdLength) - m_maxIdLength = idLength; - m_passiveMessagesByKey[key] = message; + m_messagesByName[key] = message; + + key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // also store without class + m_messagesByName[key] = message; // last key without class overrides previous + + if (message->isPassive() == true) { + unsigned char idLength = message->getId().size() - 2; + if (idLength < m_minIdLength) + m_minIdLength = idLength; + if (idLength > m_maxIdLength) + m_maxIdLength = idLength; + m_passiveMessagesByKey[pkey] = message; + } return RESULT_OK; } @@ -353,14 +354,14 @@ result_t MessageMap::addFromFile(vector& row, DataFieldTemplates* arg, v return result; } -Message* MessageMap::find(const string& clazz, const string& name, const bool isSet) +Message* MessageMap::find(const string& clazz, const string& name, const bool isSet,const bool isPassive) { - string key; for (int i=0; i<2; i++) { + string key; if (i==0) - key = string(isSet ? "W" : "R") + clazz + ";" + name; + key = string(isPassive ? "P" : (isSet ? "W" : "R")) + clazz + ";" + name; else - key = string(isSet ? "-W" : "-R") + name; // second try: without class + key = string(isPassive ? "-P;" : (isSet ? "-W;" : "-R;")) + name; // second try: without class map::iterator it = m_messagesByName.find(key); if (it != m_messagesByName.end()) return it->second; diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 1338bd4a..6e10b64a 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -137,11 +137,12 @@ public: * @param partType the @a PartType of the data. * @param data the unescaped data @a SymbolString for reading binary data. * @param output the @a ostringstream to append the formatted value to. + * @param leadingSeparator whether to prepend a separator before the formatted value. * @param separator the separator character between multiple fields. * @return @a RESULT_OK on success, or an error code. */ result_t decode(const PartType partType, SymbolString& data, - ostringstream& output, char separator=';'); + ostringstream& output, bool leadingSeparator=false, char separator=';'); private: @@ -200,10 +201,11 @@ public: * @param class the optional device class. * @param name the message name. * @param isSet whether this is a set message. + * @param isPassive whether this is a passive message. * @return the @a Message instance, or NULL. * Note: the caller may not free the returned instance. */ - Message* find(const string& clazz, const string& name, const bool isSet); + Message* find(const string& clazz, const string& name, const bool isSet, const bool isPassive=false); /** * @brief Find the @a Message instance for the specified master data. * @param master the master @a SymbolString for identifying the @a Message. diff --git a/src/lib/ebus/test/test_message.cpp b/src/lib/ebus/test/test_message.cpp index 5509a8f5..dbd69e08 100644 --- a/src/lib/ebus/test/test_message.cpp +++ b/src/lib/ebus/test/test_message.cpp @@ -52,6 +52,7 @@ int main() {"r;ehp;time;;;08;b509;0d2800;;;time", "15:00:17", "ff08b509030d2800ea", "0311000f00", "m"}, {"r;ehp;date;;;08;b509;0d2900;;;hda:3", "23.11.2014", "ff08b509030d290071", "03170b0e5a", "m"}, {"u;ehp;ActualEnvironmentPower;Energiebezug;;08;B509;29BA00;;s;IGN:2;;;;;s;power", "8", "1008b5090329ba00", "03ba0008", "pm"}, + {"uw;ehp;test;Test;;08;B5de;ab;;;power;;;;;s;hex:1", "8;39", "1008b5de02ab08", "0139", "pm"}, {"","55.50;ok","1025b50903290000","050000780300",""}, {"","no;25","10feb505042700190023","",""}, }; @@ -151,7 +152,7 @@ int main() ostringstream output; result = message->decode(pt_masterData, mstr, output); if (result == RESULT_OK) - result = message->decode(pt_slaveData, sstr, output); + result = message->decode(pt_slaveData, sstr, output, output.str().empty() == false); if (result != RESULT_OK) { cout << " \"" << inputStr << "\": decode error: " << getResultCode(result) << endl;