From 2af6e55505e163bb985a30f2092830cb32ca6876 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 14 Dec 2014 18:09:16 +0100 Subject: [PATCH 1/6] added result code for invalid address --- src/lib/ebus/result.cpp | 7 ++++--- src/lib/ebus/result.h | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/lib/ebus/result.cpp b/src/lib/ebus/result.cpp index 15b8c0bc..6fce35f1 100644 --- a/src/lib/ebus/result.cpp +++ b/src/lib/ebus/result.cpp @@ -25,9 +25,9 @@ using namespace std; const char* getResultCode(result_t resultCode) { switch (resultCode) { case RESULT_OK: return "success"; - case RESULT_IN_ESC: return "success: escape sequence received"; - case RESULT_SYN: return "success: SYN received"; - case RESULT_EMPTY: return "success: empty"; + case RESULT_IN_ESC: return "escape sequence received"; + case RESULT_SYN: return "SYN received"; + case RESULT_EMPTY: return "empty"; case RESULT_ERR_GENERIC_IO: return "ERR: generic I/O error"; case RESULT_ERR_DEVICE: return "ERR: generic device error"; case RESULT_ERR_SEND: return "ERR: send error"; @@ -37,6 +37,7 @@ const char* getResultCode(result_t resultCode) { case RESULT_ERR_EOF: return "ERR: end of input reached"; case RESULT_ERR_INVALID_ARG: return "ERR: invalid argument"; case RESULT_ERR_INVALID_NUM: return "ERR: invalid numeric argument"; + case RESULT_ERR_INVALID_ADDR: return "ERR: invalid address"; case RESULT_ERR_INVALID_POS: return "ERR: invalid position"; case RESULT_ERR_OUT_OF_RANGE: return "ERR: argument value out of valid range"; case RESULT_ERR_INVALID_PART: return "ERR: invalid part type value"; diff --git a/src/lib/ebus/result.h b/src/lib/ebus/result.h index 774c04e1..4959d4f6 100644 --- a/src/lib/ebus/result.h +++ b/src/lib/ebus/result.h @@ -36,17 +36,18 @@ static const int RESULT_ERR_NOTFOUND = -6; // file/element not found or not static const int RESULT_ERR_EOF = -7; // end of input reached static const int RESULT_ERR_INVALID_ARG = -8; // invalid argument static const int RESULT_ERR_INVALID_NUM = -9; // invalid numeric argument -static const int RESULT_ERR_INVALID_POS = -10; // invalid position -static const int RESULT_ERR_OUT_OF_RANGE = -11; // argument value out of valid range -static const int RESULT_ERR_INVALID_PART = -12; // invalid part type value -static const int RESULT_ERR_MISSING_TYPE = -13; // missing data type -static const int RESULT_ERR_INVALID_LIST = -14; // invalid value list -static const int RESULT_ERR_DUPLICATE = -15; // duplicate entry +static const int RESULT_ERR_INVALID_ADDR = -10; // invalid address +static const int RESULT_ERR_INVALID_POS = -11; // invalid position +static const int RESULT_ERR_OUT_OF_RANGE = -12; // argument value out of valid range +static const int RESULT_ERR_INVALID_PART = -13; // invalid part type value +static const int RESULT_ERR_MISSING_TYPE = -14; // missing data type +static const int RESULT_ERR_INVALID_LIST = -15; // invalid value list +static const int RESULT_ERR_DUPLICATE = -16; // duplicate entry -static const int RESULT_ERR_BUS_LOST = -16; // arbitration lost -static const int RESULT_ERR_CRC = -17; // CRC error -static const int RESULT_ERR_ACK = -18; // ACK error -static const int RESULT_ERR_NAK = -19; // NAK received +static const int RESULT_ERR_BUS_LOST = -17; // arbitration lost +static const int RESULT_ERR_CRC = -18; // CRC error +static const int RESULT_ERR_ACK = -19; // ACK error +static const int RESULT_ERR_NAK = -20; // NAK received /** type for result code. */ typedef int result_t; From 6d8a82a524f9026490ee2b2802232670198a3780 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 14 Dec 2014 18:50:49 +0100 Subject: [PATCH 2/6] allow blank destination address (e.g. for scans), added MessageMap::findAll() --- src/lib/ebus/message.cpp | 60 +++++++++++++++++++++++++++++----------- src/lib/ebus/message.h | 14 ++++++++-- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index 48573b7d..380c77fb 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -71,21 +71,20 @@ Message::Message(const bool isSet, const bool isPassive, * @param pos the position in defaults. * @return the default if available and value is empty, or the value. */ -string getDefault(string value, vector* defaults, size_t pos) +string getDefault(const string value, vector* defaults, size_t pos) { if (value.length() > 0 || defaults == NULL || pos > defaults->size()) { return value; } - value = defaults->at(pos); - return value; + return defaults->at(pos); } result_t Message::create(vector::iterator& it, const vector::iterator end, vector< vector >* defaultsRows, DataFieldTemplates* templates, Message*& returnValue) { - // [type],[class],name,[comment],[QQ],ZZ,id,fields... + // [type],[class],name,[comment],[QQ],[ZZ],id,fields... result_t result; bool isSet = false, isPassive = false; string defaultName; @@ -148,24 +147,28 @@ result_t Message::create(vector::iterator& it, const vector::ite return RESULT_ERR_EOF; unsigned char srcAddress; if (*str == 0) - srcAddress = SYN; // no specific source defined + srcAddress = SYN; // no specific source else { srcAddress = parseInt(str, 16, 0, 0xff, result); if (result != RESULT_OK) return result; if (isMaster(srcAddress) == false) - return RESULT_ERR_INVALID_ARG; + return RESULT_ERR_INVALID_ADDR; } str = getDefault(*it++, defaults, defaultPos++).c_str(); if (it == end) - return RESULT_ERR_EOF; - - unsigned char dstAddress = parseInt(str, 16, 0, 0xff, result); - if (result != RESULT_OK) - return result; - if (isValidAddress(dstAddress) == false) - return RESULT_ERR_INVALID_ARG; + return RESULT_ERR_EOF; + unsigned char dstAddress; + if (*str == 0) + dstAddress = SYN; // no specific destination + else { + dstAddress = parseInt(str, 16, 0, 0xff, result); + if (result != RESULT_OK) + return result; + if (isValidAddress(dstAddress) == false) + return RESULT_ERR_INVALID_ADDR; + } vector id; for (int pos=0, useDefaults=1; pos<2; pos++) { // message id (PBSB, optional master data) @@ -229,7 +232,7 @@ result_t Message::create(vector::iterator& it, const vector::ite } } DataField* data = NULL; - result = DataField::create(it, realEnd, templates, data, isSet, dstAddress); + result = DataField::create(it, realEnd, templates, data, isSet, dstAddress==SYN ? ESC : dstAddress); if (result != RESULT_OK) { return result; } @@ -246,9 +249,11 @@ result_t Message::prepareMaster(const unsigned char srcAddress, SymbolString& ma result_t result = master.push_back(srcAddress, false, false); if (result != RESULT_OK) return result; - if (dstAddress == SYN) + if (dstAddress == SYN) { + if (m_dstAddress == SYN) + return RESULT_ERR_INVALID_ADDR; result = master.push_back(m_dstAddress, false, false); - else + } else result = master.push_back(dstAddress, false, false); if (result != RESULT_OK) return result; @@ -413,6 +418,29 @@ Message* MessageMap::find(const string& clazz, const string& name, const bool is return NULL; } +deque MessageMap::findAll(const string& clazz, const string& name, const short pb) +{ + deque ret; + + bool checkClass = clazz.length() > 0; + bool checkName = name.length() > 0; + bool checkPb = pb >= 0; + for (map::iterator it = m_messagesByName.begin(); it != m_messagesByName.end(); it++) { + if (it->first[0] != '-') // avoid duplicates: instances stored multiple times have a key starting with "-" + continue; + Message* message = it->second; + if (checkClass == true && message->getClass() != clazz) + continue; + if (checkName == true && message->getName() != name) + continue; + if (checkPb == true && message->getId()[0] != pb) + continue; + ret.push_back(message); + } + + return ret; +} + Message* MessageMap::find(SymbolString& master) { if (master.size() < 5) diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index f8335d2c..022c4684 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -25,6 +25,7 @@ #include "symbol.h" #include #include +#include #include using namespace std; @@ -48,7 +49,7 @@ public: * false if message can be initiated by any participant. * @param comment the comment. * @param srcAddress the source address, or @a SYN for any (only relevant if passive). - * @param dstAddress the destination address. + * @param dstAddress the destination address, or @a SYN for any (set later). * @param id the primary, secondary, and optional further ID bytes. * @param data the @a DataField for encoding/decoding the message. * @param pollPriority the priority for polling, or 0 for no polling at all. @@ -120,7 +121,7 @@ public: unsigned char getSrcAddress() const { return m_srcAddress; } /** * @brief Get the destination address. - * @return the destination address. + * @return the destination address, or @a SYN for any. */ unsigned char getDstAddress() const { return m_dstAddress; } /** @@ -280,6 +281,15 @@ public: * Note: the caller may not free the returned instance. */ Message* find(const string& clazz, const string& name, const bool isSet, const bool isPassive=false); + /** + * @brief Find all active get @a Message instances for the specified class and name. + * @param class the device class, or empty for any. + * @param name the message name, or empty for any. + * @param pb the primary ID byte, or -1 for any. + * @return the found @a Message instances. + * Note: the caller may not free the returned instances. + */ + deque findAll(const string& clazz, const string& name, const short pb); /** * @brief Find the @a Message instance for the specified master data. * @param master the master @a SymbolString for identifying the @a Message. From 5670c05a9a08352dba456b979cab1ac2962d769e Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 14 Dec 2014 18:54:49 +0100 Subject: [PATCH 3/6] added base type PIN, simplified ident fields --- src/lib/ebus/data.cpp | 27 ++++++++++++++------------- src/lib/ebus/data.h | 3 ++- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index e35b6644..1be9d40c 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -32,11 +32,11 @@ static const dataType_t stringDataType = { "STR",16*8,bt_str, ADJ, ' ', 1, 16, 0, 0 // >= 1 byte character string filled up with space }; -static const dataType_t bcdDataType = { - "BCD", 8, bt_num, BCD|LST, 0xff, 0, 0x99, 1, 0 // unsigned decimal in BCD, 0 - 99 +static const dataType_t pinDataType = { + "PIN", 16, bt_num, FIX|BCD|REV, 0xffff, 0, 0x9999, 1, 0 // unsigned decimal in BCD, 0000 - 9999 (fixed length) }; -static const dataType_t ucharDataType = { +static const dataType_t uchDataType = { "UCH", 8, bt_num, LST, 0xff, 0, 0xfe, 1, 0 // unsigned integer, 0 - 254 }; @@ -56,8 +56,9 @@ static const dataType_t dataTypes[] = { {"TTM", 8, bt_tim, 0, 0x90, 5, 5, 0, 0}, // truncated time (only multiple of 10 minutes), 00:00 - 24:00 (minutes div 10 + hour * 6 as integer) {"BDY", 8, bt_num, DAY|LST, 0x07, 0, 6, 1, 0}, // weekday, "Mon" - "Sun" (0x00 - 0x06) [ebus type] {"HDY", 8, bt_num, DAY|LST, 0x00, 1, 7, 1, 0}, // weekday, "Mon" - "Sun" (0x01 - 0x07) [Vaillant type] - bcdDataType, - ucharDataType, + {"BCD", 8, bt_num, BCD|LST, 0xff, 0, 0x99, 1, 0}, // unsigned decimal in BCD, 0 - 99 + pinDataType, + uchDataType, {"SCH", 8, bt_num, SIG, 0x80, 0x81, 0x7f, 1, 0}, // signed integer, -127 - +127 {"D1B", 8, bt_num, SIG, 0x80, 0x81, 0x7f, 1, 0}, // signed integer, -127 - +127 {"D1C", 8, bt_num, 0, 0xff, 0x00, 0xc8, 2, 1}, // unsigned number (fraction 1/2), 0 - 100 (0x00 - 0xc8, replacement 0xff) @@ -861,9 +862,11 @@ result_t NumberDataField::readSymbols(SymbolString& input, else signedValue = (int) value; - if (m_divisor <= 1) - output << static_cast(signedValue); - else + if (m_divisor <= 1) { + if ((m_dataType.flags & (FIX|BCD)) == (FIX|BCD)) + output << setw(m_length * 2) << setfill('0'); + output << static_cast(signedValue) << setw(0); + } else output << setprecision((m_bitCount % 8) == 0 ? m_dataType.precisionOrFirstBit : 0) << fixed << static_cast(signedValue / (float) m_divisor); @@ -1048,12 +1051,10 @@ DataFieldSet* DataFieldSet::createIdentFields() manufacturers[0xb5] = "Joh. Vaillant GmbH & Co."; manufacturers[0xc0] = "Toby AG"; manufacturers[0xc5] = "Max Weishaupt GmbH"; - fields.push_back(new ValueListDataField("manufacturer", "", "", ucharDataType, pt_slaveData, 1, 8, manufacturers)); + fields.push_back(new ValueListDataField("manufacturer", "", "", uchDataType, pt_slaveData, 1, 8, manufacturers)); fields.push_back(new StringDataField("id", "", "", stringDataType, pt_slaveData, 5)); - fields.push_back(new NumberDataField("swv", "", "", bcdDataType, pt_slaveData, 1, 8, 0)); - fields.push_back(new NumberDataField("swr", "", "", bcdDataType, pt_slaveData, 1, 8, 0)); - fields.push_back(new NumberDataField("hwv", "", "", bcdDataType, pt_slaveData, 1, 8, 0)); - fields.push_back(new NumberDataField("hwr", "", "", bcdDataType, pt_slaveData, 1, 8, 0)); + fields.push_back(new NumberDataField("software", "", "", pinDataType, pt_slaveData, 2, 16, 0)); + fields.push_back(new NumberDataField("hardware", "", "", pinDataType, pt_slaveData, 2, 16, 0)); return new DataFieldSet("ident", "", fields); } diff --git a/src/lib/ebus/data.h b/src/lib/ebus/data.h index e656ea97..75d4e41e 100644 --- a/src/lib/ebus/data.h +++ b/src/lib/ebus/data.h @@ -49,7 +49,7 @@ enum PartType { pt_any, // stored in any data (master or slave) pt_masterData, // stored in master data pt_slaveData, // stored in slave data - }; +}; /** the available base data types. */ enum BaseType { @@ -68,6 +68,7 @@ const unsigned int SIG = 0x08; // signed value const unsigned int LST = 0x10; // value list is possible (without applied divisor) const unsigned int DAY = 0x20; // forced value list defaulting to week days const unsigned int IGN = 0x40; // ignore value during read and write +const unsigned int FIX = 0x80; // fixed width formatting /** the structure for defining field types with their properties. */ typedef struct { From 3a55d7552c4d5ad7025c2da1ad699babb25f4319 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 14 Dec 2014 18:55:11 +0100 Subject: [PATCH 4/6] fix for new result code empty --- src/lib/ebus/test/test_data.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/ebus/test/test_data.cpp b/src/lib/ebus/test/test_data.cpp index 1423324a..93619fd6 100644 --- a/src/lib/ebus/test/test_data.cpp +++ b/src/lib/ebus/test/test_data.cpp @@ -250,17 +250,17 @@ int main() SymbolString writeMstr(mstr.getDataStr().substr(0, 10), false); SymbolString writeSstr(sstr.getDataStr().substr(0, 2), false); result = fields->read(pt_masterData, mstr, 0, output, false, verbose); - if (result == RESULT_OK) { + if (result >= RESULT_OK) { result = fields->read(pt_slaveData, sstr, 0, output, output.str().empty() == false, verbose); } if (failedRead == true) - if (result == RESULT_OK) + if (result >= RESULT_OK) cout << " failed read " << fields->getName() << " >" << check[2] << "< error: unexpectedly succeeded" << endl; else cout << " failed read " << fields->getName() << " >" << check[2] << "< OK" << endl; - else if (result != RESULT_OK) { + else if (result < RESULT_OK) { cout << " read " << fields->getName() << " >" << check[2] << "< error: " << getResultCode(result) << endl; } @@ -272,17 +272,17 @@ int main() if (verbose == false) { istringstream input(expectStr); result = fields->write(input, pt_masterData, writeMstr, 0); - if (result == RESULT_OK) + if (result >= RESULT_OK) result = fields->write(input, pt_slaveData, writeSstr, 0); if (failedWrite == true) { - if (result == RESULT_OK) + if (result >= RESULT_OK) cout << " failed write " << fields->getName() << " >" << expectStr << "< error: unexpectedly succeeded" << endl; else cout << " failed write " << fields->getName() << " >" << expectStr << "< OK" << endl; } - else if (result != RESULT_OK) { + else if (result < RESULT_OK) { cout << " write " << fields->getName() << " >" << expectStr << "< error: " << getResultCode(result) << endl; } From 118a0ea7d4a211e7a89db520527b3c9740d76f73 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 14 Dec 2014 18:58:15 +0100 Subject: [PATCH 5/6] completed individual scanning with definitions in "scan" class, nicer passing of received data to BusRequests --- src/ebusd/bushandler.cpp | 77 ++++++++++++++++++++++++++++------------ src/ebusd/bushandler.h | 43 ++++++++++++---------- 2 files changed, 79 insertions(+), 41 deletions(-) diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index 14e738b0..4a890221 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -26,6 +26,7 @@ #include "appl.h" #include #include +#include #include #include #include @@ -68,16 +69,18 @@ result_t PollRequest::prepare(unsigned char ownMasterAddress) return result; } -void PollRequest::notify(result_t result) +bool PollRequest::notify(result_t result, SymbolString& slave) { ostringstream output; if (result == RESULT_OK) { - result = m_message->decode(pt_slaveData, m_slave, output); // decode data + result = m_message->decode(pt_slaveData, slave, output); // decode data } if (result != RESULT_OK) L.log(bus, error, "poll %s failed: %s", m_message->getName().c_str(), getResultCode(result)); else L.log(bus, event, "poll %s: %s", m_message->getName().c_str(), output.str().c_str()); + + return false; } @@ -90,27 +93,47 @@ result_t ScanRequest::prepare(unsigned char ownMasterAddress, unsigned char dstA return result; } -void ScanRequest::notify(result_t result) +bool ScanRequest::notify(result_t result, SymbolString& slave) { unsigned char dstAddress = m_master[1]; + bool append = m_scanResults != NULL && m_scanResults->find(dstAddress) != m_scanResults->end(); ostringstream scanResult; if (result == RESULT_OK) { - scanResult << hex << setw(2) << setfill('0') << static_cast(dstAddress) << UI_FIELD_SEPARATOR; - result = m_message->decode(pt_slaveData, m_slave, scanResult); // decode data + if (append == false) + scanResult << hex << setw(2) << setfill('0') << static_cast(dstAddress) << UI_FIELD_SEPARATOR; + result = m_message->decode(pt_slaveData, slave, scanResult, append); // decode data } - if (result != RESULT_OK) + if (result != RESULT_OK) { L.log(bus, error, "scan %2.2x failed: %s", dstAddress, getResultCode(result)); - else { - string str = scanResult.str(); - L.log(bus, event, "scan: %s", str.c_str()); - if (m_scanResults != NULL) + return false; + } + + string str = scanResult.str(); + L.log(bus, event, "scan: %s", str.c_str()); + if (m_scanResults != NULL) { + if (append == true) + (*m_scanResults)[dstAddress] += str; + else (*m_scanResults)[dstAddress] = str; } + + // check for remaining secondary messages + if (m_messages.empty() == true) + return false; + + m_message = m_messages.front(); + m_messages.pop_front(); + + result = prepare(m_master[0], dstAddress); + if (result != RESULT_OK) + return false; // give up + + return true; } ActiveBusRequest::ActiveBusRequest(SymbolString& master, SymbolString& slave) - : BusRequest(master, slave, false), m_finished(false), m_result(RESULT_SYN) + : BusRequest(master, false), m_finished(false), m_result(RESULT_SYN), m_slave(slave) { pthread_mutex_init(&m_mutex, NULL); pthread_cond_init(&m_cond, NULL); @@ -144,18 +167,20 @@ bool ActiveBusRequest::wait(int timeout) return result == 0; } -void ActiveBusRequest::notify(result_t result) +bool ActiveBusRequest::notify(result_t result, SymbolString& slave) { if (result == RESULT_OK) - L.log(bus, event, "read res: %s", m_slave.getDataStr().c_str()); + L.log(bus, event, "read res: %s", slave.getDataStr().c_str()); pthread_mutex_lock(&m_mutex); m_result = result; + m_slave = SymbolString(slave, false, false); m_finished = true; pthread_cond_signal(&m_cond); pthread_mutex_unlock(&m_mutex); + return false; } @@ -226,7 +251,7 @@ result_t BusHandler::handleSymbol() Message* message = m_messages->getNextPoll(); if (message != NULL) { m_lastPoll = now; - PollRequest* request = new PollRequest(m_response, message); + PollRequest* request = new PollRequest(message); result_t ret = request->prepare(m_ownMasterAddress); if (ret != RESULT_OK) { L.log(bus, error, "prepare poll message: %s", getResultCode(ret)); @@ -574,12 +599,15 @@ result_t BusHandler::setState(BusState state, result_t result, bool firstRepetit m_request = NULL; } else if (state == bs_sendSyn || (result != RESULT_OK && firstRepetition == false)) { L.log(bus, debug, "notify request: %s", getResultCode(result)); - m_request->m_slave = SymbolString(m_response, false, false); + bool restart = m_request->notify(result, m_response); unsigned char dstAddress = m_request->m_master[1]; if (result == RESULT_OK && isValidAddress(dstAddress, false) == true) m_seenAddresses[dstAddress] = true; - m_request->notify(result); - if (m_request->m_deleteOnFinish == true) { + if (restart == true) { + m_request->m_busLostRetries = 0; + m_requests.add(m_request); + } + else if (m_request->m_deleteOnFinish == true) { delete m_request; } m_request = NULL; @@ -642,8 +670,14 @@ void BusHandler::receiveCompleted() result_t BusHandler::startScan(bool full) { Message* scanMessage = m_scanMessage; - if (scanMessage == NULL) { - scanMessage = m_messages->find("", "scan", false); + deque messages = m_messages->findAll("scan", "", -1); + for (deque::iterator it = messages.begin(); it < messages.end();) { + Message* message = *it++; + if (message->getId()[0] == 0x07 && message->getId()[1] == 0x04) { + if (scanMessage == NULL) + scanMessage = message; + messages.erase(it - 1); // query pb 0x07 / sb 0x04 only once + } } if (scanMessage == NULL) { DataFieldSet* identFields = DataFieldSet::createIdentFields(); @@ -652,8 +686,7 @@ result_t BusHandler::startScan(bool full) if (scanMessage == NULL) return RESULT_ERR_NOTFOUND; - if (full == true) - m_scanResults.clear(); + m_scanResults.clear(); for (unsigned int slave=0; slave<=255; slave++) { if (isValidAddress(slave, false) == false || isMaster(slave) == true) @@ -664,7 +697,7 @@ result_t BusHandler::startScan(bool full) continue; } - ScanRequest* request = new ScanRequest(m_response, scanMessage, &m_scanResults); + ScanRequest* request = new ScanRequest(scanMessage, messages, &m_scanResults); result_t result = request->prepare(m_ownMasterAddress, slave); if (result != RESULT_OK) { delete request; diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index a1e5c1f6..b0d74bec 100644 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -71,11 +71,10 @@ public: /** * @brief Constructor. * @param master the master data @a SymbolString to send. - * @param slave the slave data @a SymbolString received. * @param deleteOnFinish whether to automatically delete this @a BusRequest when finished. */ - BusRequest(SymbolString& master, SymbolString& slave, bool deleteOnFinish) - : m_master(master), m_slave(slave), m_busLostRetries(0), + BusRequest(SymbolString& master, const bool deleteOnFinish) + : m_master(master), m_busLostRetries(0), m_deleteOnFinish(deleteOnFinish) {} /** @@ -86,22 +85,21 @@ public: /** * @brief Notify the request of the specified result. * @param result the result of the request. + * @param slave the slave data @a SymbolString received. + * @return true if the request needs to be restarted. */ - virtual void notify(result_t result) = 0; + virtual bool notify(result_t result, SymbolString& slave) = 0; protected: /** the master data @a SymbolString to send. */ SymbolString& m_master; - /** the slave data @a SymbolString received. */ - SymbolString& m_slave; - /** the number of times a send is repeated due to lost arbitration. */ unsigned int m_busLostRetries; /** whether to automatically delete this @a BusRequest when finished. */ - bool m_deleteOnFinish; + const bool m_deleteOnFinish; }; @@ -119,8 +117,8 @@ public: * @param slave the slave data @a SymbolString received. * @param message the associated @a Message. */ - PollRequest(SymbolString& slave, Message* message) - : BusRequest(m_master, slave, true), m_message(message) {} + PollRequest(Message* message) + : BusRequest(m_master, true), m_message(message) {} /** * @brief Destructor. @@ -135,7 +133,7 @@ public: result_t prepare(unsigned char masterAddress); // @copydoc - virtual void notify(result_t result); + virtual bool notify(result_t result, SymbolString& slave); private: @@ -159,12 +157,13 @@ public: /** * @brief Constructor. * @param slave the slave data @a SymbolString received. - * @param message the associated @a Message. + * @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 scanResults the map in which to store the formatted scan result by slave address. */ - ScanRequest(SymbolString& slave, Message* message, + ScanRequest(Message* message, deque messages, map* scanResults) - : BusRequest(m_master, slave, true), m_message(message), + : BusRequest(m_master, true), m_message(message), m_messages(messages), m_scanResults(scanResults) {} /** @@ -181,16 +180,19 @@ public: result_t prepare(unsigned char masterAddress, unsigned char dstAddress); // @copydoc - virtual void notify(result_t result); + virtual bool notify(result_t result, SymbolString& slave); private: /** the master data @a SymbolString. */ SymbolString m_master; - /** the associated @a Message. */ + /** the currently queried @a Message. */ Message* m_message; + /** the remaining secondary @a Message instances. */ + deque m_messages; + /** the map in which to store the formatted scan result by slave address. */ map* m_scanResults; @@ -207,8 +209,8 @@ public: /** * @brief Constructor. - * @param master the master data @a SymbolString to send. - * @param slave the slave data @a SymbolString received. + * @param master reference to the master data @a SymbolString to send. + * @param slave reference to @a SymbolString for filling in the received slave data. */ ActiveBusRequest(SymbolString& master, SymbolString& slave); @@ -225,7 +227,7 @@ public: bool wait(int timeout); // @copydoc - virtual void notify(result_t result); + virtual bool notify(result_t result, SymbolString& slave); private: @@ -235,6 +237,9 @@ private: /** the result of handling the request. */ result_t m_result; + /** reference to @a SymbolString for filling in the received slave data. */ + SymbolString& m_slave; + /** a mutex for wait/notify. */ pthread_mutex_t m_mutex; From 2df7bc75b24b6be1f571122b2e5409a663f1fe62 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 14 Dec 2014 18:58:44 +0100 Subject: [PATCH 6/6] deny invalid destination address in write hex --- src/ebusd/baseloop.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ebusd/baseloop.cpp b/src/ebusd/baseloop.cpp index a79117c8..fbac03fb 100644 --- a/src/ebusd/baseloop.cpp +++ b/src/ebusd/baseloop.cpp @@ -351,6 +351,10 @@ string BaseLoop::decodeMessage(const string& data) break; SymbolString master(msg.str()); + if (isValidAddress(master[1]) == false) { + result << "invalid destination"; + break; + } L.log(bas, event, "write hex cmd: %s", master.getDataStr().c_str()); // send message