There are two problems related to this issue:
If receiving a MD reply in the same cycle as the timeout occurs, the stack informs the user (callback) a second time with TRDP_UNKNOWN_ERR.
If one o the MD requests has not been replied within configured timeout time (timeout event), the stack may inform the user (callback) with TRDP_UNKNOWN_ERR for other MD requests.
Approach
If receiving an MD reply, the stack shall not inform the user a second time.
Timeout event of MD request shall not have side effects on other MD requests.
Current implementation (trdp_mdCheckTimeouts in trdp_mdcom.c):
do
{
TRDP_ERR_T resultCode = TRDP_UNKNOWN_ERR;
/* Update the current time always inside loop in case of application delays */
vos_getTime(&now);
/* Switch to receive queue */
if (NULL == iterMD && TRUE == firstLoop)
{
iterMD = appHandle->pMDRcvQueue;
firstLoop = FALSE;
}
/* Are we finished? */
if (NULL == iterMD)
{
break;
}
/* timeToGo is timeout value! */
if (((iterMD->interval.tv_sec != TRDP_MD_INFINITE_TIME) ||
(iterMD->interval.tv_usec != TRDP_MD_INFINITE_USEC_TIME)) &&
(0 > vos_cmpTime(&iterMD->timeToGo, &now))) /* timeout overflow */
{
timeOut = trdp_mdTimeOutStateHandler( iterMD, appHandle, &resultCode);
}
if (TRUE == timeOut) /* Notify user */
{
/* Execute callback */
if (iterMD->pfCbFunction != NULL)
{
trdp_mdInvokeCallback(iterMD, appHandle, resultCode);
}
}
iterMD = iterMD->pNext;
}
while (TRUE); /*lint !e506 */
Suggested fix (trdp_mdCheckTimeouts in trdp_mdcom.c):
do
{
TRDP_ERR_T resultCode = TRDP_UNKNOWN_ERR;
timeOut = FALSE; /* TRDP-104: Make shure that timeouts of MD request do not affect other MD requests */
/* Update the current time always inside loop in case of application delays */
vos_getTime(&now);
/* Switch to receive queue */
if (NULL == iterMD && TRUE == firstLoop)
{
iterMD = appHandle->pMDRcvQueue;
firstLoop = FALSE;
}
/* Are we finished? */
if (NULL == iterMD)
{
break;
}
/* FIX: Do not inform user if MD request is about to die */
if (iterMD->morituri != TRUE)
{
/* timeToGo is timeout value! */
if (((iterMD->interval.tv_sec != TRDP_MD_INFINITE_TIME) ||
(iterMD->interval.tv_usec != TRDP_MD_INFINITE_USEC_TIME)) &&
(0 > vos_cmpTime(&iterMD->timeToGo, &now))) /* timeout overflow */
{
timeOut = trdp_mdTimeOutStateHandler( iterMD, appHandle, &resultCode);
}
if (TRUE == timeOut) /* Notify user */
{
/* Execute callback */
if (iterMD->pfCbFunction != NULL)
{
trdp_mdInvokeCallback(iterMD, appHandle, resultCode);
}
}
}
iterMD = iterMD->pNext;
}
while (TRUE); /*lint !e506 */
Fixed with revision: 2348