From dd3721e7f40fd84c90d7bb898d8643e998193e41 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 11 Nov 2023 09:30:01 +0100 Subject: [PATCH] rework info transfer, missed commit --- src/lib/ebus/device.cpp | 106 ++++++++++++++++++++++--------- src/lib/ebus/device.h | 25 +++++--- src/lib/ebus/protocol_direct.cpp | 22 +++++++ 3 files changed, 116 insertions(+), 37 deletions(-) diff --git a/src/lib/ebus/device.cpp b/src/lib/ebus/device.cpp index da3ee80c..ced40f58 100755 --- a/src/lib/ebus/device.cpp +++ b/src/lib/ebus/device.cpp @@ -110,9 +110,10 @@ FileDevice::FileDevice(const char* name, bool checkDevice, unsigned int latency, m_checkDevice(checkDevice), m_latency(HOST_LATENCY_MS+(enhancedLevel?ENHANCED_LATENCY_MS:0)+latency), m_enhancedLevel(enhancedLevel), m_fd(-1), m_resetRequested(false), - m_arbitrationMaster(SYN), - m_arbitrationCheck(0), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0), - m_extraFatures(0), m_infoId(0xff), m_infoReqTime(0), m_infoLen(0), m_infoPos(0) { + m_arbitrationMaster(SYN), m_arbitrationCheck(0), + m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0), + m_sendBuf(nullptr), m_sendBufSize(0), + m_extraFatures(0), m_infoReqTime(0), m_infoLen(0), m_infoPos(0) { m_buffer = reinterpret_cast(malloc(m_bufSize)); if (!m_buffer) { m_bufSize = 0; @@ -125,6 +126,10 @@ FileDevice::~FileDevice() { free(m_buffer); m_buffer = nullptr; } + if (m_sendBuf) { + free(m_sendBuf); + m_sendBuf = nullptr; + } } void FileDevice::formatInfo(ostringstream* ostream, bool verbose, bool prefix) { @@ -211,18 +216,18 @@ result_t FileDevice::requestEnhancedInfo(symbol_t infoId) { return RESULT_ERR_INVALID_ARG; } for (unsigned int i = 0; i < 4; i++) { - if (m_infoId == 0xff) { + if (m_infoLen == 0) { break; } usleep(40000 + i*40000); } - if (m_infoId != 0xff) { + if (m_infoLen > 0) { if (m_infoReqTime > 0 && time(NULL) > m_infoReqTime+5) { // request timed out if (m_listener != nullptr) { m_listener->notifyDeviceStatus(false, "info request timed out"); } - m_infoId = 0xff; + m_infoLen = 0; m_infoReqTime = 0; } else { return RESULT_ERR_DUPLICATE; @@ -232,19 +237,67 @@ result_t FileDevice::requestEnhancedInfo(symbol_t infoId) { // just waited for completion return RESULT_OK; } - return sendEnhancedInfoRequest(infoId); + return sendSequence(sid_info, &infoId, 1); } -result_t FileDevice::sendEnhancedInfoRequest(symbol_t infoId) { - symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INFO, infoId); - DEBUG_RAW_TRAFFIC("enhanced > %2.2x %2.2x", buf[0], buf[1]); - if (::write(m_fd, buf, 2) != 2) { +result_t FileDevice::sendSequence(SequenceId id, const uint8_t* data, size_t len) { + if (!isValid()) { return RESULT_ERR_DEVICE; } - m_infoPos = 0; - m_infoId = infoId; - time(&m_infoReqTime); - return RESULT_OK; + if (m_enhancedLevel >= el_basic && id==sid_info && (m_extraFatures&0x01) != 0) { + // request is supported + } else { + return RESULT_ERR_NOTFOUND; // not supported + } + size_t pos = (1+len)*2; + if (pos > m_sendBufSize) { + m_sendBuf = static_cast(realloc(m_sendBuf, pos)); + if (!m_sendBuf) { + m_sendBufSize = 0; + return RESULT_ERR_DEVICE; + } + m_sendBufSize = pos; + } + pos = 0; + uint8_t cmd = id==sid_info ? ENH_REQ_INFO : 0; + if (cmd == 0) { + return RESULT_ERR_NOTFOUND; // not supported + } + if (cmd & 0x8) { + // sequence-encoded + m_sendBuf[pos++] = makeEnhancedByte1(cmd, len); + m_sendBuf[pos++] = makeEnhancedByte2(cmd, len); + cmd = static_cast(cmd & ~0x8); + } else { + // direct-encoded + uint8_t val = data ? *data : 0; + m_sendBuf[pos++] = makeEnhancedByte1(cmd, val); + m_sendBuf[pos++] = makeEnhancedByte2(cmd, val); + if (id==sid_info) { + m_infoBuf[0] = val; + m_infoLen = 0; + } + if (len > 0) { + len--; + data++; + } + } + while (len > 0) { + m_sendBuf[pos++] = makeEnhancedByte1(cmd, *data); + m_sendBuf[pos++] = makeEnhancedByte2(cmd, *data); + data++; + len--; + } + // DEBUG_RAW_TRAFFIC("enhanced > %2.2x %2.2x", buf[0], buf[1]); + if (::write(m_fd, m_sendBuf, pos) == pos) { + if (id==sid_info) { + m_infoLen = 1; + m_infoPos = 1; + time(&m_infoReqTime); + } + return RESULT_OK; + } + return RESULT_ERR_DEVICE; } string FileDevice::getEnhancedInfos() { @@ -266,8 +319,7 @@ string FileDevice::getEnhancedInfos() { if (res != RESULT_OK) { fails += ", cannot request config"; requestEnhancedInfo(0xff); // wait for completion - m_infoPos = 0; - m_infoId = 0xff; + m_infoLen = 0; // cancel anyway } } res = requestEnhancedInfo(6); @@ -289,8 +341,7 @@ string FileDevice::getEnhancedInfos() { res = requestEnhancedInfo(0xff); // wait for completion if (res != RESULT_OK) { m_enhInfoBusVoltage = "bus voltage unknown"; - m_infoPos = 0; - m_infoId = 0xff; + m_infoLen = 0; // cancel anyway } return "firmware " + m_enhInfoVersion + ", " + m_enhInfoTemperature + ", " + m_enhInfoSupplyVoltage + ", " + m_enhInfoBusVoltage; @@ -669,12 +720,12 @@ bool FileDevice::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* a m_enhInfoTemperature = ""; m_enhInfoSupplyVoltage = ""; m_enhInfoBusVoltage = ""; - m_infoId = 0xff; + m_infoLen = 0; m_extraFatures = data; if (m_resetRequested) { m_resetRequested = false; if (m_extraFatures&0x01) { - sendEnhancedInfoRequest(0); // request version, ignore result + sendSequence(sid_info); // request version, ignore result } } else { close(); // on self-reset of device close and reopen it to have a clean startup @@ -685,19 +736,16 @@ bool FileDevice::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* a } break; case ENH_RES_INFO: - if (m_infoLen == 0) { - m_infoLen = data; - m_infoPos = 0; + if (m_infoLen == 1) { + m_infoLen = data+1; } else if (m_infoPos < m_infoLen && m_infoPos < sizeof(m_infoBuf)) { m_infoBuf[m_infoPos++] = data; if (m_infoPos >= m_infoLen) { notifyInfoRetrieved(); m_infoLen = 0; - m_infoId = 0xff; } } else { m_infoLen = 0; // reset on invalid response - m_infoId = 0xff; } break; case ENH_RES_ERROR_EBUS: @@ -736,9 +784,9 @@ bool FileDevice::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* a } void FileDevice::notifyInfoRetrieved() { - symbol_t* data = m_infoBuf; - size_t len = m_infoLen; - symbol_t id = m_infoId; + symbol_t id = m_infoBuf[0]; + symbol_t* data = m_infoBuf+1; + size_t len = m_infoLen-1; unsigned int val; ostringstream stream; switch ((len << 8) | id) { diff --git a/src/lib/ebus/device.h b/src/lib/ebus/device.h index 60bfa53b..41fc7e64 100755 --- a/src/lib/ebus/device.h +++ b/src/lib/ebus/device.h @@ -65,6 +65,11 @@ enum ArbitrationState { as_won, //!< arbitration won }; +/** the sequence IDs as handled by @a FileDevice. */ +enum SequenceId { + sid_info, //!< send/receive info +}; + /** * Interface for listening to data received on/sent to a device. */ @@ -296,11 +301,13 @@ class FileDevice : public Device { result_t requestEnhancedInfo(symbol_t infoId); /** - * Send a request for extra infos to enhanced device. - * @param infoId the ID of the info to request. - * @return @a RESULT_OK on success, or an error code otherwise. + * Write a sequence of bytes to the device. + * @param id the ID of the sequence. + * @param data the buffer with the data to send. + * @param len the length of the buffer. + * @return the @a result_t code. */ - result_t sendEnhancedInfoRequest(symbol_t infoId); + virtual result_t sendSequence(SequenceId id, const uint8_t* data = nullptr, size_t len = 0); /** * Get the enhanced device version. @@ -399,13 +406,15 @@ class FileDevice : public Device { /** the read buffer read position. */ size_t m_bufPos; + /** the send buffer. */ + uint8_t* m_sendBuf; + + /** the send buffer size. */ + size_t m_sendBufSize; /** the extra features supported by the device. */ symbol_t m_extraFatures; - /** the ID of the last requested info. */ - symbol_t m_infoId; - /** the time of the last info request. */ time_t m_infoReqTime; @@ -416,7 +425,7 @@ class FileDevice : public Device { size_t m_infoPos; /** the info buffer. */ - symbol_t m_infoBuf[16]; + symbol_t m_infoBuf[16+1]; /** a string describing the enhanced device version. */ string m_enhInfoVersion; diff --git a/src/lib/ebus/protocol_direct.cpp b/src/lib/ebus/protocol_direct.cpp index 6b789e23..80eb1e30 100644 --- a/src/lib/ebus/protocol_direct.cpp +++ b/src/lib/ebus/protocol_direct.cpp @@ -52,6 +52,28 @@ const char* getStateCode(BusState state) { } } +/** + * The @a ProtocolState value by internal @a BusState value index. + */ +static const ProtocolState protocolStateByBusState[] = { + ps_noSignal, // bs_noSignal + ps_idle, // bs_skip + ps_idle, // bs_ready + ps_recv, // bs_recvCmd + ps_recv, // bs_recvCmdCrc + ps_recv, // bs_recvCmdAck + ps_recv, // bs_recvRes + ps_recv, // bs_recvResCrc + ps_recv, // bs_recvResAck + ps_send, // bs_sendCmd + ps_send, // bs_sendCmdCrc + ps_send, // bs_sendResAck + ps_send, // bs_sendCmdAck + ps_send, // bs_sendRes + ps_send, // bs_sendResCrc + ps_send, // bs_sendSyn +}; + void DirectProtocolHandler::run() { unsigned int symCount = 0;