From bcd6eb57fecd189c1b7f44a2ed7892a422234bc3 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 27 Dec 2015 22:57:11 +0100 Subject: [PATCH] added chained messages, adjusted to message.h, small fix for find formatting use named objects for JSON fields instead of array (or numbered if field names are not unique), fix for JSON output when decoding failed --- src/ebusd/mainloop.cpp | 88 ++++++++++++++++++++++-------------------- src/ebusd/mainloop.h | 4 +- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index e77d306a..0ff5f7e5 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -299,21 +299,30 @@ result_t MainLoop::parseHexMaster(vector &args, size_t argPos, SymbolStr return ret; } -result_t MainLoop::readFromBus(Message* message, SymbolString& master, string inputStr, SymbolString& slave, const unsigned char dstAddress) +result_t MainLoop::readFromBus(Message* message, string inputStr, const unsigned char dstAddress) { - istringstream input(inputStr); - result_t ret = message->prepareMaster(m_address, master, input, UI_FIELD_SEPARATOR, dstAddress); - if (ret != RESULT_OK) { - logError(lf_main, "prepare message: %s", getResultCode(ret)); - return ret; + result_t ret = RESULT_EMPTY; + SymbolString master(true); + SymbolString slave(false); + for (unsigned char index=0; indexgetCount(); index++) { + istringstream input(inputStr); + ret = message->prepareMaster(m_address, master, input, UI_FIELD_SEPARATOR, dstAddress, index); + if (ret != RESULT_OK) { + logError(lf_main, "prepare message part %d: %s", index, getResultCode(ret)); + break; + } + // send message + ret = m_busHandler->sendAndWait(master, slave); + if (ret != RESULT_OK) { + logError(lf_main, "send message part %d: %s", index, getResultCode(ret)); + break; + } + ret = message->storeLastData(pt_slaveData, slave, index); + if (ret < RESULT_OK) { + logError(lf_main, "store message part %d: %s", index, getResultCode(ret)); + break; + } } - - // send message - logInfo(lf_main, "send message: %s", master.getDataStr().c_str()); - ret = m_busHandler->sendAndWait(master, slave); - if (ret != RESULT_OK) - logError(lf_main, "send message: %s", getResultCode(ret)); - return ret; } @@ -426,8 +435,10 @@ string MainLoop::executeRead(vector &args) ret = m_busHandler->sendAndWait(master, slave); if (ret == RESULT_OK) { + ret = message->storeLastData(cacheMaster, slave); ostringstream result; - ret = message->decode(cacheMaster, slave, result); + if (ret==RESULT_OK) + ret = message->decodeLastData(result); if (ret >= RESULT_OK) logInfo(lf_main, "hex read %s %s cache update: %s", message->getCircuit().c_str(), message->getName().c_str(), result.str().c_str()); else @@ -489,7 +500,7 @@ string MainLoop::executeRead(vector &args) if (cacheMessage != NULL && (cacheMessage->getLastUpdateTime() + maxAge > now || (cacheMessage->isPassive() && cacheMessage->getLastUpdateTime() != 0))) { if (verbose) result << cacheMessage->getCircuit() << " " << cacheMessage->getName() << " "; - result_t ret = cacheMessage->decodeLastData(result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); + result_t ret = cacheMessage->decodeLastData(pt_slaveData, result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); if (ret != RESULT_OK) { if (ret < RESULT_OK) logError(lf_main, "read %s %s cached: %s", cacheMessage->getCircuit().c_str(), cacheMessage->getName().c_str(), getResultCode(ret)); @@ -510,15 +521,13 @@ string MainLoop::executeRead(vector &args) return getResultCode(RESULT_ERR_INVALID_ADDR); // read directly from bus - SymbolString master(true); - SymbolString slave(false); - result_t ret = readFromBus(message, master, params, slave, dstAddress); + result_t ret = readFromBus(message, params, dstAddress); if (ret != RESULT_OK) return getResultCode(ret); if (verbose) result << message->getCircuit() << " " << message->getName() << " "; - ret = message->decode(pt_slaveData, slave, result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); + ret = message->decodeLastData(pt_slaveData, result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); if (ret < RESULT_OK) { logError(lf_main, "read %s %s: decode %s", message->getCircuit().c_str(), message->getName().c_str(), getResultCode(ret)); result.str(""); @@ -560,8 +569,10 @@ string MainLoop::executeWrite(vector &args) if (ret == RESULT_OK) { if (message != NULL) { // also updates read messages + ret = message->storeLastData(cacheMaster, slave); ostringstream result; - ret = message->decode(cacheMaster, slave, result); + if (ret==RESULT_OK) + ret = message->decodeLastData(result); if (ret >= RESULT_OK) logInfo(lf_main, "hex write %s %s cache update: %s", message->getCircuit().c_str(), message->getName().c_str(), result.str().c_str()); else @@ -612,21 +623,20 @@ string MainLoop::executeWrite(vector &args) if (message->getDstAddress()==SYN && dstAddress==SYN) return getResultCode(RESULT_ERR_INVALID_ADDR); - SymbolString master(true); - SymbolString slave(false); - result_t ret = readFromBus(message, master, args.size() == argPos + 2 ? "" : args[argPos + 2], slave, dstAddress); // allow missing values + result_t ret = readFromBus(message, args.size() == argPos + 2 ? "" : args[argPos + 2], dstAddress); // allow missing values if (ret != RESULT_OK) return getResultCode(ret); + dstAddress = message->getLastMasterData()[1]; ostringstream result; - if (master[1] == BROADCAST || isMaster(master[1])) { + if (dstAddress == BROADCAST || isMaster(dstAddress)) { logInfo(lf_main, "write %s %s: %s", message->getCircuit().c_str(), message->getName().c_str(), getResultCode(ret)); - if (master[1] == BROADCAST) + if (dstAddress == BROADCAST) return "done broadcast"; return getResultCode(RESULT_OK); } - ret = message->decode(pt_slaveData, slave, result); // decode data + ret = message->decodeLastData(pt_slaveData, result); // decode data if (ret >= RESULT_OK && result.str().empty()) { logInfo(lf_main, "write %s %s: decode %s", message->getCircuit().c_str(), message->getName().c_str(), getResultCode(ret)); return getResultCode(RESULT_OK); @@ -758,7 +768,7 @@ string MainLoop::executeFind(vector &args) char str[32]; for (deque::iterator it = messages.begin(); it < messages.end();) { Message* message = *it++; - if (!id.empty() && !message->checkIdMatch(id)) { + if (!id.empty() && !message->checkIdPrefix(id)) { continue; } time_t lastup = message->getLastUpdateTime(); @@ -783,7 +793,7 @@ string MainLoop::executeFind(vector &args) if (ret!=RESULT_OK) { result << " (" << getResultCode(ret) << " for " << message->getLastMasterData().getDataStr() - << " / " << message->getLastSlaveData().getDataStr(); + << " / " << message->getLastSlaveData().getDataStr() << ")"; } } if (verbose) { @@ -1097,15 +1107,9 @@ string MainLoop::executeGet(vector &args, bool& connected) time_t lastup = message->getLastUpdateTime(); if (lastup == 0 && required) { // read directly from bus - SymbolString master(true); - SymbolString slave(false); - ret = readFromBus(message, master, "", slave); - if (ret == RESULT_OK) { - ostringstream temp; - ret = message->decode(pt_slaveData, slave, temp); - } + ret = readFromBus(message, ""); if (ret != RESULT_OK) - break; + continue; lastup = message->getLastUpdateTime(); } else { if (since > 0 && lastup <= since) @@ -1129,13 +1133,15 @@ string MainLoop::executeGet(vector &args, bool& connected) if (lastup != 0) { result << ",\n \"zz\": \"" << setfill('0') << setw(2) << hex << static_cast(dstAddress) << "\""; size_t pos = result.tellp(); - result << ",\n \"fields\": ["; + result << ",\n \"fields\": {"; result_t dret = message->decodeLastData(result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|OF_JSON); - result << "\n ]"; - if (dret!=RESULT_OK) { + if (dret==RESULT_OK) { + result << "\n }"; + } else { string prefix = result.str().substr(0, pos); - result.str(prefix); // remove written fields - result << ",\n \"decodeerror\": \"" << getResultCode(dret) << "\""; + result.str(""); + result.clear(); // remove written fields + result << prefix << ",\n \"decodeerror\": \"" << getResultCode(dret) << "\""; } } result << ",\n \"passive\": " << (message->isPassive() ? "true" : "false"); diff --git a/src/ebusd/mainloop.h b/src/ebusd/mainloop.h index df0e61fb..2800caeb 100644 --- a/src/ebusd/mainloop.h +++ b/src/ebusd/mainloop.h @@ -107,13 +107,11 @@ private: /** * Prepare the master part for the @a Message, send it to the bus and wait for the answer. * @param message the @a Message instance. - * @param master the master data @a SymbolString for writing symbols to. * @param inputStr the input @a string from which to read master values (if any). - * @param slave the @a SymbolString that will be filled with retrieved slave data. * @param dstAddress the destination address to set, or @a SYN to keep the address defined during construction. * @return the result code. */ - result_t readFromBus(Message* message, SymbolString& master, string inputStr, SymbolString& slave, const unsigned char dstAddress=SYN); + result_t readFromBus(Message* message, string inputStr, const unsigned char dstAddress=SYN); /** * Execute the read command.