diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index 48573b7d..380c77fb 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -71,21 +71,20 @@ Message::Message(const bool isSet, const bool isPassive, * @param pos the position in defaults. * @return the default if available and value is empty, or the value. */ -string getDefault(string value, vector* defaults, size_t pos) +string getDefault(const string value, vector* defaults, size_t pos) { if (value.length() > 0 || defaults == NULL || pos > defaults->size()) { return value; } - value = defaults->at(pos); - return value; + return defaults->at(pos); } result_t Message::create(vector::iterator& it, const vector::iterator end, vector< vector >* defaultsRows, DataFieldTemplates* templates, Message*& returnValue) { - // [type],[class],name,[comment],[QQ],ZZ,id,fields... + // [type],[class],name,[comment],[QQ],[ZZ],id,fields... result_t result; bool isSet = false, isPassive = false; string defaultName; @@ -148,24 +147,28 @@ result_t Message::create(vector::iterator& it, const vector::ite return RESULT_ERR_EOF; unsigned char srcAddress; if (*str == 0) - srcAddress = SYN; // no specific source defined + srcAddress = SYN; // no specific source else { srcAddress = parseInt(str, 16, 0, 0xff, result); if (result != RESULT_OK) return result; if (isMaster(srcAddress) == false) - return RESULT_ERR_INVALID_ARG; + return RESULT_ERR_INVALID_ADDR; } str = getDefault(*it++, defaults, defaultPos++).c_str(); if (it == end) - return RESULT_ERR_EOF; - - unsigned char dstAddress = parseInt(str, 16, 0, 0xff, result); - if (result != RESULT_OK) - return result; - if (isValidAddress(dstAddress) == false) - return RESULT_ERR_INVALID_ARG; + return RESULT_ERR_EOF; + unsigned char dstAddress; + if (*str == 0) + dstAddress = SYN; // no specific destination + else { + dstAddress = parseInt(str, 16, 0, 0xff, result); + if (result != RESULT_OK) + return result; + if (isValidAddress(dstAddress) == false) + return RESULT_ERR_INVALID_ADDR; + } vector id; for (int pos=0, useDefaults=1; pos<2; pos++) { // message id (PBSB, optional master data) @@ -229,7 +232,7 @@ result_t Message::create(vector::iterator& it, const vector::ite } } DataField* data = NULL; - result = DataField::create(it, realEnd, templates, data, isSet, dstAddress); + result = DataField::create(it, realEnd, templates, data, isSet, dstAddress==SYN ? ESC : dstAddress); if (result != RESULT_OK) { return result; } @@ -246,9 +249,11 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma result_t result = master.push_back(srcAddress, false, false); if (result != RESULT_OK) return result; - if (dstAddress == SYN) + if (dstAddress == SYN) { + if (m_dstAddress == SYN) + return RESULT_ERR_INVALID_ADDR; result = master.push_back(m_dstAddress, false, false); - else + } else result = master.push_back(dstAddress, false, false); if (result != RESULT_OK) return result; @@ -413,6 +418,29 @@ Message* MessageMap::find(const string& clazz, const string& name, const bool is return NULL; } +deque MessageMap::findAll(const string& clazz, const string& name, const short pb) +{ + deque ret; + + bool checkClass = clazz.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; + Message* message = it->second; + if (checkClass == true && message->getClass() != clazz) + continue; + if (checkName == true && message->getName() != name) + continue; + if (checkPb == true && message->getId()[0] != pb) + continue; + ret.push_back(message); + } + + return ret; +} + Message* MessageMap::find(SymbolString& master) { if (master.size() < 5) diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index f8335d2c..022c4684 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -25,6 +25,7 @@ #include "symbol.h" #include #include +#include #include using namespace std; @@ -48,7 +49,7 @@ public: * false if message can be initiated by any participant. * @param comment the comment. * @param srcAddress the source address, or @a SYN for any (only relevant if passive). - * @param dstAddress the destination address. + * @param dstAddress the destination address, or @a SYN for any (set later). * @param id the primary, secondary, and optional further ID bytes. * @param data the @a DataField for encoding/decoding the message. * @param pollPriority the priority for polling, or 0 for no polling at all. @@ -120,7 +121,7 @@ public: unsigned char getSrcAddress() const { return m_srcAddress; } /** * @brief Get the destination address. - * @return the destination address. + * @return the destination address, or @a SYN for any. */ unsigned char getDstAddress() const { return m_dstAddress; } /** @@ -280,6 +281,15 @@ public: * Note: the caller may not free the returned instance. */ Message* find(const string& clazz, const string& name, const bool isSet, const bool isPassive=false); + /** + * @brief Find all active get @a Message instances for the specified class and name. + * @param class the device class, or empty for any. + * @param name the message name, or empty for any. + * @param pb the primary ID byte, or -1 for any. + * @return the found @a Message instances. + * Note: the caller may not free the returned instances. + */ + deque findAll(const string& clazz, const string& name, const short pb); /** * @brief Find the @a Message instance for the specified master data. * @param master the master @a SymbolString for identifying the @a Message.