rework info transfer, missed commit
This commit is contained in:
+77
-29
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user