const char * CellularSrcTokenErrorTable[] =
{ "ERROR", "BUSY", "NO CARRIER", "NO ANSWER", "NO DIALTONE", "ABORTED", "+CMS ERROR", "+CME ERROR", "SEND FAIL" };
const char * CellularUrcTokenWoPrefixTable[] =
{ "NORMAL POWER DOWN", "RDY", "NO CARRIER" };
When a final response like “NO CARRIER” is added to both tables above, if a “NO CARRIER” response is received for a sent AT command, this response will be processed as a URC.
To address this issue, if a command has been sent and a response is expected, the incoming response should first be searched and processed in the final response table.
As a solution, we can make a simple change as shown below.
static _atRespType_t _getMsgType( CellularContext_t * pContext,
const char * pLine,
const char * pRespPrefix )
{
_atRespType_t atRespType = AT_UNDEFINED;
CellularATError_t atStatus = CELLULAR_AT_SUCCESS;
bool inputWithPrefix = false;
bool inputWithSrcPrefix = false;
/* Lock the response mutex when deciding message type. */
PlatformMutex_Lock( &( pContext->PktRespMutex ) );
if (pContext->PktioAtCmdType != CELLULAR_AT_NO_COMMAND) /* && (WE CAN CHECK FINAL RESPONSE IS RECEIVED) */
{
atRespType = AT_SOLICITED;
}
else if( _checkUrcTokenWoPrefix( pContext, pLine ) == true )
{
atRespType = AT_UNSOLICITED;
}
else
{
/* Check if prefix exist in pLine. */
( void ) Cellular_ATIsPrefixPresent( pLine, &inputWithPrefix );
if( ( inputWithPrefix == true ) && ( pRespPrefix != NULL ) )
{
/* Check if this line contains prefix expected in AT command response. */
atStatus = Cellular_ATStrStartWith( pLine, pRespPrefix, &inputWithSrcPrefix );
}
}
if( ( atStatus == CELLULAR_AT_SUCCESS ) && ( atRespType == AT_UNDEFINED ) )
{
if( inputWithPrefix == true )
{
if( ( pContext->PktioAtCmdType != CELLULAR_AT_NO_COMMAND ) && ( inputWithSrcPrefix == true ) )
{
/* Celluar interface is sending AT command and this line contains
* expected prefix in the response. Return AT_SOLICITED here. */
atRespType = AT_SOLICITED;
}
else
{
/* Lines with prefix are considered AT_UNSOLICITED unless the prefix
* is expected in AT command response. */
atRespType = AT_UNSOLICITED;
}
}
else
{
if( pContext->PktioAtCmdType != CELLULAR_AT_NO_COMMAND )
{
/* Cellular interface is waiting for AT command response from
* cellular modem. The token without prefix can be success or error
* token to indicate the AT command status. Return AT_SOLICITED
* here and this line will be parsed in _Cellular_ProcessLine later. */
atRespType = AT_SOLICITED;
}
else
{
/* This line doesn't contain any prefix and cellular interface is
* not sending AT command. Therefore, this line is unexpected.
* Return AT_UNDEFINED here. */
atRespType = AT_UNDEFINED;
}
}
}
PlatformMutex_Unlock( &( pContext->PktRespMutex ) );
return atRespType;
}
So in your case, a URC and a response can both have the same prefix? If yes, is it guaranteed that the modem won’t send a URC if the host is waiting for a command response? If yes, then we can move the URC checking at the end -
static _atRespType_t _getMsgType( CellularContext_t * pContext,
const char * pLine,
const char * pRespPrefix )
{
_atRespType_t atRespType = AT_UNDEFINED;
CellularATError_t atStatus = CELLULAR_AT_SUCCESS;
bool inputWithPrefix = false;
bool inputWithSrcPrefix = false;
/* Lock the response mutex when deciding message type. */
PlatformMutex_Lock( &( pContext->PktRespMutex ) );
/* Check if prefix exist in pLine. */
( void ) Cellular_ATIsPrefixPresent( pLine, &inputWithPrefix );
if( ( inputWithPrefix == true ) && ( pRespPrefix != NULL ) )
{
/* Check if this line contains prefix expected in AT command response. */
atStatus = Cellular_ATStrStartWith( pLine, pRespPrefix, &inputWithSrcPrefix );
}
if( atStatus == CELLULAR_AT_SUCCESS )
{
if( inputWithPrefix == true )
{
if( ( pContext->PktioAtCmdType != CELLULAR_AT_NO_COMMAND ) && ( inputWithSrcPrefix == true ) )
{
/* Celluar interface is sending AT command and this line contains
* expected prefix in the response. Return AT_SOLICITED here. */
atRespType = AT_SOLICITED;
}
else
{
/* Lines with prefix are considered AT_UNSOLICITED unless the prefix
* is expected in AT command response. */
atRespType = AT_UNSOLICITED;
}
}
else
{
if( pContext->PktioAtCmdType != CELLULAR_AT_NO_COMMAND )
{
/* Cellular interface is waiting for AT command response from
* cellular modem. The token without prefix can be success or error
* token to indicate the AT command status. Return AT_SOLICITED
* here and this line will be parsed in _Cellular_ProcessLine later. */
atRespType = AT_SOLICITED;
}
else
{
/* This line doesn't contain any prefix and cellular interface is
* not sending AT command. Therefore, this line is unexpected.
* Return AT_UNDEFINED here. */
atRespType = AT_UNDEFINED;
}
}
}
if( ( atStatus == CELLULAR_AT_SUCCESS ) && ( atRespType == AT_UNDEFINED ) )
{
if( _checkUrcTokenWoPrefix( pContext, pLine ) == true )
{
atRespType = AT_UNSOLICITED;
}
}
PlatformMutex_Unlock( &( pContext->PktRespMutex ) );
return atRespType;
}
So in your case, a URC and a response can both have the same prefix?
Yes.
Is it guaranteed that the modem won’t send a URC if the host is waiting for a command response?
I think No. So my and ur solution will not give the right result.
Also, can your share the URC and Response syntax?
*When a call is initiated using the ATD command and it is successful, an OK response is received. If the call fails, a NO CARRIER response is returned.
*If the modem is connected to a call and the call is terminated for any reason (user, network, or the other party), a NO CARRIER message is sent as a URC.
In this case, what I want to understand is whether the received NO CARRIER response is a reply to the ATD command or a URC.
Because a URC can happen anytime, we need a way to differentiate if “NO CARRIER” is a URC or response to a command. You need to check with your modem vendor about how can we differentiate the two and then we can look into the best way to implement it.