fix some issues with double-length DVM frames ($FD) where sometimes the serial port would still be buffering data and would return 0 bytes when the packet length was attempted to be read;

r05a06_dev
Bryan Biedenkapp 2 days ago
parent 5d7de897f3
commit 054f157096

@ -32,6 +32,8 @@ using namespace modem;
#define CONFIG_OPT_ALTERED_STR "Configuration option manually altered; "
#define MODEM_CONFIG_AREA_DISAGREE_STR "modem configuration area disagreement, "
#define MAX_GET_RESPONSE_RETRIES 10U
// ---------------------------------------------------------------------------
// Macros
// ---------------------------------------------------------------------------
@ -2399,125 +2401,119 @@ void Modem::printDebug(const uint8_t* buffer, uint16_t len)
RESP_TYPE_DVM Modem::getResponse()
{
uint8_t retries = 0U;
m_rspDoubleLength = false;
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "checking if we have data");
// get the start of the frame or nothing at all
if (m_rspState == RESP_START) {
int ret = m_port->read(m_buffer + 0U, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
}
if (ret == 0) {
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "no data available");
return RTM_TIMEOUT;
}
while (true) {
// get the start of the frame or nothing at all
if (m_rspState == RESP_START) {
int ret = m_port->read(m_buffer + 0U, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
}
if (m_buffer[0U] != DVM_SHORT_FRAME_START &&
m_buffer[0U] != DVM_LONG_FRAME_START) {
//LogErrorEx(LOG_MODEM, "Modem::getResponse()", "illegal response, first byte not a frame start; byte = %02X", m_buffer[0U]);
::memset(m_buffer, 0x00U, BUFFER_LENGTH);
m_rspState = RESP_START;
return RTM_ERROR;
}
// received 0 bytes, which means no data is available, so we should just return and wait for the next time
if (ret == 0) {
//LogError(LOG_MODEM, "RESP_START, No data received from the modem");
return RTM_TIMEOUT;
}
if (m_buffer[0U] == DVM_LONG_FRAME_START) {
m_rspDoubleLength = true;
}
if (m_buffer[0U] != DVM_SHORT_FRAME_START &&
m_buffer[0U] != DVM_LONG_FRAME_START) {
//LogErrorEx(LOG_MODEM, "Modem::getResponse()", "illegal response, first byte not a frame start; byte = %02X", m_buffer[0U]);
::memset(m_buffer, 0x00U, BUFFER_LENGTH);
m_rspState = RESP_START;
return RTM_ERROR;
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_START");
if (m_buffer[0U] == DVM_LONG_FRAME_START) {
m_rspDoubleLength = true;
}
m_rspState = RESP_LENGTH1;
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_START");
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "getting frame length 1/2, rspDoubleLength = %u", m_rspDoubleLength);
// get the length of the frame, 1/2
if (m_rspState == RESP_LENGTH1) {
int ret = m_port->read(m_buffer + 1U, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
m_rspState = RESP_LENGTH1;
}
if (ret == 0)
return RTM_TIMEOUT;
// get the length of the frame, 1/2
if (m_rspState == RESP_LENGTH1) {
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_LENGTH1, getting frame length 1/2, rspDoubleLength = %u, retries = %u", m_rspDoubleLength, retries);
int ret = m_port->read(m_buffer + 1U, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
}
if (m_buffer[1U] >= 250U && !m_rspDoubleLength) {
LogError(LOG_MODEM, "Invalid length received from the modem, len = %u", m_buffer[1U]);
m_rspState = RESP_START;
return RTM_ERROR;
}
// received 0 bytes, which means no data is available, so we should just return and wait for the next time
// to check for data
if (ret == 0) {
if (retries >= MAX_GET_RESPONSE_RETRIES) {
LogError(LOG_MODEM, "RESP_LENGTH1, No data received from the modem after %u attempts", retries);
return RTM_TIMEOUT;
} else {
retries++;
Thread::sleep(10U);
continue;
}
}
if (m_rspDoubleLength) {
m_rspState = RESP_LENGTH2;
m_length = ((m_buffer[1U] & 0xFFU) << 8);
} else {
m_rspState = RESP_TYPE;
m_length = m_buffer[1U];
}
if (m_buffer[1U] >= 250U && !m_rspDoubleLength) {
LogError(LOG_MODEM, "Invalid length received from the modem, len = %u", m_buffer[1U]);
m_rspState = RESP_START;
return RTM_ERROR;
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_LENGTH1, len = %u", m_length);
if (m_rspDoubleLength) {
m_rspState = RESP_LENGTH2;
m_length = ((m_buffer[1U] & 0xFFU) << 8);
} else {
m_rspState = RESP_TYPE;
m_length = m_buffer[1U];
}
m_rspOffset = 2U;
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_LENGTH1, len = %u", m_length);
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "getting frame length 2/2");
// get the length of the frame, 2/2
if (m_rspState == RESP_LENGTH2) {
int ret = m_port->read(m_buffer + 2U, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
m_rspOffset = 2U;
}
if (ret == 0)
return RTM_TIMEOUT;
// get the length of the frame, 2/2
if (m_rspState == RESP_LENGTH2) {
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_LENGTH2, getting frame length 2/2, retries = %u", retries);
int ret = m_port->read(m_buffer + 2U, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
}
m_length = (m_length + (m_buffer[2U] & 0xFFU));
m_rspState = RESP_TYPE;
// received 0 bytes, which means no data is available, so we should just return and wait for the next time
if (ret == 0) {
if (retries >= MAX_GET_RESPONSE_RETRIES) {
LogError(LOG_MODEM, "RESP_LENGTH2, No data received from the modem after %u attempts", retries);
return RTM_TIMEOUT;
} else {
retries++;
Thread::sleep(10U);
continue;
}
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_LENGTH2, len = %u", m_length);
m_length = (m_length + (m_buffer[2U] & 0xFFU));
m_rspState = RESP_TYPE;
m_rspDoubleLength = true;
m_rspOffset = 3U;
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_LENGTH2, len = %u", m_length);
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "getting frame type");
// get the frame type
if (m_rspState == RESP_TYPE) {
int ret = m_port->read(m_buffer + m_rspOffset, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
m_rspDoubleLength = true;
m_rspOffset = 3U;
}
if (ret == 0)
return RTM_TIMEOUT;
m_rspType = (DVM_COMMANDS)m_buffer[m_rspOffset];
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_TYPE, len = %u, type = %u", m_length, m_rspType);
m_rspState = RESP_DATA;
m_rspOffset++;
}
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "getting frame data");
// get the frame data
if (m_rspState == RESP_DATA) {
if (m_respTrace)
LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_DATA, len = %u, offset = %u, type = %02X", m_length, m_rspOffset, m_rspType);
while (m_rspOffset < m_length) {
int ret = m_port->read(m_buffer + m_rspOffset, m_length - m_rspOffset);
// get the frame type
if (m_rspState == RESP_TYPE) {
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_TYPE, getting frame type");
int ret = m_port->read(m_buffer + m_rspOffset, 1U);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
@ -2527,12 +2523,41 @@ RESP_TYPE_DVM Modem::getResponse()
if (ret == 0)
return RTM_TIMEOUT;
if (ret > 0)
m_rspOffset += ret;
m_rspType = (DVM_COMMANDS)m_buffer[m_rspOffset];
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_TYPE, len = %u, type = %u", m_length, m_rspType);
m_rspState = RESP_DATA;
m_rspOffset++;
}
if (m_respTrace)
Utils::dump(1U, "Modem::getResponse(), Buffer", m_buffer, m_length);
// get the frame data
if (m_rspState == RESP_DATA) {
//LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_DATA, getting frame data");
if (m_respTrace)
LogDebugEx(LOG_MODEM, "Modem::getResponse()", "RESP_DATA, len = %u, offset = %u, type = %02X", m_length, m_rspOffset, m_rspType);
while (m_rspOffset < m_length) {
int ret = m_port->read(m_buffer + m_rspOffset, m_length - m_rspOffset);
if (ret < 0) {
LogError(LOG_MODEM, "Error reading from the modem, ret = %d", ret);
m_rspState = RESP_START;
return RTM_ERROR;
}
if (ret == 0)
return RTM_TIMEOUT;
if (ret > 0)
m_rspOffset += ret;
}
if (m_respTrace)
Utils::dump(1U, "Modem::getResponse(), Buffer", m_buffer, m_length);
}
// terminate loop
break;
}
m_rspState = RESP_START;

Loading…
Cancel
Save

Powered by TurnKey Linux.