diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index 49f58794..873030ee 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -252,7 +252,7 @@ void BusHandler::run() time_t lastTime; time(&lastTime); do { - if (m_device->isValid()) { + if (m_device->isValid() && !m_reconnect) { result_t result = handleSymbol(); if (result != RESULT_ERR_TIMEOUT) symCount++; @@ -262,20 +262,22 @@ void BusHandler::run() m_symPerSec = symCount / (unsigned int)(now-lastTime); if (m_symPerSec > m_maxSymPerSec) { m_maxSymPerSec = m_symPerSec; - if (m_maxSymPerSec > 100) + if (m_maxSymPerSec > 100) { logNotice(lf_bus, "max. symbols per second: %d", m_maxSymPerSec); + } } lastTime = now; symCount = 0; } } else { - if (!Wait(10)) + if (!Wait(10)) { break; + } + m_reconnect = false; result_t result = m_device->open(); - - if (result == RESULT_OK) + if (result == RESULT_OK) { logNotice(lf_bus, "re-opened %s", m_device->getName()); - else { + } else { logError(lf_bus, "unable to open %s: %s", m_device->getName(), getResultCode(result)); setState(bs_noSignal, result); } diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index 1af8e245..558291e9 100644 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -316,7 +316,7 @@ public: const unsigned int transferLatency, const unsigned int busAcquireTimeout, const unsigned int slaveRecvTimeout, const unsigned int lockCount, const bool generateSyn, const unsigned int pollInterval) - : WaitThread(), m_device(device), m_messages(messages), + : WaitThread(), m_device(device), m_reconnect(false), m_messages(messages), m_ownMasterAddress(ownAddress), m_ownSlaveAddress((unsigned char)(ownAddress+5)), m_answer(answer), m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries), m_transferLatency(transferLatency), m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout), @@ -424,6 +424,11 @@ public: */ bool hasSignal() { return m_state != bs_noSignal; } + /** + * Reconnect the device. + */ + void reconnect() { m_reconnect = true; } + /** * Return the current symbol rate. * @return the number of received symbols in the last second. @@ -488,6 +493,9 @@ private: /** the @a Device instance for accessing the bus. */ Device* m_device; + /** set to @p true when the device shall be reconnected. */ + bool m_reconnect; + /** the @a MessageMap instance with all known @a Message instances. */ MessageMap* m_messages; diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index 8d4c6bf6..50bcc0ec 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -25,6 +25,9 @@ using namespace std; +/** the number of seconds of permanent missing signal after which to reconnect the device. */ +#define RECONNECT_MISSING_SIGNAL 60 + /** the known column names (pairs of full length name and short length name). */ static const char* columnNames[] = { "type", "t", @@ -42,7 +45,9 @@ static const char* columnNames[] = { static const size_t columnCount = sizeof(columnNames) / sizeof(char*); MainLoop::MainLoop(const struct options opt, Device *device, MessageMap* messages) - : Thread(), m_device(device), m_messages(messages), m_address(opt.address), m_scanConfig(opt.scanConfig), m_initialScan(opt.initialScan), m_enableHex(opt.enableHex) + : Thread(), m_device(device), m_reconnectCount(0), m_messages(messages), + m_address(opt.address), m_scanConfig(opt.scanConfig), + m_initialScan(opt.initialScan), m_enableHex(opt.enableHex) { // setup Device m_device->setLogRaw(opt.logRaw); @@ -98,7 +103,7 @@ MainLoop::~MainLoop() void MainLoop::run() { bool reload = true; - time_t lastTaskRun, now; + time_t lastTaskRun, now, lastSignal = 0; int taskDelay = 5; unsigned char lastScanAddress = 0; // 0 is known to be a master time(&now); @@ -112,9 +117,19 @@ void MainLoop::run() time(&now); if (now lastTaskRun+taskDelay) { logDebug(lf_main, "performing regular tasks"); + if (m_busHandler->hasSignal()) { + lastSignal = now; + } else if (lastSignal && now > lastSignal+RECONNECT_MISSING_SIGNAL) { + lastSignal = 0; + m_busHandler->reconnect(); + m_reconnectCount++; + } if (m_scanConfig) { if (m_initialScan != ESC && reload && m_busHandler->hasSignal()) { result_t result = RESULT_ERR_NO_SIGNAL; @@ -1135,11 +1150,12 @@ string MainLoop::executeInfo(vector &args) } else { result << "signal: no signal\n"; } + result << "reconnects: " << static_cast(m_reconnectCount) << "\n"; result << "masters: " << static_cast(m_busHandler->getMasterCount()) << "\n"; result << "messages: " << static_cast(m_messages->size()) << "\n"; result << "conditional: " << static_cast(m_messages->sizeConditional()) << "\n"; result << "poll: " << static_cast(m_messages->sizePoll()) << "\n"; - result << "update: " << static_cast(m_messages->sizePassive()) << "\n"; + result << "update: " << static_cast(m_messages->sizePassive()); m_busHandler->formatSeenInfo(result); return result.str(); } diff --git a/src/ebusd/mainloop.h b/src/ebusd/mainloop.h index 1765220f..47abc567 100644 --- a/src/ebusd/mainloop.h +++ b/src/ebusd/mainloop.h @@ -69,6 +69,9 @@ private: /** the @a Device instance. */ Device* m_device; + /** the number of reconnects requested from the @a Device. */ + unsigned int m_reconnectCount; + /** the @a MessageMap instance. */ MessageMap* m_messages;