diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index df2b3e95..d486e158 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -80,27 +80,23 @@ Message::Message(const string circuit, const string level, const string name, } Message::Message(const string circuit, const string level, const string name, - const bool isWrite, const bool isPassive, const symbol_t pb, const symbol_t sb, - DataField* data, const bool deleteData) - : m_circuit(circuit), m_level(level), m_name(name), m_isWrite(isWrite), - m_isPassive(isPassive), m_comment(), - m_srcAddress(SYN), m_dstAddress(SYN), - m_data(data), m_deleteData(true), + const bool broadcast, DataField* data, const bool deleteData) + : m_circuit(circuit), m_level(level), m_name(name), m_isWrite(broadcast), + m_isPassive(false), m_comment(), + m_srcAddress(SYN), m_dstAddress(broadcast ? BROADCAST : SYN), + m_data(data), m_deleteData(deleteData), m_pollPriority(0), - m_usedByCondition(false), m_isScanMessage(false), m_condition(NULL), + m_usedByCondition(false), m_isScanMessage(true), m_condition(NULL), m_lastUpdateTime(0), m_lastChangeTime(0), m_pollCount(0), m_lastPollTime(0) { m_id.push_back(pb); m_id.push_back(sb); uint64_t key = 0; - if (!isPassive) { - key |= (isWrite ? 0x1fLL : 0x1eLL) << (8 * 7); // special values for active - } - key |= (uint64_t)SYN << (8 * 6); + key |= (broadcast ? 0x1fLL : 0x1eLL) << (8 * 7); // special values for active + key |= (uint64_t)(broadcast ? BROADCAST : SYN) << (8 * 6); key |= (uint64_t)pb << (8 * 5); key |= (uint64_t)sb << (8 * 4); m_key = key; - setScanMessage(); } @@ -473,8 +469,8 @@ result_t Message::create(vector::iterator& it, const vector::ite return RESULT_OK; } -Message* Message::createScanMessage() { - return new Message("scan", "", "", false, false, 0x07, 0x04, DataFieldSet::getIdentFields(), true); +Message* Message::createScanMessage(bool broadcast) { + return new Message("scan", "", "", 0x07, 0x04, broadcast, DataFieldSet::getIdentFields(), !broadcast); } Message* Message::derive(const symbol_t dstAddress, const symbol_t srcAddress, const string circuit) { @@ -1605,6 +1601,9 @@ result_t MessageMap::add(Message* message, bool storeByName) { bool isWrite = message->isWrite(); string circuit = message->getCircuit(); FileReader::tolower(circuit); + if (circuit == "scan") { + m_additionalScanMessages = true; + } string name = message->getName(); FileReader::tolower(name); string nameKey = string(isPassive ? "P" : (isWrite ? "W" : "R")) + circuit + FIELD_SEPARATOR + name; @@ -1833,7 +1832,10 @@ Message* MessageMap::getScanMessage(const symbol_t dstAddress) { if (dstAddress == SYN) { return m_scanMessage; } - if (!isValidAddress(dstAddress, false) || isMaster(dstAddress)) { + if (dstAddress == BROADCAST) { + return m_broadcastScanMessage; + } + if (!isValidAddress(dstAddress, true) || isMaster(dstAddress)) { return NULL; } uint64_t key = m_scanMessage->getDerivedKey(dstAddress); @@ -1937,22 +1939,13 @@ result_t MessageMap::executeInstructions(ostringstream& log, void (*readMessageF void MessageMap::addLoadedFile(symbol_t address, string file, string comment) { if (!file.empty()) { - string fileComment = "\""+file+"\""; - if (!comment.empty()) { - fileComment += " ("+comment+")"; - } - if (m_loadedFiles.find(address) == m_loadedFiles.end()) { - m_loadedFiles[address] = fileComment; - } else { - m_loadedFiles[address] += ", "+fileComment; - } + vector& files = m_loadedFiles[address]; + files.push_back(file); + files.push_back(comment); } } -string MessageMap::getLoadedFiles(symbol_t address) { - if (m_loadedFiles.find(address) == m_loadedFiles.end()) { - return ""; - } +vector& MessageMap::getLoadedFiles(symbol_t address) { return m_loadedFiles[address]; } @@ -2213,6 +2206,7 @@ void MessageMap::clear() { m_conditions.clear(); m_instructions.clear(); m_maxIdLength = 0; + m_additionalScanMessages = false; } Message* MessageMap::getNextPoll() { diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index e7a6f24b..48d045f8 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -138,18 +138,15 @@ class Message { * @param circuit the circuit name, or empty for not storing by name. * @param level the optional access level. * @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. * @param pb the primary ID byte. * @param sb the secondary ID byte. + * @param broadcast true for broadcast scan message, false for scan message to be sent to a slave address. * @param data the @a DataField for encoding/decoding the message. * @param deleteData whether to delete the @a DataField during destruction. */ Message(const string circuit, const string level, const string name, - const bool isWrite, const bool isPassive, const symbol_t pb, const symbol_t sb, - DataField* data, const bool deleteData); + const bool broadcast, DataField* data, const bool deleteData); public: @@ -215,8 +212,9 @@ class Message { /** * Create a new scan @a Message instance. + * @param broadcast true for broadcast scan message, false for scan message to be sent to a slave address. */ - static Message* createScanMessage(); + static Message* createScanMessage(bool broadcast = false); /** * Set that this is a special scanning @a Message instance. @@ -1228,8 +1226,10 @@ class MessageMap : public FileReader { * @param addAll whether to add all messages, even if duplicate. */ explicit MessageMap(const bool addAll = false) : FileReader::FileReader(true), - m_addAll(addAll), m_maxIdLength(0), m_messageCount(0), m_conditionalMessageCount(0), m_passiveMessageCount(0) { + m_addAll(addAll), m_additionalScanMessages(false), m_maxIdLength(0), m_messageCount(0), + m_conditionalMessageCount(0), m_passiveMessageCount(0) { m_scanMessage = Message::createScanMessage(); + m_broadcastScanMessage = Message::createScanMessage(true); } /** @@ -1237,7 +1237,14 @@ class MessageMap : public FileReader { */ virtual ~MessageMap() { clear(); - delete m_scanMessage; + if (m_scanMessage) { + delete m_scanMessage; + m_scanMessage = NULL; + } + if (m_broadcastScanMessage) { + delete m_broadcastScanMessage; + m_broadcastScanMessage = NULL; + } } /** @@ -1275,6 +1282,12 @@ class MessageMap : public FileReader { */ Message* getScanMessage(const symbol_t dstAddress = SYN); + /** + * Return whether additional scan @a Message instances are available. + * @return whether additional scan @a Message instances are available. + */ + bool hasAdditionalScanMessages() { return m_additionalScanMessages; } + /** * Resolve all @a Condition instances. * @param verbose whether to verbosely add all problems to the error message. @@ -1310,10 +1323,9 @@ class MessageMap : public FileReader { /** * Get the loaded files for a participant. * @param address the slave address. - * @return the name of the file(s) loaded for the participant (separated by comma and enclosed in double quotes), - * or empty. + * @return the loaded configuration files (pairs of file name and comment). */ - string getLoadedFiles(symbol_t address); + vector& getLoadedFiles(symbol_t address); /** * Get the stored @a Message instances for the key. @@ -1448,11 +1460,17 @@ class MessageMap : public FileReader { /** whether to add all messages, even if duplicate. */ const bool m_addAll; - /** the @a Message instance used for scanning. */ + /** the @a Message instance used for scanning a slave. */ Message* m_scanMessage; - /** the loaded configuration files by slave address. */ - map m_loadedFiles; + /** the @a Message instance used for sending the broadcast scan request. */ + Message* m_broadcastScanMessage; + + /** whether additional scan @a Message instances are available. */ + bool m_additionalScanMessages; + + /** the loaded configuration files by slave address (pairs of file name and comment). */ + map> m_loadedFiles; /** the maximum ID length used by any of the known @a Message instances. */ size_t m_maxIdLength;