diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index 563ef425..b9b2aa57 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -808,19 +808,33 @@ result_t BusHandler::setState(BusState state, result_t result, bool firstRepetit void BusHandler::addSeenAddress(unsigned char address) { - if (!isValidAddress(address, false)) + if (!isValidAddress(address, false)) { return; + } if (!isMaster(address)) { + if (!m_device->isReadOnly() && address==m_ownSlaveAddress) { + if (!m_addressConflict) { + m_addressConflict = true; + logError(lf_bus, "own slave address %2.2x is used by another participant", address); + } + } m_seenAddresses[address] |= SEEN; address = getMasterAddress(address); - if (address==SYN) + if (address==SYN) { return; + } } if ((m_seenAddresses[address]&SEEN)==0) { - if (!m_answer || address!=m_ownMasterAddress) { + if (!m_device->isReadOnly() && address==m_ownMasterAddress) { + if (!m_addressConflict) { + m_addressConflict = true; + logError(lf_bus, "own master address %2.2x is used by another participant", address); + } + } else { m_masterCount++; - if (m_autoLockCount && m_masterCount>m_lockCount) + if (m_autoLockCount && m_masterCount>m_lockCount) { m_lockCount = m_masterCount; + } logNotice(lf_bus, "new master %2.2x, master count %d", address, m_masterCount); } m_seenAddresses[address] |= SEEN; @@ -1010,7 +1024,7 @@ void BusHandler::formatSeenInfo(ostringstream& output) unsigned char address = 0; for (int index=0; index<256; index++, address++) { if (isValidAddress(address, false) - && ((m_seenAddresses[address]&SEEN)!=0 || address==m_ownMasterAddress || address==m_ownSlaveAddress)) { + && ((m_seenAddresses[address]&SEEN)!=0 || (!m_device->isReadOnly() && (address==m_ownMasterAddress || address==m_ownSlaveAddress)))) { output << endl << "address " << setfill('0') << setw(2) << hex << static_cast(address); unsigned char master; if (isMaster(address)) { @@ -1022,12 +1036,12 @@ void BusHandler::formatSeenInfo(ostringstream& output) } if (master != SYN) output << " #" << setw(0) << dec << static_cast(getMasterNumber(master)); - if (address==m_ownMasterAddress || (m_answer && address==m_ownSlaveAddress)) { + if (!m_device->isReadOnly() && (address==m_ownMasterAddress || address==m_ownSlaveAddress)) { output << ", ebusd"; if (m_answer) { output << " (answering)"; } - if ((m_seenAddresses[address]&SEEN)!=0) { + if (m_addressConflict && (m_seenAddresses[address]&SEEN)!=0) { output << ", conflict"; } } @@ -1088,7 +1102,7 @@ bool BusHandler::enableGrab(bool enable) return false; } if (!enable) { - m_grabbedMessages.clear(); // TODO check + m_grabbedMessages.clear(); } m_grabMessages = enable; return true; diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index 3d899442..e642f346 100644 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -363,10 +363,11 @@ public: const unsigned int lockCount, const bool generateSyn, const unsigned int pollInterval) : WaitThread(), m_device(device), m_reconnect(false), m_messages(messages), - m_ownMasterAddress(ownAddress), m_ownSlaveAddress((unsigned char)(ownAddress+5)), m_answer(answer), + m_ownMasterAddress(ownAddress), m_ownSlaveAddress((unsigned char)(ownAddress+5)), + m_addressConflict(false), m_answer(answer), m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries), m_transferLatency(transferLatency), m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout), - m_masterCount(1), m_autoLockCount(lockCount==0), m_lockCount(lockCount<=3 ? 3 : lockCount), m_remainLockCount(m_autoLockCount), + m_masterCount(device->isReadOnly()?0:1), m_autoLockCount(lockCount==0), m_lockCount(lockCount<=3 ? 3 : lockCount), m_remainLockCount(m_autoLockCount), m_generateSynInterval(generateSyn ? SYN_TIMEOUT*getMasterNumber(ownAddress)+SYMBOL_DURATION : 0), m_pollInterval(pollInterval), m_lastReceive(0), m_lastPoll(0), m_currentRequest(NULL), m_runningScans(0), m_nextSendPos(0), @@ -566,6 +567,9 @@ private: /** whether to answer queries for the own master/slave address. */ const bool m_answer; + /** set to @p true once an address conflict with the own addresses was detected. */ + bool m_addressConflict; + /** the number of times a send is repeated due to lost arbitration. */ const unsigned int m_busLostRetries;