rework info transfer, missed commit

This commit is contained in:
John
2023-11-11 09:30:01 +01:00
parent bfe7b451a5
commit dd3721e7f4
3 changed files with 116 additions and 37 deletions
+77 -29
View File
@@ -110,9 +110,10 @@ FileDevice::FileDevice(const char* name, bool checkDevice, unsigned int latency,
m_checkDevice(checkDevice), m_checkDevice(checkDevice),
m_latency(HOST_LATENCY_MS+(enhancedLevel?ENHANCED_LATENCY_MS:0)+latency), m_latency(HOST_LATENCY_MS+(enhancedLevel?ENHANCED_LATENCY_MS:0)+latency),
m_enhancedLevel(enhancedLevel), m_fd(-1), m_resetRequested(false), m_enhancedLevel(enhancedLevel), m_fd(-1), m_resetRequested(false),
m_arbitrationMaster(SYN), m_arbitrationMaster(SYN), m_arbitrationCheck(0),
m_arbitrationCheck(0), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(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_sendBuf(nullptr), m_sendBufSize(0),
m_extraFatures(0), m_infoReqTime(0), m_infoLen(0), m_infoPos(0) {
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize)); m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
if (!m_buffer) { if (!m_buffer) {
m_bufSize = 0; m_bufSize = 0;
@@ -125,6 +126,10 @@ FileDevice::~FileDevice() {
free(m_buffer); free(m_buffer);
m_buffer = nullptr; m_buffer = nullptr;
} }
if (m_sendBuf) {
free(m_sendBuf);
m_sendBuf = nullptr;
}
} }
void FileDevice::formatInfo(ostringstream* ostream, bool verbose, bool prefix) { 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; return RESULT_ERR_INVALID_ARG;
} }
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
if (m_infoId == 0xff) { if (m_infoLen == 0) {
break; break;
} }
usleep(40000 + i*40000); usleep(40000 + i*40000);
} }
if (m_infoId != 0xff) { if (m_infoLen > 0) {
if (m_infoReqTime > 0 && time(NULL) > m_infoReqTime+5) { if (m_infoReqTime > 0 && time(NULL) > m_infoReqTime+5) {
// request timed out // request timed out
if (m_listener != nullptr) { if (m_listener != nullptr) {
m_listener->notifyDeviceStatus(false, "info request timed out"); m_listener->notifyDeviceStatus(false, "info request timed out");
} }
m_infoId = 0xff; m_infoLen = 0;
m_infoReqTime = 0; m_infoReqTime = 0;
} else { } else {
return RESULT_ERR_DUPLICATE; return RESULT_ERR_DUPLICATE;
@@ -232,19 +237,67 @@ result_t FileDevice::requestEnhancedInfo(symbol_t infoId) {
// just waited for completion // just waited for completion
return RESULT_OK; return RESULT_OK;
} }
return sendEnhancedInfoRequest(infoId); return sendSequence(sid_info, &infoId, 1);
} }
result_t FileDevice::sendEnhancedInfoRequest(symbol_t infoId) { result_t FileDevice::sendSequence(SequenceId id, const uint8_t* data, size_t len) {
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INFO, infoId); if (!isValid()) {
DEBUG_RAW_TRAFFIC("enhanced > %2.2x %2.2x", buf[0], buf[1]);
if (::write(m_fd, buf, 2) != 2) {
return RESULT_ERR_DEVICE; return RESULT_ERR_DEVICE;
} }
m_infoPos = 0; if (m_enhancedLevel >= el_basic && id==sid_info && (m_extraFatures&0x01) != 0) {
m_infoId = infoId; // request is supported
time(&m_infoReqTime); } else {
return RESULT_OK; return RESULT_ERR_NOTFOUND; // not supported
}
size_t pos = (1+len)*2;
if (pos > m_sendBufSize) {
m_sendBuf = static_cast<uint8_t*>(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<uint8_t>(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() { string FileDevice::getEnhancedInfos() {
@@ -266,8 +319,7 @@ string FileDevice::getEnhancedInfos() {
if (res != RESULT_OK) { if (res != RESULT_OK) {
fails += ", cannot request config"; fails += ", cannot request config";
requestEnhancedInfo(0xff); // wait for completion requestEnhancedInfo(0xff); // wait for completion
m_infoPos = 0; m_infoLen = 0; // cancel anyway
m_infoId = 0xff;
} }
} }
res = requestEnhancedInfo(6); res = requestEnhancedInfo(6);
@@ -289,8 +341,7 @@ string FileDevice::getEnhancedInfos() {
res = requestEnhancedInfo(0xff); // wait for completion res = requestEnhancedInfo(0xff); // wait for completion
if (res != RESULT_OK) { if (res != RESULT_OK) {
m_enhInfoBusVoltage = "bus voltage unknown"; m_enhInfoBusVoltage = "bus voltage unknown";
m_infoPos = 0; m_infoLen = 0; // cancel anyway
m_infoId = 0xff;
} }
return "firmware " + m_enhInfoVersion + ", " + m_enhInfoTemperature + ", " + m_enhInfoSupplyVoltage + ", " return "firmware " + m_enhInfoVersion + ", " + m_enhInfoTemperature + ", " + m_enhInfoSupplyVoltage + ", "
+ m_enhInfoBusVoltage; + m_enhInfoBusVoltage;
@@ -669,12 +720,12 @@ bool FileDevice::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* a
m_enhInfoTemperature = ""; m_enhInfoTemperature = "";
m_enhInfoSupplyVoltage = ""; m_enhInfoSupplyVoltage = "";
m_enhInfoBusVoltage = ""; m_enhInfoBusVoltage = "";
m_infoId = 0xff; m_infoLen = 0;
m_extraFatures = data; m_extraFatures = data;
if (m_resetRequested) { if (m_resetRequested) {
m_resetRequested = false; m_resetRequested = false;
if (m_extraFatures&0x01) { if (m_extraFatures&0x01) {
sendEnhancedInfoRequest(0); // request version, ignore result sendSequence(sid_info); // request version, ignore result
} }
} else { } else {
close(); // on self-reset of device close and reopen it to have a clean startup 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; break;
case ENH_RES_INFO: case ENH_RES_INFO:
if (m_infoLen == 0) { if (m_infoLen == 1) {
m_infoLen = data; m_infoLen = data+1;
m_infoPos = 0;
} else if (m_infoPos < m_infoLen && m_infoPos < sizeof(m_infoBuf)) { } else if (m_infoPos < m_infoLen && m_infoPos < sizeof(m_infoBuf)) {
m_infoBuf[m_infoPos++] = data; m_infoBuf[m_infoPos++] = data;
if (m_infoPos >= m_infoLen) { if (m_infoPos >= m_infoLen) {
notifyInfoRetrieved(); notifyInfoRetrieved();
m_infoLen = 0; m_infoLen = 0;
m_infoId = 0xff;
} }
} else { } else {
m_infoLen = 0; // reset on invalid response m_infoLen = 0; // reset on invalid response
m_infoId = 0xff;
} }
break; break;
case ENH_RES_ERROR_EBUS: case ENH_RES_ERROR_EBUS:
@@ -736,9 +784,9 @@ bool FileDevice::handleEnhancedBufferedData(symbol_t* value, ArbitrationState* a
} }
void FileDevice::notifyInfoRetrieved() { void FileDevice::notifyInfoRetrieved() {
symbol_t* data = m_infoBuf; symbol_t id = m_infoBuf[0];
size_t len = m_infoLen; symbol_t* data = m_infoBuf+1;
symbol_t id = m_infoId; size_t len = m_infoLen-1;
unsigned int val; unsigned int val;
ostringstream stream; ostringstream stream;
switch ((len << 8) | id) { switch ((len << 8) | id) {
+17 -8
View File
@@ -65,6 +65,11 @@ enum ArbitrationState {
as_won, //!< arbitration won 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. * 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); result_t requestEnhancedInfo(symbol_t infoId);
/** /**
* Send a request for extra infos to enhanced device. * Write a sequence of bytes to the device.
* @param infoId the ID of the info to request. * @param id the ID of the sequence.
* @return @a RESULT_OK on success, or an error code otherwise. * @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. * Get the enhanced device version.
@@ -399,13 +406,15 @@ class FileDevice : public Device {
/** the read buffer read position. */ /** the read buffer read position. */
size_t m_bufPos; 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. */ /** the extra features supported by the device. */
symbol_t m_extraFatures; symbol_t m_extraFatures;
/** the ID of the last requested info. */
symbol_t m_infoId;
/** the time of the last info request. */ /** the time of the last info request. */
time_t m_infoReqTime; time_t m_infoReqTime;
@@ -416,7 +425,7 @@ class FileDevice : public Device {
size_t m_infoPos; size_t m_infoPos;
/** the info buffer. */ /** the info buffer. */
symbol_t m_infoBuf[16]; symbol_t m_infoBuf[16+1];
/** a string describing the enhanced device version. */ /** a string describing the enhanced device version. */
string m_enhInfoVersion; string m_enhInfoVersion;
+22
View File
@@ -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() { void DirectProtocolHandler::run() {
unsigned int symCount = 0; unsigned int symCount = 0;