From 27778f2255bace7b5b252bcb8bf5bbb218dfed63 Mon Sep 17 00:00:00 2001 From: john30 Date: Thu, 15 Aug 2019 19:04:51 +0200 Subject: [PATCH] use defines for values in source mask of message key and simplified a bit (in preparation of #278), documentation --- src/lib/ebus/message.cpp | 83 ++++++++++++++++++------------ src/lib/ebus/message.h | 11 ++++ src/lib/ebus/test/test_message.cpp | 8 ++- 3 files changed, 68 insertions(+), 34 deletions(-) mode change 100755 => 100644 src/lib/ebus/test/test_message.cpp diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index df0b19b4..008cb078 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -45,12 +45,24 @@ using std::endl; /** the bit mask for the ID length and combined ID bytes in the message key. */ #define ID_LENGTH_AND_IDS_MASK ((7LL << (8 * 7 + 5)) | 0xffffffffLL) -/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active read message. */ +/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active write message. */ #define ID_SOURCE_ACTIVE_WRITE (0x1fLL << (8 * 7)) -/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active write message. */ +/** the bits in the @a ID_SOURCE_MASK for arbitrary source and active read message. */ #define ID_SOURCE_ACTIVE_READ (0x1eLL << (8 * 7)) +/** + * the bits in the @a ID_SOURCE_MASK for arbitrary source and active write message + * to a master (same value as ID_SOURCE_ACTIVE_WRITE for now). + */ +#define ID_SOURCE_ACTIVE_WRITE_MASTER (0x1fLL << (8 * 7)) + +/** + * the bits in the @a ID_SOURCE_MASK for arbitrary source and active read message + * to a master (same value as ID_SOURCE_ACTIVE_WRITE for now). + */ +#define ID_SOURCE_ACTIVE_READ_MASTER (0x1eLL << (8 * 7)) + /** special value for invalid message key. */ #define INVALID_KEY 0xffffffffffffffffLL @@ -161,7 +173,8 @@ uint64_t Message::createKey(const vector& id, bool isWrite, bool isPas if (isPassive) { key |= (uint64_t)getMasterNumber(srcAddress) << (8 * 7); // 0..25 } else { - key |= (isWrite ? 0x1fLL : 0x1eLL) << (8 * 7); // special values for active + key |= isMaster(dstAddress) ? (isWrite ? ID_SOURCE_ACTIVE_WRITE_MASTER : ID_SOURCE_ACTIVE_READ_MASTER) + : (isWrite ? ID_SOURCE_ACTIVE_WRITE : ID_SOURCE_ACTIVE_READ); // special values for active } key |= (uint64_t)dstAddress << (8 * 6); int exp = 5; @@ -202,7 +215,7 @@ uint64_t Message::createKey(const MasterSymbolString& master, size_t maxIdLength uint64_t Message::createKey(symbol_t pb, symbol_t sb, bool broadcast) { uint64_t key = 0; - key |= (broadcast ? 0x1fLL : 0x1eLL) << (8 * 7); // special values for active + key |= broadcast ? ID_SOURCE_ACTIVE_WRITE : ID_SOURCE_ACTIVE_READ; // special values for active key |= (uint64_t)(broadcast ? BROADCAST : SYN) << (8 * 6); key |= (uint64_t)pb << (8 * 5); key |= (uint64_t)sb << (8 * 4); @@ -1270,6 +1283,7 @@ void ChainedMessage::dumpField(const string& fieldName, bool withConditions, ost * @param sameIdExtAs the optional @a MasterSymbolString to check for having the same ID. * @param onlyAvailable true to include only available messages (default true), false to also include messages that * are currently not available (e.g. due to unresolved or false conditions). + * @return the first available @a Message from the list. */ Message* getFirstAvailable(const vector& messages, const MasterSymbolString* sameIdExtAs, const bool onlyAvailable = true) { @@ -1290,6 +1304,7 @@ Message* getFirstAvailable(const vector& messages, const MasterSymbolS * @param sameIdExtAs the optional @a Message to check for having the same ID. * @param onlyAvailable true to include only available messages (default true), false to also include messages that * are currently not available (e.g. due to unresolved or false conditions). + * @return the first available @a Message from the list. */ Message* getFirstAvailable(const vector& messages, const Message* sameIdExtAs = nullptr, const bool onlyAvailable = true) { @@ -2569,6 +2584,14 @@ void MessageMap::findAll(const string& circuit, const string& name, const string } } +Message* MessageMap::getFirstAvailableFromIterator(const map >::const_iterator& it, + const MasterSymbolString* sameIdExtAs, bool onlyAvailable) const { + if (it != m_messagesByKey.end()) { + return getFirstAvailable(it->second, sameIdExtAs, onlyAvailable); + } + return nullptr; +} + Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination, bool withRead, bool withWrite, bool withPassive, bool onlyAvailable) const { if (anyDestination && master.size() >= 5 && master[4] == 0 && master[2] == 0x07 && master[3] == 0x04) { @@ -2579,6 +2602,7 @@ Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination, if (baseKey == INVALID_KEY) { return nullptr; } + bool isWriteDest = isMaster(master[1]) || master[1] == BROADCAST; size_t maxIdLength = Message::getKeyLength(baseKey); for (size_t idLength = maxIdLength; true; idLength--) { uint64_t key = baseKey; @@ -2594,44 +2618,39 @@ Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination, } } } - map >::const_iterator it; + Message* message; if (withPassive) { - it = m_messagesByKey.find(key); - if (it != m_messagesByKey.end()) { - Message* message = getFirstAvailable(it->second, &master, onlyAvailable); + message = getFirstAvailableFromIterator(m_messagesByKey.find(key), &master, onlyAvailable); + if (message) { + return message; + } + } + if ((key & ID_SOURCE_MASK) != 0) { + key &= ~ID_SOURCE_MASK; + if (withPassive) { + // try again without specific source master + message = getFirstAvailableFromIterator(m_messagesByKey.find(key), &master, onlyAvailable); if (message) { return message; } } - if ((key & ID_SOURCE_MASK) != 0) { - key &= ~ID_SOURCE_MASK; - it = m_messagesByKey.find(key & ~ID_SOURCE_MASK); // try again without specific source master - if (it != m_messagesByKey.end()) { - Message* message = getFirstAvailable(it->second, &master, onlyAvailable); - if (message) { - return message; - } - } - } - } else { - key &= ~ID_SOURCE_MASK; } if (withRead) { - it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_READ); // try again with special value for active read - if (it != m_messagesByKey.end()) { - Message* message = getFirstAvailable(it->second, &master, onlyAvailable); - if (message) { - return message; - } + // try again with special value for active read + message = getFirstAvailableFromIterator( + m_messagesByKey.find(key | (isWriteDest ? ID_SOURCE_ACTIVE_READ_MASTER : ID_SOURCE_ACTIVE_READ)), + &master, onlyAvailable); + if (message) { + return message; } } if (withWrite) { - it = m_messagesByKey.find(key | ID_SOURCE_ACTIVE_WRITE); // try again with special value for active write - if (it != m_messagesByKey.end()) { - Message* message = getFirstAvailable(it->second, &master, onlyAvailable); - if (message) { - return message; - } + // try again with special value for active write + message = getFirstAvailableFromIterator( + m_messagesByKey.find(key | (isWriteDest ? ID_SOURCE_ACTIVE_WRITE_MASTER : ID_SOURCE_ACTIVE_WRITE)), + &master, onlyAvailable); + if (message) { + return message; } } if (idLength == 0) { diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index b987f0ed..0f2a2d13 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -1410,6 +1410,17 @@ class MessageMap : public MappedFileReader { bool completeMatch, bool withRead, bool withWrite, bool withPassive, bool includeEmptyLevel, bool onlyAvailable, time_t since, time_t until, bool changedSince, deque* messages) const; + /** + * Get the first available @a Message from the first map iterator entry. + * @param it the map iterator with list of @a Message instances to check. + * @param sameIdExtAs the optional @a MasterSymbolString to check for having the same ID. + * @param onlyAvailable true to include only available messages (default true), false to also include messages that + * are currently not available (e.g. due to unresolved or false conditions). + * @return the first available @a Message from the first map iterator entry. + */ + Message* getFirstAvailableFromIterator(const map >::const_iterator& it, + const MasterSymbolString* sameIdExtAs, bool onlyAvailable) const; + /** * Find the @a Message instance for the specified master data. * @param master the @a MasterSymbolString for identifying the @a Message. diff --git a/src/lib/ebus/test/test_message.cpp b/src/lib/ebus/test/test_message.cpp old mode 100755 new mode 100644 index 16d54bc0..aea4f361 --- a/src/lib/ebus/test/test_message.cpp +++ b/src/lib/ebus/test/test_message.cpp @@ -173,7 +173,11 @@ int main() { {"w,,x,,,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:6,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "1;1;1;0;0;0", "ff08b509030e0700", "00", "di" }, {"w,,x,,,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:6,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "1;0;0;0;0;1", "ff08b509030e0104", "00", "di" }, {"w,,x,,,,,,b0,,BI0:1,,,,b1,,BI1:1,,,,b2,,BI2:6,,,,c0,,BI0:1,,,,c1,,BI1:1,,,,c2,,BI2:1", "0;0;1;0;1;1", "ff08b509030e0406", "00", "di" }, - {"*r,cir*cuit#level,na*me,com*ment,ff,75,b509,0d", "", "", "", "" }, + {"r,470,ccTimer.Monday,,,15,B515,0002,,,IGN:1,,,,from,,TTM", "", "", "", "M"}, + {"w,470,ccTimer.Monday,,,10,B515,0002,from,,TTM", "", "", "", "kM*"}, + {"", "19:00", "3115b515020002", "080272", "kd"}, + {"", "19:00", "3110b51503000272", "00", "kd"}, + {"*r,cir*cuit#level,na*me,com*ment,ff,75,b509,0d", "", "", "", ""}, {"r,CIRCUIT,NAME,COMMENT,,,,0100,field,,UCH", "r,cirCIRCUITcuit,naNAMEme,comCOMMENTment,ff,75,b509,0d0100,field,s,UCH,,,: field=42", "ff75b509030d0100", "012a", "DN"}, {"r,CIRCUIT,NAME,COMMENT,,,,0100,field,,UCH", // "\"naNAMEme\": {r,cirCIRCUITcuit,naNAMEme,comCOMMENTment,ff,75,b509,0d0100,field,s,UCH,,,: field=42" @@ -420,7 +424,7 @@ int main() { result = message->decodeLastData(false, nullptr, -1, (decodeVerbose?OF_NAMES|OF_UNITS|OF_COMMENTS:0)|(decodeJson?OF_NAMES|OF_JSON:0), &output); if (result != RESULT_OK) { - cout << " \"" << check[2] << "\" / \"" << check[3] << "\": decode error: " + cout << " \"" << check[2] << "\" / \"" << check[3] << "\": decode error " << (message->isWrite() ? "write: " : "read: ") << getResultCode(result) << endl; error = true; continue;