delay scanning when using broadcast, moved loading scan files to bushandler, reworked update check, add max symbol rate to info result, keep scan results for each message separate, also do a decent scan on individual address and delay scan subsequent scan messages if necessary

This commit is contained in:
john30
2017-03-05 12:56:54 +01:00
parent 5633d3825d
commit b2f2bfcf58
3 changed files with 303 additions and 172 deletions
+218 -114
View File
@@ -22,6 +22,7 @@
#include "ebusd/bushandler.h"
#include <iomanip>
#include "ebusd/main.h"
#include "lib/utils/log.h"
namespace ebusd {
@@ -102,16 +103,12 @@ result_t ScanRequest::prepare(symbol_t ownMasterAddress) {
return RESULT_ERR_EOF;
}
symbol_t dstAddress = m_slaves.front();
if (m_index == 0 && m_messages.size() == m_allMessages.size()) { // first message for this address
m_busHandler->setScanResult(dstAddress, "");
}
istringstream input;
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input, UI_FIELD_SEPARATOR, dstAddress,
m_index);
if (result >= RESULT_OK) {
m_result = m_message->prepareMaster(ownMasterAddress, m_master, input, UI_FIELD_SEPARATOR, dstAddress, m_index);
if (m_result >= RESULT_OK) {
logInfo(lf_bus, "scan %2.2x cmd: %s", dstAddress, m_master.getStr().c_str());
}
return result;
return m_result;
}
bool ScanRequest::notify(result_t result, SlaveSymbolString& slave) {
@@ -137,43 +134,52 @@ bool ScanRequest::notify(result_t result, SlaveSymbolString& slave) {
}
}
if (result == RESULT_OK) {
result = m_message->decodeLastData(m_scanResult, 0, true); // decode data
ostringstream output;
result = m_message->decodeLastData(output, 0, true); // decode data
string str = output.str();
m_busHandler->setScanResult(dstAddress, m_notifyIndex+m_index, str);
}
}
if (result < RESULT_OK) {
if (!m_slaves.empty()) {
m_slaves.pop_front();
}
if (result == RESULT_ERR_TIMEOUT) {
logNotice(lf_bus, "scan %2.2x timed out (%d slaves left)", dstAddress, m_slaves.size());
} else {
logError(lf_bus, "scan %2.2x failed (%d slaves left): %s", dstAddress, m_slaves.size(), getResultCode(result));
if (m_deleteOnFinish) {
if (result == RESULT_ERR_TIMEOUT) {
logNotice(lf_bus, "scan %2.2x timed out (%d slaves left)", dstAddress, m_slaves.size());
} else {
logError(lf_bus, "scan %2.2x failed (%d slaves left): %s", dstAddress, m_slaves.size(), getResultCode(result));
}
}
m_messages.clear(); // skip remaining secondary messages
} else if (m_messages.empty()) {
if (!m_slaves.empty()) {
m_slaves.pop_front();
}
logNotice(lf_bus, "scan %2.2x completed (%d slaves left)", dstAddress, m_slaves.size());
}
if (m_messages.empty()) { // last message for this address
m_busHandler->setScanResult(dstAddress, m_scanResult.str());
if (m_deleteOnFinish) {
logNotice(lf_bus, "scan %2.2x completed (%d slaves left)", dstAddress, m_slaves.size());
}
}
m_result = result;
if (m_slaves.empty()) {
logNotice(lf_bus, "scan finished");
if (m_deleteOnFinish) {
logNotice(lf_bus, "scan finished");
}
m_busHandler->setScanFinished();
return false;
}
if (m_messages.empty()) {
m_messages = m_allMessages;
m_scanResult.str("");
m_scanResult.clear();
}
m_index = 0;
m_message = m_messages.front();
m_messages.pop_front();
if (prepare(m_master[0]) < RESULT_OK) {
result = prepare(m_master[0]);
if (result < RESULT_OK) {
m_busHandler->setScanFinished();
if (result != RESULT_ERR_EOF) {
m_result = result;
}
return false; // give up
}
return true;
@@ -373,16 +379,16 @@ result_t BusHandler::readFromBus(Message* message, string inputStr, const symbol
void BusHandler::run() {
unsigned int symCount = 0;
time_t lastTime;
time_t now, lastTime;
time(&lastTime);
lastTime += 2;
do {
if (m_device->isValid() && !m_reconnect) {
result_t result = handleSymbol();
if (result != RESULT_ERR_TIMEOUT) {
time(&now);
if (result != RESULT_ERR_TIMEOUT && now >= lastTime) {
symCount++;
}
time_t now;
time(&now);
if (now > lastTime) {
m_symPerSec = symCount / (unsigned int)(now-lastTime);
if (m_symPerSec > m_maxSymPerSec) {
@@ -407,6 +413,8 @@ void BusHandler::run() {
setState(bs_noSignal, result);
}
symCount = 0;
time(&lastTime);
lastTime += 2;
}
} while (isRunning());
}
@@ -1029,7 +1037,6 @@ void BusHandler::receiveCompleted() {
Message* message = m_messages->getScanMessage(slaveAddress);
if (message && (message->getLastUpdateTime() == 0 || message->getLastSlaveData().getDataSize() < 10)) {
// e.g. 10fe07040a b5564149303001248901
m_seenAddresses[slaveAddress] |= SCAN_INIT;
MasterSymbolString dummyMaster;
istringstream input;
result_t result = message->prepareMaster(m_ownMasterAddress, dummyMaster, input);
@@ -1040,9 +1047,14 @@ void BusHandler::receiveCompleted() {
idData.push_back(m_command.dataAt(i));
}
result = message->storeLastData(idData, 0);
}
if (result == RESULT_OK) {
m_seenAddresses[slaveAddress] |= SCAN_DONE;
if (result == RESULT_OK) {
ostringstream output;
result = message->decodeLastData(output, 0, true);
if (result == RESULT_OK) {
string str = output.str();
setScanResult(slaveAddress, 0, str);
}
}
}
logNotice(lf_update, "store BC ident: %s", getResultCode(result));
}
@@ -1103,10 +1115,12 @@ void BusHandler::receiveCompleted() {
}
}
result_t BusHandler::startScan(bool full, string levels) {
if (m_runningScans > 0) {
return RESULT_ERR_DUPLICATE;
result_t BusHandler::prepareScan(symbol_t slave, bool full, string levels, bool& reload, ScanRequest*& request) {
Message* scanMessage = m_messages->getScanMessage();
if (scanMessage == NULL) {
return RESULT_ERR_NOTFOUND;
}
deque<Message*> messages = m_messages->findAll("scan", "", levels, true);
for (deque<Message*>::iterator it = messages.begin(); it < messages.end(); it++) {
Message* message = *it;
@@ -1115,42 +1129,74 @@ result_t BusHandler::startScan(bool full, string levels) {
}
}
Message* scanMessage = m_messages->getScanMessage();
if (scanMessage == NULL) {
return RESULT_ERR_NOTFOUND;
}
m_scanResults.clear();
deque<symbol_t> slaves;
for (symbol_t slave = 1; slave != 0; slave++) { // 0 is known to be a master
if (!isValidAddress(slave, false) || isMaster(slave)) {
continue;
}
if (!full && (m_seenAddresses[slave]&SEEN) == 0) {
symbol_t master = getMasterAddress(slave); // check if we saw the corresponding master already
if (master == SYN || (m_seenAddresses[master]&SEEN) == 0) {
continue;
if (slave != SYN) {
slaves.push_back(slave);
if (!reload) {
Message* message = m_messages->getScanMessage(slave);
if (message == NULL || message->getLastChangeTime() == 0) {
reload = true;
}
}
slaves.push_back(slave);
} else {
reload = true;
for (slave = 1; slave != 0; slave++) { // 0 is known to be a master
if (!isValidAddress(slave, false) || isMaster(slave)) {
continue;
}
if (!full && (m_seenAddresses[slave]&SEEN) == 0) {
symbol_t master = getMasterAddress(slave); // check if we saw the corresponding master already
if (master == SYN || (m_seenAddresses[master]&SEEN) == 0) {
continue;
}
}
slaves.push_back(slave);
}
}
messages.push_front(scanMessage);
ScanRequest* request = new ScanRequest(m_messages, messages, slaves, this);
if (reload) {
messages.push_front(scanMessage);
}
if (messages.empty()) {
return RESULT_OK;
}
request = new ScanRequest(slave == SYN, m_messages, messages, slaves, this, reload ? 0 : 1);
result_t result = request->prepare(m_ownMasterAddress);
if (result < RESULT_OK) {
delete request;
request = NULL;
return result == RESULT_ERR_EOF ? RESULT_EMPTY : result;
}
return RESULT_OK;
}
result_t BusHandler::startScan(bool full, string levels) {
if (m_runningScans > 0) {
return RESULT_ERR_DUPLICATE;
}
ScanRequest* request = NULL;
bool reload = true;
result_t result = prepareScan(SYN, full, levels, reload, request);
if (result != RESULT_OK) {
return result;
}
if (!request) {
return RESULT_ERR_NOTFOUND;
}
m_scanResults.clear();
m_runningScans++;
m_nextRequests.push(request);
return RESULT_OK;
}
void BusHandler::setScanResult(symbol_t dstAddress, string str) {
void BusHandler::setScanResult(symbol_t dstAddress, size_t index, string str) {
m_seenAddresses[dstAddress] |= SCAN_INIT;
if (str.length() > 0) {
m_seenAddresses[dstAddress] |= SCAN_DONE;
m_scanResults[dstAddress] = str;
vector<string>& result = m_scanResults[dstAddress];
if (index >= result.size()) {
result.resize(index+1);
}
result[index] = str;
logNotice(lf_bus, "scan %2.2x: %s", dstAddress, str.c_str());
}
}
@@ -1161,20 +1207,29 @@ void BusHandler::setScanFinished() {
}
}
bool BusHandler::formatScanResult(symbol_t slave, ostringstream& output, bool leadingNewline) {
map<symbol_t, vector<string>>::iterator it = m_scanResults.find(slave);
if (it == m_scanResults.end()) {
return false;
}
if (leadingNewline) {
output << endl;
}
output << hex << setw(2) << setfill('0') << static_cast<unsigned>(slave);
for (auto result : it->second) {
output << result;
}
return true;
}
void BusHandler::formatScanResult(ostringstream& output) {
if (m_runningScans > 0) {
output << m_runningScans << " scan(s) still running" << endl;
}
bool first = true;
for (symbol_t slave = 1; slave != 0; slave++) { // 0 is known to be a master
map<symbol_t, string>::iterator it = m_scanResults.find(slave);
if (it != m_scanResults.end()) {
if (first) {
first = false;
} else {
output << endl;
}
output << hex << setw(2) << setfill('0') << static_cast<unsigned>(slave) << it->second;
if (formatScanResult(slave, output, !first)) {
first = false;
}
}
if (first) {
@@ -1199,8 +1254,8 @@ void BusHandler::formatScanResult(ostringstream& output) {
void BusHandler::formatSeenInfo(ostringstream& output) {
symbol_t address = 0;
for (int index = 0; index < 256; index++, address++) {
bool self = !m_device->isReadOnly() && (address == m_ownMasterAddress || address == m_ownSlaveAddress);
if (!isValidAddress(address, false) || ((m_seenAddresses[address]&SEEN) == 0 && !self)) {
bool ownAddress = !m_device->isReadOnly() && (address == m_ownMasterAddress || address == m_ownSlaveAddress);
if (!isValidAddress(address, false) || ((m_seenAddresses[address]&SEEN) == 0 && !ownAddress)) {
continue;
}
output << endl << "address " << setfill('0') << setw(2) << hex << static_cast<unsigned>(address);
@@ -1215,7 +1270,7 @@ void BusHandler::formatSeenInfo(ostringstream& output) {
if (master != SYN) {
output << " #" << setw(0) << dec << static_cast<unsigned>(getMasterNumber(master));
}
if (self) {
if (ownAddress) {
output << ", ebusd";
if (m_answer) {
output << " (answering)";
@@ -1238,81 +1293,121 @@ void BusHandler::formatSeenInfo(ostringstream& output) {
}
}
}
string loadedFiles = m_messages->getLoadedFiles(address);
vector<string> loadedFiles = m_messages->getLoadedFiles(address);
if (!loadedFiles.empty()) {
output << ", loaded " << loadedFiles;
bool first = true;
for (vector<string>::iterator it = loadedFiles.begin(); it != loadedFiles.end(); it++) {
if (first) {
first = false;
output << ", loaded \"";
} else {
output << ", \"";
}
output << *it << "\"";
it++;
if (!(*it).empty()) {
output << " (" << *it << ")";
}
}
}
}
}
void BusHandler::formatUpdateInfo(ostringstream& output) {
if (hasSignal()) {
output << "&s=" << static_cast<unsigned>(m_symPerSec);
output << ",\"s\":" << m_maxSymPerSec;
}
output << "&m=" << static_cast<unsigned>(m_masterCount);
output << "&ms=" << m_messages->size();
output << "&r=" << (m_device->isReadOnly() ? 1 : 0);
output << "&an=" << (m_answer ? 1 : 0);
output << "&c=" << (m_addressConflict ? 1 : 0);
output << ",\"c\":" << m_masterCount;
output << ",\"m\":" << m_messages->size();
output << ",\"r\":" << (m_device->isReadOnly() ? 1 : 0);
output << ",\"an\":" << (m_answer ? 1 : 0);
output << ",\"ac\":" << (m_addressConflict ? 1 : 0);
unsigned char address = 0;
for (int index = 0; index < 256; index++, address++) {
bool self = !m_device->isReadOnly() && (address == m_ownMasterAddress || address == m_ownSlaveAddress);
if (!isValidAddress(address, false) || ((m_seenAddresses[address]&SEEN) == 0 && !self)) {
bool ownAddress = !m_device->isReadOnly() && (address == m_ownMasterAddress || address == m_ownSlaveAddress);
if (!isValidAddress(address, false) || ((m_seenAddresses[address]&SEEN) == 0 && !ownAddress)) {
continue;
}
output << "&a[";
output << setfill('0') << setw(2) << hex << static_cast<unsigned>(address);
output << "]=";
if (self) {
output << "self";
}
map<symbol_t, string>::iterator it = m_scanResults.find(address);
output << ",\"" << setfill('0') << setw(2) << hex << static_cast<unsigned>(address);
output << "\":{\"o\":" << (ownAddress ? 1 : 0);
map<symbol_t, vector<string>>::iterator it = m_scanResults.find(address);
if (it != m_scanResults.end()) {
output << it->second;
} else if ((m_seenAddresses[address]&SCAN_DONE) != 0) {
output << ",\"s\":\"";
for (auto result : it->second) {
output << result;
}
output << "\"";
}
if ((m_seenAddresses[address]&SCAN_DONE) != 0) {
Message* message = m_messages->getScanMessage(address);
if (message != NULL && message->getLastUpdateTime() > 0) {
// add detailed scan info: Manufacturer ID SW HW
message->decodeLastData(output, OF_NUMERIC);
message->decodeLastData(output, OF_NAMES|OF_NUMERIC|OF_JSON|OF_SHORT, true);
}
}
string loadedFiles = m_messages->getLoadedFiles(address);
vector<string> loadedFiles = m_messages->getLoadedFiles(address);
if (!loadedFiles.empty()) {
output << "|" << loadedFiles;
output << ",\"f\":[";
bool first = true;
for (vector<string>::iterator it = loadedFiles.begin(); it != loadedFiles.end(); it++) {
if (first) {
first = false;
} else {
output << ",";
}
output << "{\"f\":\"" << *it << "\"";
it++;
if (!(*it).empty()) {
output << ",\"c\":\"" << *it << "\"";
}
output << "}";
}
output << "]";
}
output << "}";
}
}
result_t BusHandler::scanAndWait(symbol_t dstAddress, SlaveSymbolString& slave) {
if (!isValidAddress(dstAddress) || isMaster(dstAddress)) {
result_t BusHandler::scanAndWait(symbol_t dstAddress, bool loadScanConfig, bool reload) {
if (!isValidAddress(dstAddress, false) || isMaster(dstAddress)) {
return RESULT_ERR_INVALID_ADDR;
}
m_seenAddresses[dstAddress] |= SCAN_INIT;
Message* scanMessage = m_messages->getScanMessage();
if (scanMessage == NULL) {
return RESULT_ERR_NOTFOUND;
}
istringstream input;
MasterSymbolString master;
result_t result = scanMessage->prepareMaster(m_ownMasterAddress, master, input, UI_FIELD_SEPARATOR, dstAddress);
if (result == RESULT_OK) {
result = sendAndWait(master, slave);
if (result == RESULT_OK) {
Message* message = m_messages->getScanMessage(dstAddress);
if (message != NULL && message != scanMessage) {
scanMessage = message;
// update the cache, expected to work since this is a clone
scanMessage->storeLastData(master, 0);
}
}
if (result != RESULT_ERR_NO_SIGNAL) {
m_seenAddresses[dstAddress] |= SCAN_DONE;
}
}
if (result != RESULT_OK || slave.getDataSize() == 0) { // avoid "invalid position" during decode
ScanRequest* request = NULL;
bool hasAdditionalScanMessages = m_messages->hasAdditionalScanMessages();
result_t result = prepareScan(dstAddress, false, "", reload, request);
if (result != RESULT_OK) {
return result;
}
return scanMessage->storeLastData(slave, 0); // update the cache
if (request) {
if (reload) {
m_scanResults.erase(dstAddress);
} else if (m_scanResults.find(dstAddress) != m_scanResults.end()) {
m_scanResults[dstAddress].resize(1);
}
m_runningScans++;
m_nextRequests.push(request);
bool success = m_finishedRequests.remove(request, true);
result = success ? request->m_result : RESULT_ERR_TIMEOUT;
delete request;
request = NULL;
}
if (result != RESULT_OK) {
return result;
}
if (loadScanConfig) {
string file;
result = loadScanConfigFile(m_messages, dstAddress, file);
if (result == RESULT_OK) {
setScanConfigLoaded(dstAddress, file);
if (!hasAdditionalScanMessages && m_messages->hasAdditionalScanMessages()) {
// additional scan messages now available
scanAndWait(dstAddress, false, false);
}
} else {
setScanConfigLoaded(dstAddress, "");
}
}
return result;
}
bool BusHandler::enableGrab(bool enable) {
@@ -1340,7 +1435,7 @@ void BusHandler::formatGrabResult(const bool unknown, ostringstream& output, con
}
}
symbol_t BusHandler::getNextScanAddress(symbol_t lastAddress, bool& scanned) {
symbol_t BusHandler::getNextScanAddress(symbol_t lastAddress, bool onlyScanned) {
if (lastAddress == SYN) {
return SYN;
}
@@ -1348,13 +1443,22 @@ symbol_t BusHandler::getNextScanAddress(symbol_t lastAddress, bool& scanned) {
if (!isValidAddress(lastAddress, false) || isMaster(lastAddress)) {
continue;
}
if ((m_seenAddresses[lastAddress]&(SEEN|LOAD_INIT)) == SEEN) {
scanned = (m_seenAddresses[lastAddress]&SCAN_INIT) != 0;
if (onlyScanned) {
if ((m_seenAddresses[lastAddress]&(LOAD_INIT|SCAN_DONE)) == SCAN_DONE) {
return lastAddress;
}
} else if ((m_seenAddresses[lastAddress]&(SEEN|LOAD_INIT)) == SEEN) {
return lastAddress;
}
symbol_t master = getMasterAddress(lastAddress);
if (master != SYN && (m_seenAddresses[master]&SEEN) != 0 && (m_seenAddresses[lastAddress]&LOAD_INIT) == 0) {
scanned = (m_seenAddresses[lastAddress]&SCAN_INIT) != 0;
if (master == SYN || (m_seenAddresses[master]&SEEN) == 0) {
continue;
}
if (onlyScanned) {
if ((m_seenAddresses[lastAddress]&(LOAD_INIT|SCAN_DONE)) == SCAN_DONE) {
return lastAddress;
}
} else if ((m_seenAddresses[lastAddress]&LOAD_INIT) == 0) {
return lastAddress;
}
}
+39 -13
View File
@@ -190,14 +190,18 @@ class ScanRequest : public BusRequest {
public:
/**
* Constructor.
* @param deleteOnFinish whether to automatically delete this @a ScanRequest when finished.
* @param messageMap the @a MessageMap instance.
* @param messages the @a Message instances to query starting with the primary one.
* @param slaves the slave addresses to scan.
* @param busHandler the @a BusHandler instance to notify of final scan result.
* @param notifyIndex the offset to the index for notifying the scan result.
*/
ScanRequest(MessageMap* messageMap, deque<Message*> messages, deque<symbol_t> slaves, BusHandler* busHandler)
: BusRequest(m_master, true), m_messageMap(messageMap), m_index(0), m_allMessages(messages), m_messages(messages),
m_slaves(slaves), m_busHandler(busHandler) {
ScanRequest(bool deleteOnFinish, MessageMap* messageMap, deque<Message*> messages, deque<symbol_t> slaves,
BusHandler* busHandler, size_t notifyIndex = 0)
: BusRequest(m_master, deleteOnFinish), m_messageMap(messageMap), m_index(0), m_allMessages(messages),
m_messages(messages), m_slaves(slaves), m_busHandler(busHandler), m_notifyIndex(notifyIndex),
m_result(RESULT_ERR_NO_SIGNAL) {
m_message = m_messages.front();
m_messages.pop_front();
}
@@ -240,11 +244,14 @@ class ScanRequest : public BusRequest {
/** the slave addresses to scan. */
deque<symbol_t> m_slaves;
/** the @a ostringstream for building the scan result of a single slave. */
ostringstream m_scanResult;
/** the @a BusHandler instance to notify of final scan result. */
BusHandler* m_busHandler;
/** the offset to the index for notifying the scan result. */
size_t m_notifyIndex;
/** the overall result of handling the request. */
result_t m_result;
};
@@ -434,15 +441,25 @@ class BusHandler : public WaitThread {
/**
* Set the scan result @a string for a scanned slave address.
* @param dstAddress the scanned slave address.
* @param index the index of the result to set (starting with 0 for the ident message).
* @param str the scan result @a string to set, or empty if not a single part of the scan was successful.
*/
void setScanResult(symbol_t dstAddress, string str);
void setScanResult(symbol_t dstAddress, size_t index, string str);
/**
* Called from @a ScanRequest upon completion.
*/
void setScanFinished();
/**
* Format the scan result for a single slave to the @a ostringstream.
* @param slave the slave address for which to format the scan result.
* @param leadingNewline whether to insert a newline before the scan result.
* @param output the @a ostringstream to format the scan result to.
* @return true when a scan result was formatted, false otherwise.
*/
bool formatScanResult(symbol_t slave, ostringstream& output, bool leadingNewline);
/**
* Format the scan result to the @a ostringstream.
* @param output the @a ostringstream to format the scan result to.
@@ -464,10 +481,9 @@ class BusHandler : public WaitThread {
/**
* Send a scan message on the bus and wait for the answer.
* @param dstAddress the destination slave address to send to.
* @param slave the @a SlaveSymbolString that will be filled with retrieved slave data.
* @return the result code.
*/
result_t scanAndWait(symbol_t dstAddress, SlaveSymbolString& slave);
result_t scanAndWait(symbol_t dstAddress, bool loadScanConfig = false, bool reload = false);
/**
* Start or stop grabbing unknown messages.
@@ -516,10 +532,9 @@ class BusHandler : public WaitThread {
/**
* Get the next slave address that still needs to be scanned or loaded.
* @param lastAddress the last returned slave address, or 0 for returning the first one.
* @param scanned set to true when the slave is already scanned but not yet loaded, set to false when it still needs to be scanned and loaded.
* @return the next slave address that still needs to be scanned or loaded, or @a SYN.
*/
symbol_t getNextScanAddress(symbol_t lastAddress, bool& scanned);
symbol_t getNextScanAddress(symbol_t lastAddress, bool onlyScanned = false);
/**
* Set the state of the participant to configuration @a LOADED.
@@ -556,6 +571,17 @@ class BusHandler : public WaitThread {
*/
void receiveCompleted();
/**
* Prepare a @a ScanRequest.
* @param slave the single slave address to scan, or @a SYN for multiple.
* @param full true for a full scan (all slaves), false for scanning only already seen slaves.
* @param levels the current user's access levels.
* @param reload true to force sending the scan message, false to send only if necessary (only for single slave).
* @param request the created @a ScanRequest (may be NULL with positive result if scan is not needed).
* @return the result code.
*/
result_t prepareScan(symbol_t slave, bool full, string levels, bool& reload, ScanRequest*& request);
/** the @a Device instance for accessing the bus. */
Device* m_device;
@@ -662,8 +688,8 @@ class BusHandler : public WaitThread {
/** the participating bus addresses seen so far (0 if not seen yet, or combination of @a SEEN bits). */
symbol_t m_seenAddresses[256];
/** the scan results by slave address. */
map<symbol_t, string> m_scanResults;
/** the scan results by slave address and index. */
map<symbol_t, vector<string>> m_scanResults;
/** whether to grab messages. */
bool m_grabMessages;
+46 -45
View File
@@ -197,10 +197,11 @@ MainLoop::~MainLoop() {
void MainLoop::run() {
bool reload = true;
time_t lastTaskRun, now, lastSignal = 0, since, sinkSince = 1, nextCheckRun;
time_t lastTaskRun, now, start, lastSignal = 0, since, sinkSince = 1, nextCheckRun;
int taskDelay = 5;
symbol_t lastScanAddress = 0; // 0 is known to be a master
time(&now);
start = now;
lastTaskRun = now;
nextCheckRun = now + CHECK_INITIAL_DELAY;
ostringstream updates;
@@ -233,20 +234,33 @@ void MainLoop::run() {
m_reconnectCount++;
}
if (m_scanConfig) {
bool loadDelay = false;
if (m_initialScan != ESC && reload && m_busHandler->hasSignal()) {
loadDelay = true;
result_t result = RESULT_ERR_NO_SIGNAL;
if (m_initialScan == SYN) {
logNotice(lf_main, "initiating full scan");
logNotice(lf_main, "starting initial full scan");
result = m_busHandler->startScan(true, "*");
} else if (m_initialScan == BROADCAST) {
logNotice(lf_main, "starting initial broadcast scan");
Message* message = m_messages->getScanMessage(BROADCAST);
if (message) {
MasterSymbolString master;
SlaveSymbolString slave;
istringstream input;
result = message->prepareMaster(m_address, master, input);
if (result == RESULT_OK) {
result = m_busHandler->sendAndWait(master, slave);
}
} else {
result = RESULT_ERR_NOTFOUND;
}
} else {
logNotice(lf_main, "starting initial scan for %2.2x", m_initialScan);
SlaveSymbolString slave;
result = m_busHandler->scanAndWait(m_initialScan, slave);
Message* message = m_messages->getScanMessage(m_initialScan);
if (result == RESULT_OK && message != NULL) {
result = m_busHandler->scanAndWait(m_initialScan, true);
if (result == RESULT_OK) {
ostringstream ret;
result = message->decodeLastData(ret, 0, true); // decode data
if (result == RESULT_OK) {
if (m_busHandler->formatScanResult(m_initialScan, ret, false)) {
logNotice(lf_main, "initial scan result: %2.2x%s", m_initialScan, ret.str().c_str());
}
}
@@ -258,38 +272,21 @@ void MainLoop::run() {
reload = false;
}
}
bool scanned = false;
lastScanAddress = m_busHandler->getNextScanAddress(lastScanAddress, scanned);
if (lastScanAddress == SYN) {
taskDelay = 5;
lastScanAddress = 0;
} else {
nextCheckRun = now + CHECK_INITIAL_DELAY;
SlaveSymbolString slave;
if (scanned) {
Message* message = m_messages->getScanMessage(lastScanAddress);
slave = message->getLastSlaveData();
scanned = message->getLastUpdateTime() > 0;
if (!loadDelay) {
lastScanAddress = m_busHandler->getNextScanAddress(lastScanAddress);
if (lastScanAddress == SYN) {
taskDelay = 5;
lastScanAddress = 0;
} else {
result_t result = m_busHandler->scanAndWait(lastScanAddress, slave);
nextCheckRun = now + CHECK_INITIAL_DELAY;
result_t result = m_busHandler->scanAndWait(lastScanAddress, true);
taskDelay = (result == RESULT_ERR_NO_SIGNAL) ? 10 : 1;
if (result != RESULT_OK) {
logError(lf_main, "scan config %2.2x message: %s", lastScanAddress, getResultCode(result));
logError(lf_main, "scan config %2.2x: %s", lastScanAddress, getResultCode(result));
} else {
scanned = true;
logInfo(lf_main, "scan config %2.2x message received", lastScanAddress);
}
}
if (scanned) {
string file;
result_t result = loadScanConfigFile(m_messages, lastScanAddress, slave, file);
if (result == RESULT_OK) {
logNotice(lf_main, "scan config %2.2x: file %s loaded", lastScanAddress, file.c_str());
m_busHandler->setScanConfigLoaded(lastScanAddress, file);
} else {
m_busHandler->setScanConfigLoaded(lastScanAddress, "");
}
}
}
}
if (now > nextCheckRun) {
@@ -298,16 +295,24 @@ void MainLoop::run() {
if (socket) {
socket->setTimeout(5);
ostringstream ostr;
ostr << "GET /updatecheck/?v=" << PACKAGE_VERSION << "." << REVISION;
ostr << "{\"v\":\"" << PACKAGE_VERSION << "." << REVISION << "\"";
ostr << ",\"u\":" << (now-start);
if (m_reconnectCount) {
ostr << "&c=" << m_reconnectCount;
ostr << ",\"c\":" << m_reconnectCount;
}
m_busHandler->formatUpdateInfo(ostr);
ostr << " HTTP/1.0\r\n";
ostr << "}";
string str = ostr.str();
ostr.clear();
ostr.str("");
ostr << "POST /updatecheck/ HTTP/1.0\r\n";
ostr << "Host: ebusd.eu" << "\r\n";
ostr << "User-Agent: " << PACKAGE_NAME << "/" << PACKAGE_VERSION << "\r\n";
ostr << "Content-Type: application/json; charset=utf-8\r\n";
ostr << "Content-Length: " << str.length() << "\r\n";
ostr << "\r\n";
string str = ostr.str();
ostr << str;
str = ostr.str();
const char* cstr = str.c_str();
size_t len = str.size();
for (size_t pos = 0; pos < len; ) {
@@ -1379,18 +1384,13 @@ string MainLoop::executeScan(vector<string> &args, string levels) {
if (result != RESULT_OK) {
return getResultCode(result);
}
SlaveSymbolString slave;
result = m_busHandler->scanAndWait(dstAddress, slave);
result = m_busHandler->scanAndWait(dstAddress);
if (result != RESULT_OK) {
return getResultCode(result);
}
Message* message = m_messages->getScanMessage(dstAddress);
// never NULL due to scanAndWait() == RESULT_OK && dstAddress != BROADCAST
ostringstream ret;
ret << hex << setw(2) << setfill('0') << static_cast<unsigned>(dstAddress);
result = message->decodeLastData(ret, 0, true); // decode data
if (result != RESULT_OK) {
return getResultCode(result);
if (!m_busHandler->formatScanResult(dstAddress, ret, false)) {
return getResultCode(RESULT_EMPTY);
}
return ret.str();
}
@@ -1485,6 +1485,7 @@ string MainLoop::executeInfo(vector<string> &args, const string user) {
if (m_busHandler->hasSignal()) {
result << "signal: acquired\n";
result << "symbol rate: " << m_busHandler->getSymbolRate() << "\n";
result << "max symbol rate: " << m_busHandler->getMaxSymbolRate() << "\n";
} else {
result << "signal: no signal\n";
}