Hello everyone,
I think that there is a BUG in function tlp_get(), from tlp_if.c file. In this function, it is attemped to read a socket until there is no more data to read, which is ok. The issue we found is that there is no exit way from the do while loop even when urrecoverable errors occur.
/* read all you can get, return value checked for recoverable errors (Ticket #304) */
do
{
err = trdp_pdReceive(appHandle, appHandle->ifacePD[pElement->socketIdx].sock);
switch (err)
{
case TRDP_NO_ERR:
case TRDP_NOSUB_ERR: /* missing subscription should not lead to extensive error output */
case TRDP_NODATA_ERR:
case TRDP_BLOCK_ERR:
break;
case TRDP_PARAM_ERR:
vos_printLog(VOS_LOG_ERROR, "trdp_pdReceive() failed (Err: %d)\n", err);
break;
case TRDP_WIRE_ERR:
case TRDP_CRC_ERR:
case TRDP_MEM_ERR:
default:
vos_printLog(VOS_LOG_WARNING, "trdp_pdReceive() failed (Err: %d)\n", err);
break;
}
}
while ((err != TRDP_NODATA_ERR) && (err != TRDP_BLOCK_ERR)); /* as long as there are messages or a timeout is received */
In our case, trdp_pdReceive() call returned a TRDP_IO_ERR (urrecoverable error), so the main program is stuck in tlp_get() call. Our proposal is to take into account the list of error codes that should end the loop and propagate the error to the user:
/* Call the receive function if we are in non blocking mode */
if (!(appHandle->option & TRDP_OPTION_BLOCK))
{
TRDP_ERR_T err;
/* read all you can get, return value checked for recoverable errors (Ticket #304) */
do
{
err = trdp_pdReceive(appHandle, appHandle->ifacePD[pElement->socketIdx].sock);
switch (err)
{
case TRDP_NO_ERR:
case TRDP_NOSUB_ERR: /* missing subscription should not lead to extensive error output */
case TRDP_NODATA_ERR:
case TRDP_BLOCK_ERR:
break;
case TRDP_PARAM_ERR:
case TRDP_WIRE_ERR:
case TRDP_CRC_ERR:
case TRDP_MEM_ERR:
vos_printLog(VOS_LOG_WARNING, "trdp_pdReceive() failed (Err: %d)\n", err);
break;
default:
ret = err;
break;
}
}
while ((err != TRDP_NODATA_ERR) && (err != TRDP_BLOCK_ERR) && ret == TRDP_NO_ERR); /* as long as there are messages or a timeout is received */
}
if (ret == TRDP_NO_ERR)
{
/* Get the current time */
vos_getTime(&now);
/* Check time out */
if (timerisset(&pElement->interval) &&
timercmp(&pElement->timeToGo, &now, <))
{
...
...
...
A patch is provided, from trunk branch at is it today (20230217).
Another urrecoverable error is TRDP_PARAM_ERR, which now only prints the error message but does not end the loop. TRDP_PARAM_ERR is returned by trdp_pdReceive() function when the provided parameters are incorrect, but those parameters do not change between loops, so if wrong parameter is provided, the loop will become an infinite loop also. However, my patch does not change this, since I prefer to report and let in admins hand the decission.
Hola Adrian, thanks for sharing Your findings. I have included TRDP_PARAM_ERR in the fix even the only possibility is that somebody passes an invalid socket.