added chained messages, let a single ScanRequest do all the work and be more verbose on scan, fix for storing scan result, adjusted to message.h
This commit is contained in:
+76
-56
@@ -60,7 +60,7 @@ const char* getStateCode(BusState state) {
|
||||
result_t PollRequest::prepare(unsigned char ownMasterAddress)
|
||||
{
|
||||
istringstream input;
|
||||
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input);
|
||||
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input, m_index);
|
||||
if (result == RESULT_OK)
|
||||
logInfo(lf_bus, "poll cmd: %s", m_master.getDataStr().c_str());
|
||||
return result;
|
||||
@@ -68,10 +68,16 @@ result_t PollRequest::prepare(unsigned char ownMasterAddress)
|
||||
|
||||
bool PollRequest::notify(result_t result, SymbolString& slave)
|
||||
{
|
||||
ostringstream output;
|
||||
if (result == RESULT_OK) {
|
||||
result = m_message->decode(pt_slaveData, slave, output); // decode data
|
||||
result = m_message->storeLastData(pt_slaveData, slave, m_index);
|
||||
if (result>=RESULT_OK && m_index+1 < m_message->getCount()) {
|
||||
m_index++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ostringstream output;
|
||||
if (result==RESULT_OK)
|
||||
result = m_message->decodeLastData(output); // decode data
|
||||
if (result < RESULT_OK)
|
||||
logError(lf_bus, "poll %s %s failed: %s", m_message->getCircuit().c_str(), m_message->getName().c_str(), getResultCode(result));
|
||||
else
|
||||
@@ -81,13 +87,16 @@ bool PollRequest::notify(result_t result, SymbolString& slave)
|
||||
}
|
||||
|
||||
|
||||
result_t ScanRequest::prepare(unsigned char ownMasterAddress, unsigned char dstAddress)
|
||||
result_t ScanRequest::prepare(unsigned char ownMasterAddress)
|
||||
{
|
||||
if (m_slaves.empty())
|
||||
return RESULT_ERR_EOF;
|
||||
unsigned char dstAddress = m_slaves.front();
|
||||
istringstream input;
|
||||
m_master.clear();
|
||||
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input, UI_FIELD_SEPARATOR, dstAddress);
|
||||
if (result == RESULT_OK)
|
||||
logInfo(lf_bus, "scan cmd: %s", m_master.getDataStr().c_str());
|
||||
result_t result = m_message->prepareMaster(ownMasterAddress, m_master, input, UI_FIELD_SEPARATOR, dstAddress, m_index);
|
||||
|
||||
if (result >= RESULT_OK)
|
||||
logInfo(lf_bus, "scan %2.2x cmd: %s", dstAddress, m_master.getDataStr().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -98,34 +107,47 @@ bool ScanRequest::notify(result_t result, SymbolString& slave)
|
||||
if (result == RESULT_OK) {
|
||||
if (m_message==m_messageMap->getScanMessage()) {
|
||||
Message* message = m_messageMap->getScanMessage(dstAddress);
|
||||
if (message!=NULL)
|
||||
if (message!=NULL) {
|
||||
m_message = message;
|
||||
m_message->storeLastData(pt_masterData, m_master, m_index); // expected to work since this is a clone
|
||||
}
|
||||
}
|
||||
result = m_message->decode(pt_slaveData, slave, scanResult, 0, true); // decode data
|
||||
result = m_message->storeLastData(pt_slaveData, slave, m_index);
|
||||
if (result>=RESULT_OK && m_index+1 < m_message->getCount()) {
|
||||
m_index++;
|
||||
result = prepare(m_master[0]);
|
||||
if (result >= RESULT_OK)
|
||||
return true;
|
||||
}
|
||||
if (result==RESULT_OK)
|
||||
result = m_message->decodeLastData(scanResult, 0, true); // decode data
|
||||
}
|
||||
if (result < RESULT_OK) {
|
||||
if (!m_slaves.empty())
|
||||
m_slaves.pop_front();
|
||||
if (result == RESULT_ERR_TIMEOUT)
|
||||
logInfo(lf_bus, "scan %2.2x timed out", dstAddress);
|
||||
logInfo(lf_bus, "scan %2.2x timed out, %d remain", dstAddress, m_slaves.size());
|
||||
else
|
||||
logError(lf_bus, "scan %2.2x failed: %s", dstAddress, getResultCode(result));
|
||||
m_busHandler->addScanResult(dstAddress, "", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_busHandler->addScanResult(dstAddress, scanResult.str(), result);
|
||||
|
||||
// check for remaining secondary messages
|
||||
if (m_messages.empty()) {
|
||||
logNotice(lf_bus, "scan %2.2x completed", dstAddress);
|
||||
return false;
|
||||
logError(lf_bus, "scan %2.2x failed, %d remain: %s", dstAddress, m_slaves.size(), getResultCode(result));
|
||||
m_busHandler->addScanResult(dstAddress, "", result); // TODO combine all data from one slave and then store in BusHandler
|
||||
// skip remaining secondary messages
|
||||
m_messages = m_allMessages;
|
||||
} else {
|
||||
m_busHandler->addScanResult(dstAddress, scanResult.str(), result);
|
||||
// check for remaining secondary messages
|
||||
if (m_messages.empty()) {
|
||||
if (!m_slaves.empty())
|
||||
m_slaves.pop_front();
|
||||
logNotice(lf_bus, "scan %2.2x completed, %d remain", dstAddress, m_slaves.size());
|
||||
m_messages = m_allMessages;
|
||||
}
|
||||
}
|
||||
m_index = 0;
|
||||
m_message = m_messages.front();
|
||||
m_messages.pop_front();
|
||||
|
||||
result = prepare(m_master[0], dstAddress);
|
||||
if (result != RESULT_OK)
|
||||
if (prepare(m_master[0]) < RESULT_OK) {
|
||||
return false; // give up
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -153,7 +175,9 @@ void BusHandler::clear()
|
||||
result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave)
|
||||
{
|
||||
result_t result = RESULT_ERR_NO_SIGNAL;
|
||||
slave.clear();
|
||||
ActiveBusRequest request(master, slave);
|
||||
logInfo(lf_bus, "send message: %s", master.getDataStr().c_str());
|
||||
|
||||
for (int sendRetries = m_failedSendRetries + 1; sendRetries >= 0; sendRetries--) {
|
||||
m_nextRequests.push(&request);
|
||||
@@ -161,12 +185,9 @@ result_t BusHandler::sendAndWait(SymbolString& master, SymbolString& slave)
|
||||
result = success ? request.m_result : RESULT_ERR_TIMEOUT;
|
||||
|
||||
if (result == RESULT_OK) {
|
||||
deque<Message*> messages = m_messages->findAll(master);
|
||||
while (messages.size()>0) {
|
||||
Message* message = messages.front();
|
||||
Message* message = m_messages->find(master);
|
||||
if (message != NULL)
|
||||
m_messages->invalidateCache(message);
|
||||
messages.pop_front();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!success || result == RESULT_ERR_NO_SIGNAL || result == RESULT_ERR_SEND || result == RESULT_ERR_DEVICE) {
|
||||
@@ -742,8 +763,7 @@ void BusHandler::receiveCompleted()
|
||||
else
|
||||
logInfo(lf_update, "update MS cmd: %s / %s", m_command.getDataStr().c_str(), m_response.getDataStr().c_str());
|
||||
|
||||
deque<Message*> messages = m_messages->findAll(m_command);
|
||||
Message* message = messages.size()>0 ? messages.front() : NULL;
|
||||
Message* message = m_messages->find(m_command);
|
||||
if (m_grabUnknownMessages==gr_all || (message==NULL && m_grabUnknownMessages==gr_unknown)) {
|
||||
string data;
|
||||
string key = data = m_command.getDataStr();
|
||||
@@ -762,16 +782,13 @@ void BusHandler::receiveCompleted()
|
||||
logNotice(lf_update, "unknown MS cmd: %s / %s", m_command.getDataStr().c_str(), m_response.getDataStr().c_str());
|
||||
}
|
||||
else {
|
||||
messages.pop_front();
|
||||
while (messages.size()>0) {
|
||||
Message* invalidate = messages.front();
|
||||
m_messages->invalidateCache(invalidate);
|
||||
messages.pop_front();
|
||||
}
|
||||
m_messages->invalidateCache(message);
|
||||
string circuit = message->getCircuit();
|
||||
string name = message->getName();
|
||||
result_t result = message->storeLastData(m_command, m_response);
|
||||
ostringstream output;
|
||||
result_t result = message->decode(m_command, m_response, output);
|
||||
if (result==RESULT_OK)
|
||||
result = message->decodeLastData(output);
|
||||
if (result < RESULT_OK)
|
||||
logError(lf_update, "unable to parse %s %s from %s / %s: %s", circuit.c_str(), name.c_str(), m_command.getDataStr().c_str(), m_response.getDataStr().c_str(), getResultCode(result));
|
||||
else {
|
||||
@@ -808,6 +825,7 @@ result_t BusHandler::startScan(bool full)
|
||||
|
||||
m_scanResults.clear();
|
||||
|
||||
deque<unsigned char> slaves;
|
||||
for (unsigned char slave = 1; slave != 0; slave++) { // 0 is known to be a master
|
||||
if (!isValidAddress(slave, false) || isMaster(slave))
|
||||
continue;
|
||||
@@ -816,15 +834,16 @@ result_t BusHandler::startScan(bool full)
|
||||
if (master == SYN || (m_seenAddresses[master]&SEEN)==0)
|
||||
continue;
|
||||
}
|
||||
|
||||
ScanRequest* request = new ScanRequest(m_messages, scanMessage, messages, this);
|
||||
result_t result = request->prepare(m_ownMasterAddress, slave);
|
||||
if (result != RESULT_OK) {
|
||||
delete request;
|
||||
return result;
|
||||
}
|
||||
m_nextRequests.push(request);
|
||||
slaves.push_back(slave);
|
||||
}
|
||||
messages.push_front(scanMessage);
|
||||
ScanRequest* request = new ScanRequest(m_messages, messages, slaves, this);
|
||||
result_t result = request->prepare(m_ownMasterAddress);
|
||||
if (result < RESULT_OK) {
|
||||
delete request;
|
||||
return result;
|
||||
}
|
||||
m_nextRequests.push(request);
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
@@ -838,9 +857,9 @@ void BusHandler::addScanResult(unsigned char dstAddress, string str, result_t re
|
||||
m_seenAddresses[dstAddress] |= SCAN_DONE;
|
||||
logNotice(lf_bus, "scan %2.2x: %s", dstAddress, str.c_str());
|
||||
if (m_scanResults.find(dstAddress) == m_scanResults.end())
|
||||
m_scanResults[dstAddress] = result;
|
||||
m_scanResults[dstAddress] = str;
|
||||
else
|
||||
m_scanResults[dstAddress] += result;
|
||||
m_scanResults[dstAddress] += str;
|
||||
}
|
||||
|
||||
void BusHandler::formatScanResult(ostringstream& output)
|
||||
@@ -924,17 +943,18 @@ result_t BusHandler::scanAndWait(unsigned char dstAddress, SymbolString& slave)
|
||||
result = sendAndWait(master, slave);
|
||||
if (result==RESULT_OK) {
|
||||
Message* message = m_messages->getScanMessage(dstAddress);
|
||||
if (message!=NULL)
|
||||
if (message!=NULL && message!=scanMessage) {
|
||||
scanMessage = message;
|
||||
scanMessage->storeLastData(pt_masterData, master, 0); // update the cache, expected to work since this is a clone
|
||||
}
|
||||
}
|
||||
if (result!=RESULT_ERR_NO_SIGNAL)
|
||||
m_seenAddresses[dstAddress] |= SCAN_DONE;
|
||||
}
|
||||
if (result==RESULT_OK) {
|
||||
ostringstream output;
|
||||
scanMessage->decode(master, slave, output); // just to update the cached data
|
||||
}
|
||||
return result;
|
||||
if (result!=RESULT_OK)
|
||||
return result;
|
||||
|
||||
return scanMessage->storeLastData(pt_slaveData, slave, 0); // update the cache
|
||||
}
|
||||
|
||||
bool BusHandler::enableGrab(bool enable, bool all)
|
||||
|
||||
+23
-8
@@ -153,7 +153,7 @@ public:
|
||||
* @param message the associated @a Message.
|
||||
*/
|
||||
PollRequest(Message* message)
|
||||
: BusRequest(m_master, true), m_message(message) {}
|
||||
: BusRequest(m_master, true), m_message(message), m_index(0) {}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -178,6 +178,9 @@ private:
|
||||
/** the associated @a Message. */
|
||||
Message* m_message;
|
||||
|
||||
/** the current part index in @a m_message. */
|
||||
unsigned char m_index;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -192,12 +195,16 @@ public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param messageMap the @a MessageMap instance.
|
||||
* @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 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.
|
||||
*/
|
||||
ScanRequest(MessageMap* messageMap, Message* message, deque<Message*> messages, BusHandler* busHandler)
|
||||
: BusRequest(m_master, true), m_messageMap(messageMap), m_message(message), m_messages(messages), m_busHandler(busHandler) {}
|
||||
ScanRequest(MessageMap* messageMap, deque<Message*> messages, deque<unsigned char> 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)
|
||||
{
|
||||
m_message = m_messages.front();
|
||||
m_messages.pop_front();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -205,12 +212,11 @@ public:
|
||||
virtual ~ScanRequest() {}
|
||||
|
||||
/**
|
||||
* Prepare the master data.
|
||||
* Prepare the next master data.
|
||||
* @param masterAddress the master bus address to use.
|
||||
* @param dstAddress the destination address to set.
|
||||
* @return the result code.
|
||||
*/
|
||||
result_t prepare(unsigned char masterAddress, unsigned char dstAddress);
|
||||
result_t prepare(unsigned char masterAddress);
|
||||
|
||||
// @copydoc
|
||||
virtual bool notify(result_t result, SymbolString& slave);
|
||||
@@ -226,9 +232,18 @@ private:
|
||||
/** the currently queried @a Message. */
|
||||
Message* m_message;
|
||||
|
||||
/** the current part index in @a m_message. */
|
||||
unsigned char m_index;
|
||||
|
||||
/** all secondary @a Message instances. */
|
||||
const deque<Message*> m_allMessages;
|
||||
|
||||
/** the remaining secondary @a Message instances. */
|
||||
deque<Message*> m_messages;
|
||||
|
||||
/** the slave addresses to scan. */
|
||||
deque<unsigned char> m_slaves;
|
||||
|
||||
/** the @a BusHandler instance to notify of final scan result. */
|
||||
BusHandler* m_busHandler;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user