diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index 77031f7d..ca04c7b2 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -94,12 +94,9 @@ result_t ScanRequest::prepare(unsigned char ownMasterAddress, unsigned char dstA bool ScanRequest::notify(result_t result, SymbolString& slave) { unsigned char dstAddress = m_master[1]; - bool append = m_scanResults != NULL && m_scanResults->find(dstAddress) != m_scanResults->end(); ostringstream scanResult; if (result == RESULT_OK) { - if (!append) - scanResult << hex << setw(2) << setfill('0') << static_cast(dstAddress) << UI_FIELD_SEPARATOR; - result = m_message->decode(pt_slaveData, slave, scanResult, 0, append); // decode data + result = m_message->decode(pt_slaveData, slave, scanResult); // decode data } if (result < RESULT_OK) { if (result == RESULT_ERR_TIMEOUT) @@ -109,18 +106,11 @@ bool ScanRequest::notify(result_t result, SymbolString& slave) return false; } - string str = scanResult.str(); - logNotice(lf_bus, "scan: %s", str.c_str()); - if (m_scanResults != NULL) { - if (append) - (*m_scanResults)[dstAddress] += str; - else - (*m_scanResults)[dstAddress] = str; - } + m_busHandler->addScanResult(dstAddress, scanResult.str()); // check for remaining secondary messages - if (m_messages.empty()) { // TODO appears several times - logNotice(lf_bus, "scan completed, retrieved %d answers", m_scanResults->size()); + if (m_messages.empty()) { + logNotice(lf_bus, "scan %2.2x completed", dstAddress); return false; } m_message = m_messages.front(); @@ -146,6 +136,13 @@ bool ActiveBusRequest::notify(result_t result, SymbolString& slave) } +void BusHandler::clear() +{ + m_loadedFiles.clear(); + memset(m_seenAddresses, 0, sizeof(m_seenAddresses)); + m_scanResults.clear(); +} + result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave) { result_t result = RESULT_ERR_NO_SIGNAL; @@ -792,7 +789,7 @@ void BusHandler::receiveCompleted() result_t BusHandler::startScan(bool full) { - Message* scanMessage = m_scanMessage; + Message* scanMessage = m_messages->getScanMessage(); deque messages = m_messages->findAll("scan", ""); for (deque::iterator it = messages.begin(); it < messages.end();) { Message* message = *it++; @@ -803,8 +800,6 @@ result_t BusHandler::startScan(bool full) break; } } - if (scanMessage == NULL) - scanMessage = m_scanMessage; if (scanMessage == NULL) return RESULT_ERR_NOTFOUND; @@ -813,13 +808,13 @@ result_t BusHandler::startScan(bool full) for (unsigned char slave = 1; slave != 0; slave++) { // 0 is known to be a master if (!isValidAddress(slave, false) || isMaster(slave)) continue; - if (!full && m_seenAddresses[slave]==0) { + if (!full && (m_seenAddresses[slave]&SEEN)==0) { unsigned char master = getMasterAddress(slave); // check if we saw the corresponding master already - if (master == SYN || m_seenAddresses[master]==0) + if (master == SYN || (m_seenAddresses[master]&SEEN)==0) continue; } - ScanRequest* request = new ScanRequest(scanMessage, messages, &m_scanResults); + ScanRequest* request = new ScanRequest(scanMessage, messages, this); result_t result = request->prepare(m_ownMasterAddress, slave); if (result != RESULT_OK) { delete request; @@ -830,6 +825,16 @@ result_t BusHandler::startScan(bool full) return RESULT_OK; } +void BusHandler::addScanResult(unsigned char dstAddress, string result) +{ + m_seenAddresses[dstAddress] |= SCANNED; + logNotice(lf_bus, "scan %2.2x: %s", result.c_str()); + if (m_scanResults.find(dstAddress) == m_scanResults.end()) + m_scanResults[dstAddress] = result; + else + m_scanResults[dstAddress] += result; +} + void BusHandler::formatScanResult(ostringstream& output) { bool first = true; @@ -840,6 +845,7 @@ void BusHandler::formatScanResult(ostringstream& output) first = false; else output << endl; + output << hex << setw(2) << setfill('0') << static_cast(slave) << UI_FIELD_SEPARATOR; output << it->second; } } @@ -860,10 +866,21 @@ void BusHandler::formatSeenInfo(ostringstream& output) } if ((m_seenAddresses[address]&SEEN)!=0) output << ", seen"; - if ((m_seenAddresses[address]&SCANNED)!=0) - output << ", scanned"; //TODO add detailed scan info: Manufacturer Ident SWxxxx HWxxxx + if ((m_seenAddresses[address]&SCANNED)!=0) { + output << ", scanned"; + Message* message = m_messages->getScanMessage(address); + if (message!=NULL) { + // add detailed scan info: Manufacturer ID SW HW + output << " \""; + result_t result = message->decodeLastData(output, OF_VERBOSE); + if (result!=RESULT_OK) + output << "\" error: " << getResultCode(result); + else + output << "\""; + } + } if ((m_seenAddresses[address]&LOADED)!=0) - output << ", configured"; + output << ", loaded \"" << m_loadedFiles[address] << "\""; } } } @@ -872,13 +889,20 @@ result_t BusHandler::scanAndWait(unsigned char dstAddress, SymbolString& slave) { if (!isValidAddress(dstAddress, false) || isMaster(dstAddress)) return RESULT_ERR_INVALID_ADDR; + Message* message = m_messages->getScanMessage(dstAddress); + if (message==NULL) { + return RESULT_ERR_NOTFOUND; + } istringstream input; SymbolString master; - result_t result = m_scanMessage->prepareMaster(m_ownMasterAddress, master, input, UI_FIELD_SEPARATOR, dstAddress); + result_t result = message->prepareMaster(m_ownMasterAddress, master, input, UI_FIELD_SEPARATOR, dstAddress); if (result==RESULT_OK) result = sendAndWait(master, slave); - if (result==RESULT_OK) + if (result==RESULT_OK) { m_seenAddresses[dstAddress] |= SCANNED; + ostringstream output; + message->decode(master, slave, output); // just to update the cached data + } return result; } @@ -919,6 +943,7 @@ unsigned char BusHandler::getNextScanAddress(unsigned char lastAddress) { return SYN; } -void BusHandler::setScanConfigLoaded(unsigned char address) { +void BusHandler::setScanConfigLoaded(unsigned char address, string file) { m_seenAddresses[address] |= LOADED; + m_loadedFiles[address] = file; } diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index ff0f2b1e..598756fb 100644 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -174,12 +174,10 @@ public: * Constructor. * @param message the primary query @a Message. * @param messages the optional secondary query @a Message instances (to be queried only when the primary was successful). - * @param scanResults the map in which to store the formatted scan result by slave address. + * @param busHandler the @a BusHandler instance to notify of final scan result. */ - ScanRequest(Message* message, deque messages, - map* scanResults) - : BusRequest(m_master, true), m_message(message), m_messages(messages), - m_scanResults(scanResults) {} + ScanRequest(Message* message, deque messages, BusHandler* busHandler) + : BusRequest(m_master, true), m_message(message), m_messages(messages), m_busHandler(busHandler) {} /** * Destructor. @@ -208,8 +206,8 @@ private: /** the remaining secondary @a Message instances. */ deque m_messages; - /** the map in which to store the formatted scan result by slave address. */ - map* m_scanResults; + /** the @a BusHandler instance to notify of final scan result. */ + BusHandler* m_busHandler; }; @@ -287,9 +285,8 @@ public: m_symPerSec(0), m_maxSymPerSec(0), m_state(bs_noSignal), m_repeat(false), m_command(false), m_commandCrcValid(false), m_response(false), m_responseCrcValid(false), - m_scanMessage(NULL), m_grabUnknownMessages(false) { + m_grabUnknownMessages(false) { memset(m_seenAddresses, 0, sizeof(m_seenAddresses)); - m_scanMessage = new Message(false, false, 0x07, 0x04, DataFieldSet::getIdentFields(), true); } /** @@ -297,10 +294,13 @@ public: */ virtual ~BusHandler() { stop(); - if (m_scanMessage != NULL) - delete m_scanMessage; } + /** + * Clear stored values (e.g. scan results). + */ + void clear(); + /** * Send a message on the bus and wait for the answer. * @param master the escaped @a SymbolString with the master data to send. @@ -321,6 +321,13 @@ public: */ result_t startScan(bool full=false); + /** + * Add a scan result @a string for a scanned slave address. + * @param dstAddress the scanned slave address. + * @param result the scan result @a string to add. + */ + void addScanResult(unsigned char dstAddress, string result); + /** * Format the scan result to the @a ostringstream. * @param output the @a ostringstream to format the scan result to. @@ -387,8 +394,9 @@ public: /** * Set the state of the participant to configuration @a LOADED. * @param address the slave address. + * @param file the file from which the configuration was loaded. */ - void setScanConfigLoaded(unsigned char address); + void setScanConfigLoaded(unsigned char address, string file); private: @@ -509,8 +517,8 @@ private: /** the participating bus addresses seen so far (0 if not seen yet, or combination of @a SEEN bits). */ unsigned char m_seenAddresses[256]; - /** the @a Message instance used for scanning. */ - Message* m_scanMessage; + /** the loaded configuration files by slave address. */ + map m_loadedFiles; /** the scan results by slave address. */ map m_scanResults;