Skip to content

Commit

Permalink
Update _getMsgType for URC without prefix
Browse files Browse the repository at this point in the history
* Update the logic for port not using URC without prefix table
* Check AT command type for response without prefix
  • Loading branch information
chinglee-iot committed Nov 21, 2023
1 parent b9679f3 commit e69b0fa
Show file tree
Hide file tree
Showing 2 changed files with 257 additions and 21 deletions.
55 changes: 34 additions & 21 deletions source/cellular_pktio.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ static CellularPktStatus_t _Cellular_ProcessLine( CellularContext_t * pContext,
CellularATCommandResponse_t * pResp,
CellularATCommandType_t atType,
const char * pRespPrefix );
static bool urcTokenWoPrefix( const CellularContext_t * pContext,
const char * pLine );
static bool _checkUrcTokenWoPrefix( const CellularContext_t * pContext,
const char * pLine );
static _atRespType_t _getMsgType( CellularContext_t * pContext,
const char * pLine,
const char * pRespPrefix );
Expand Down Expand Up @@ -409,20 +409,27 @@ static CellularPktStatus_t _Cellular_ProcessLine( CellularContext_t * pContext,

/*-----------------------------------------------------------*/

static bool urcTokenWoPrefix( const CellularContext_t * pContext,
const char * pLine )
static bool _checkUrcTokenWoPrefix( const CellularContext_t * pContext,
const char * pLine )
{
bool ret = false;
uint32_t i = 0;
uint32_t urcTokenTableSize = pContext->tokenTable.cellularUrcTokenWoPrefixTableSize;
const char * const * const pUrcTokenTable = pContext->tokenTable.pCellularUrcTokenWoPrefixTable;

for( i = 0; i < urcTokenTableSize; i++ )
if( ( pUrcTokenTable == NULL ) || ( urcTokenTableSize == 0 ) )
{
if( strcmp( pLine, pUrcTokenTable[ i ] ) == 0 )
ret = false;
}
else
{
for( i = 0; i < urcTokenTableSize; i++ )
{
ret = true;
break;
if( strcmp( pLine, pUrcTokenTable[ i ] ) == 0 )
{
ret = true;
break;
}
}
}

Expand All @@ -443,12 +450,7 @@ static _atRespType_t _getMsgType( CellularContext_t * pContext,
/* Lock the response mutex when deciding message type. */
PlatformMutex_Lock( &pContext->PktRespMutex );

if( pContext->tokenTable.pCellularUrcTokenWoPrefixTable == NULL )
{
atStatus = CELLULAR_AT_ERROR;
atRespType = AT_UNDEFINED;
}
else if( urcTokenWoPrefix( pContext, pLine ) == true )
if( _checkUrcTokenWoPrefix( pContext, pLine ) == true )
{
atRespType = AT_UNSOLICITED;
}
Expand All @@ -459,7 +461,7 @@ static _atRespType_t _getMsgType( CellularContext_t * pContext,

if( ( inputWithPrefix == true ) && ( pRespPrefix != NULL ) )
{
/* Check if SRC prefix exist in pLine. */
/* Check if this line contains prefix expected in AT command response. */
atStatus = Cellular_ATStrStartWith( pLine, pRespPrefix, &inputWithSrcPrefix );
}
}
Expand All @@ -470,23 +472,34 @@ static _atRespType_t _getMsgType( CellularContext_t * pContext,
{
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_SOLICTIED 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 ) && ( pRespPrefix == NULL ) ) ||
( pContext->PktioAtCmdType == CELLULAR_AT_MULTI_DATA_WO_PREFIX ) ||
( pContext->PktioAtCmdType == CELLULAR_AT_WITH_PREFIX ) ||
( pContext->PktioAtCmdType == CELLULAR_AT_MULTI_WITH_PREFIX ) ||
( pContext->PktioAtCmdType == CELLULAR_AT_WITH_PREFIX_NO_RESULT_CODE ) )
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;
}
}
}

Expand Down Expand Up @@ -1372,7 +1385,7 @@ CellularPktStatus_t _Cellular_PktioSendAtCmd( CellularContext_t * pContext,
{
PlatformMutex_Lock( &pContext->PktRespMutex );

if( pAtRspPrefix != NULL )
if( ( pAtRspPrefix != NULL ) && ( atType != CELLULAR_AT_WO_PREFIX ) && ( atType != CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE ) )
{
( void ) strncpy( pContext->pktRespPrefixBuf, pAtRspPrefix, CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH );
pContext->pRespPrefix = pContext->pktRespPrefixBuf;
Expand Down
223 changes: 223 additions & 0 deletions test/unit-test/cellular_pktio_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -2127,6 +2127,62 @@ void test__Cellular_PktioInit_Thread_Rx_Data_Event_CELLULAR_AT_WITH_PREFIX_STRIN
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
}

/**
* @brief _Cellular_PktioInit - Sending CELLULAR_AT_WITH_PREFIX with empty response prefix.
*
* Empty response prefix will be considered invalid string. Verify AT_UNDEFINED type
* is returnedy in _getMsgType function.
*
* <b>Coverage</b>
* @code{c}
* else
* {
* {
* atStatus = Cellular_ATStrStartWith( pLine, pRespPrefix, &inputWithSrcPrefix );
* }
* }
*
* if( ( atStatus == CELLULAR_AT_SUCCESS ) && ( atRespType == AT_UNDEFINED ) )
* {
* ...
* }
* @endcode
* ( atStatus == CELLULAR_AT_SUCCESS ) is false.
* ( atRespType == AT_UNDEFINED ) is true.
*/
void test__Cellular_PktioInit_Thread_Rx_Data_Event_CELLULAR_AT_WITH_PREFIX_empty_prefix( void )
{
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
CellularContext_t context;
CellularCommInterface_t * pCommIntf = &CellularCommInterface;

threadReturn = true;
memset( &context, 0, sizeof( CellularContext_t ) );

/* Assign the comm interface to pContext. */
context.pCommIntf = pCommIntf;
context.pPktioShutdownCB = _shutdownCallback;

/* Test the rx_data event with CELLULAR_AT_WITH_PREFIX resp. */
pktioEvtMask = PKTIO_EVT_MASK_RX_DATA;
recvCount = 4;
atCmdType = CELLULAR_AT_WITH_PREFIX;
/* copy the token table. */
( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) );
context.pktDataPrefixCB = NULL;
context.pRespPrefix = ""; /* Use empty string to cover Cellular_ATStrStartWith failed case. */

/* API call. */
pktStatus = _Cellular_PktioInit( &context, PktioHandlePacketCallback_t );

/* Validation. */
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
/* This command returns an AT_UNDEFINED type, which is unhandled in the test
* test case. Ensure the context is cleaned. */
TEST_ASSERT_EQUAL( CELLULAR_AT_NO_COMMAND, context.PktioAtCmdType );
TEST_ASSERT_EQUAL( NULL, context.pRespPrefix );
}

/**
* @brief Test thread receiving rx data event with CELLULAR_AT_WITH_PREFIX_STRING resp for _Cellular_PktioInit to return CELLULAR_PKT_STATUS_OK.
*/
Expand Down Expand Up @@ -2548,6 +2604,63 @@ void test__Cellular_PktioInit_Thread_Rx_Data_Event_URC_TOKEN_STRING_RESP( void )
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
}

/**
* @brief _Cellular_PktioInit - urcTokenTableSize is set to 0 in _checkUrcTokenWoPrefix.
*
* Cover urcTokenTableSize is set to 0 in _checkUrcTokenWoPrefix. This function
* should return false. Verify AT_UNDEFINED type is returned With input string "TEST1"
* and the context is cleaned for unhandled AT_UNDEFINED type input.
*
* <b>Coverage</b>
* @code{c}
* static bool _checkUrcTokenWoPrefix( const CellularContext_t * pContext,
* const char * pLine )
* {
* ...
* if( ( pUrcTokenTable == NULL ) || ( urcTokenTableSize == 0 ) )
* {
* ret = false;
* }
* ...
* }
* @endcode
* ( pUrcTokenTable == NULL ) is false.
* ( urcTokenTableSize == 0 ) is true.
*/
void test__Cellular_PktioInit_Thread_Rx_Data_Event_URC_WO_PREFIX_zero_table_size( void )
{
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
CellularContext_t context;
CellularCommInterface_t * pCommIntf = &CellularCommInterface;

threadReturn = true;
memset( &context, 0, sizeof( CellularContext_t ) );

/* Assign the comm interface to pContext. */
context.pCommIntf = pCommIntf;
context.pPktioShutdownCB = _shutdownCallback;

/* Test the rx_data event with CELLULAR_AT_NO_COMMAND resp. */
pktioEvtMask = PKTIO_EVT_MASK_RX_DATA;
recvCount = 2;
atCmdType = CELLULAR_AT_NO_COMMAND;

/* copy the token table. */
( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) );
/* Set the URC without prefix table size to 0 for testing here. */
context.tokenTable.cellularUrcTokenWoPrefixTableSize = 0;

/* API call. */
pktStatus = _Cellular_PktioInit( &context, PktioHandlePacketCallback_t );

/* Validation. */
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
/* This command returns an AT_UNDEFINED type, which is unhandled in the test
* test case. Ensure the context is cleaned. */
TEST_ASSERT_EQUAL( CELLULAR_AT_NO_COMMAND, context.PktioAtCmdType );
TEST_ASSERT_EQUAL( NULL, context.pRespPrefix );
}

/**
* @brief Test RX data event _handle_data function.
*
Expand Down Expand Up @@ -2813,10 +2926,16 @@ void test__Cellular_PktioSendAtCmd_Happy_Path( void )
memset( &context, 0, sizeof( CellularContext_t ) );
context.pCommIntf = pCommIntf;
context.hPktioCommIntf = ( CellularCommInterfaceHandle_t ) &commInterfaceHandle;

/* API call. */
pktStatus = _Cellular_PktioSendAtCmd( &context, atReqSetRatPriority.pAtCmd,
atReqSetRatPriority.atCmdType,
atReqSetRatPriority.pAtRspPrefix );

/* Validation. */
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
/* The context.PrespPrefix should be set to pktRespPrefixBuf. */
TEST_ASSERT_EQUAL( &context.pktRespPrefixBuf, context.pRespPrefix );
}

/**
Expand Down Expand Up @@ -2847,6 +2966,110 @@ void test__Cellular_PktioSendAtCmd_Happy_Path_No_Prefix( void )
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
}

/**
* @brief _Cellular_PktioSendAtCmd - Sending CELLULAR_AT_WO_PREFIX with prefix.
*
* Prefix won't be parsed for CELLULAR_AT_WO_PREFIX type command. pRespPrefix should
* be set NULL.
*
* <b>Coverage</b>
* @code{c}
* if( ( pAtRspPrefix != NULL ) && ( atType != CELLULAR_AT_WO_PREFIX ) && ( atType != CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE ) )
* {
* ( void ) strncpy( pContext->pktRespPrefixBuf, pAtRspPrefix, CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH );
* pContext->pRespPrefix = pContext->pktRespPrefixBuf;
* }
* else
* {
* pContext->pRespPrefix = NULL;
* }
* @endcode
* ( pAtRspPrefix != NULL ) is true.
* ( atType != CELLULAR_AT_WO_PREFIX ) is false.
*/
void test__Cellular_PktioSendAtCmd_CELLULAR_AT_WO_PREFIX_with_prefix( void )
{
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
CellularContext_t context;
CellularCommInterface_t * pCommIntf = &CellularCommInterface;
struct _cellularCommContext commInterfaceHandle = { 0 };
CellularAtReq_t atReqSetRatPriority =
{
"ATE0",
CELLULAR_AT_WO_PREFIX,
"+QCFG",
NULL,
NULL,
0,
};

/* Setup variable. */
memset( &context, 0, sizeof( CellularContext_t ) );
context.pCommIntf = pCommIntf;
context.hPktioCommIntf = ( CellularCommInterfaceHandle_t ) &commInterfaceHandle;

/* API call. */
pktStatus = _Cellular_PktioSendAtCmd( &context, atReqSetRatPriority.pAtCmd,
atReqSetRatPriority.atCmdType,
atReqSetRatPriority.pAtRspPrefix );

/* Validation. */
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
TEST_ASSERT_EQUAL( NULL, context.pRespPrefix ); /* The context.PrespPrefix should be set NULL. */
}

/**
* @brief _Cellular_PktioSendAtCmd - Sending CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE with prefix.
*
* Prefix won't be parsed for CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE type command.
* pRespPrefix should be set NULL.
*
* <b>Coverage</b>
* @code{c}
* if( ( pAtRspPrefix != NULL ) && ( atType != CELLULAR_AT_WO_PREFIX ) && ( atType != CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE ) )
* {
* ( void ) strncpy( pContext->pktRespPrefixBuf, pAtRspPrefix, CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH );
* pContext->pRespPrefix = pContext->pktRespPrefixBuf;
* }
* else
* {
* pContext->pRespPrefix = NULL;
* }
* @endcode
* ( pAtRspPrefix != NULL ) is true.
* ( atType != CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE ) is false.
*/
void test__Cellular_PktioSendAtCmd_CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE_with_prefix( void )
{
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
CellularContext_t context;
CellularCommInterface_t * pCommIntf = &CellularCommInterface;
struct _cellularCommContext commInterfaceHandle = { 0 };
CellularAtReq_t atReqSetRatPriority =
{
"ATE0",
CELLULAR_AT_WO_PREFIX_NO_RESULT_CODE,
"+QCFG",
NULL,
NULL,
0,
};

/* Setup variable. */
memset( &context, 0, sizeof( CellularContext_t ) );
context.pCommIntf = pCommIntf;
context.hPktioCommIntf = ( CellularCommInterfaceHandle_t ) &commInterfaceHandle;

/* API call. */
pktStatus = _Cellular_PktioSendAtCmd( &context, atReqSetRatPriority.pAtCmd,
atReqSetRatPriority.atCmdType,
atReqSetRatPriority.pAtRspPrefix );

/* Validation. */
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
TEST_ASSERT_EQUAL( NULL, context.pRespPrefix ); /* The context.PrespPrefix should be set NULL. */
}

/**
* @brief Test that any NULL parameter for _Cellular_PktioSendData.
*/
Expand Down

0 comments on commit e69b0fa

Please sign in to comment.