Skip to content

Commit

Permalink
Adding _Cellular_RegisterUrcDataCallback in common layer
Browse files Browse the repository at this point in the history
* Adding _Cellular_RegisterUrcDataCallback to handle data stream in URC
  response
  • Loading branch information
chinglee-iot committed Apr 9, 2023
1 parent e5862bd commit 92ae20f
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 22 deletions.
8 changes: 4 additions & 4 deletions docs/doxygen/include/size_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<tr>
<td>cellular_common.c</td>
<td><center>1.7K</center></td>
<td><center>1.5K</center></td>
<td><center>1.6K</center></td>
</tr>
<tr>
<td>cellular_pkthandler.c</td>
Expand All @@ -39,12 +39,12 @@
</tr>
<tr>
<td>cellular_pktio.c</td>
<td><center>2.2K</center></td>
<td><center>2.0K</center></td>
<td><center>1.8K</center></td>
</tr>
<tr>
<td><b>Total estimates</b></td>
<td><b><center>14.8K</center></b></td>
<td><b><center>13.4K</center></b></td>
<td><b><center>15.0K</center></b></td>
<td><b><center>13.7K</center></b></td>
</tr>
</table>
3 changes: 3 additions & 0 deletions lexicon.txt
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,8 @@ ptokentable
ptr
puk
pundefinedrespcbcontext
purcdatacallbackcontext
purcdatalength
puserdata
pvportmalloc
pwr
Expand Down Expand Up @@ -859,6 +861,7 @@ unneccessary
upperthreshold
urat
urc
urcdatacallback
urcevent
urcprocesscgev
urcprocessciev
Expand Down
34 changes: 34 additions & 0 deletions source/cellular_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1137,3 +1137,37 @@ CellularError_t _Cellular_RegisterUndefinedRespCallback( CellularContext_t * pCo
}

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

CellularError_t _Cellular_RegisterUrcDataCallback( CellularContext_t * pContext,
CellularUrcDataCallback_t urcDataCallback,
void * pUrcDataCallbackContext )
{
CellularError_t cellularStatus = CELLULAR_SUCCESS;

if( pContext == NULL )
{
LogError( ( "_Cellular_RegisterUrcDataCallback: invalid context." ) );
cellularStatus = CELLULAR_INVALID_HANDLE;
}
else
{
/* urcDataCallback can be set to NULL to unregister the callback. */
PlatformMutex_Lock( &pContext->PktRespMutex );
pContext->urcDataCallback = urcDataCallback;

if( pContext->urcDataCallback != NULL )
{
pContext->pUrcDataCallbackContext = pUrcDataCallbackContext;
}
else
{
pContext->pUrcDataCallbackContext = NULL;
}

PlatformMutex_Unlock( &pContext->PktRespMutex );
}

return cellularStatus;
}

/*-----------------------------------------------------------*/
135 changes: 117 additions & 18 deletions source/cellular_pktio.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ static uint32_t _handleRxDataEvent( CellularContext_t * pContext,
CellularATCommandResponse_t ** ppAtResp );
static void _pktioReadThread( void * pUserData );
static void _PktioInitProcessReadThreadStatus( CellularContext_t * pContext );
static bool _getNextLine( CellularContext_t * pContext,
char ** ppLine,
uint32_t * pBytesRead,
uint32_t currentLineLength,
CellularPktStatus_t pktStatus );
static bool _preprocessUrcData( CellularContext_t * pContext,
char ** pLine,
uint32_t * pBytesRead );

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

Expand Down Expand Up @@ -640,28 +648,40 @@ static CellularPktStatus_t _handleData( char * pStartOfData,

if( bytesDataAndLeft >= pContext->dataLength )
{
/* Add data to the response linked list. */
_saveRawData( pStartOfData, pAtResp, pContext->dataLength );
/* There is no command waiting for response if pAtResp is NULL. The is the
* case that URC data is received from the buffer. */
if( pAtResp != NULL )
{
/* Add data to the response linked list. */
_saveRawData( pStartOfData, pAtResp, pContext->dataLength );

/* Advance pLine to a point after data. */
*ppLine = &pStartOfData[ pContext->dataLength ];
/* Advance pLine to a point after data. */
*ppLine = &pStartOfData[ pContext->dataLength ];

/* There are more bytes after the data. */
*pBytesLeft = ( bytesDataAndLeft - pContext->dataLength );
/* There are more bytes after the data. */
*pBytesLeft = ( bytesDataAndLeft - pContext->dataLength );

LogDebug( ( "_handleData : read buffer buffer %p start %p prefix %d left %d, read total %d",
pContext->pktioReadBuf,
pStartOfData,
bytesBeforeData,
*pBytesLeft,
bytesRead ) );
LogDebug( ( "_handleData : read buffer buffer %p start %p prefix %d left %d, read total %d",
pContext->pktioReadBuf,
pStartOfData,
bytesBeforeData,
*pBytesLeft,
bytesRead ) );

/* reset the data related variables. */
pContext->dataLength = 0U;
/* reset the data related variables. */
pContext->dataLength = 0U;

/* Set the pPktioReadPtr to indicate data already handled. */
pContext->pPktioReadPtr = *ppLine;
pContext->partialDataRcvdLen = *pBytesLeft;
/* Set the pPktioReadPtr to indicate data already handled. */
pContext->pPktioReadPtr = *ppLine;
pContext->partialDataRcvdLen = *pBytesLeft;
}
else
{
/* This the the URC data receive case. The data required by URC data callback
* is received. Leave the data mode by setting dataLength to 0. */
*pBytesLeft = bytesRead;
pContext->dataLength = 0U;
}
}
else
{
Expand Down Expand Up @@ -818,6 +838,79 @@ static bool _findLineInStream( CellularContext_t * pContext,

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

static bool _preprocessUrcData( CellularContext_t * pContext,
char ** pLine,
uint32_t * pBytesRead )
{
char * pTempLine = *pLine;
bool keepProcess = true;
uint32_t bufferLength = 0;
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;

if( pContext->urcDataCallback != NULL )
{
PlatformMutex_Lock( &pContext->PktRespMutex );
pktStatus = pContext->urcDataCallback( pContext->pUrcDataCallbackContext,
pTempLine,
*pBytesRead,
&bufferLength );
PlatformMutex_Unlock( &pContext->PktRespMutex );

if( pktStatus == CELLULAR_PKT_STATUS_PREFIX_MISMATCH )
{
/* This is not a URC data line. Return true to parse other data. */
keepProcess = true;
}
else if( pktStatus == CELLULAR_PKT_STATUS_SIZE_MISMATCH )
{
/* Partial URC data line is received. The prefix URC is waiting for more
* data to be received. */
pContext->pPktioReadPtr = pTempLine;
pContext->partialDataRcvdLen = *pBytesRead;
keepProcess = false;
}
else if( pktStatus != CELLULAR_PKT_STATUS_OK )
{
/* The Urc data callback function returns other error. This indicate that
* the token is corrupted and the reader buffer need to be dropped. */
LogError( ( "CellularUrcDataCallback returns error %d. Clean the read buffer.", pktStatus ) );

/* Clean the read buffer and read pointer. */
( void ) memset( pContext->pktioReadBuf, 0, PKTIO_READ_BUFFER_SIZE + 1U );
pContext->pPktioReadPtr = NULL;
pContext->partialDataRcvdLen = 0;
keepProcess = false;
}
else if( bufferLength > *pBytesRead )
{
/* The Urc data callback function returns incorrect buffer length. */
LogError( ( "CellularUrcDataCallback returns bufferLength %u. Modem returns length %u. Clean the read buffer.",
bufferLength, *pBytesRead ) );

/* Clean the read buffer and read pointer. */
( void ) memset( pContext->pktioReadBuf, 0, PKTIO_READ_BUFFER_SIZE + 1U );
pContext->pPktioReadPtr = NULL;
pContext->partialDataRcvdLen = 0;
keepProcess = false;
}
else
{
/* This is a complete URC data. The URC data is handled in the callback
* successfully. Move the read pointer forwared. */
pTempLine = &pTempLine[ bufferLength ];
*pLine = pTempLine;
pContext->pPktioReadPtr = *pLine;

/* Calculate remain bytes in the buffer. */
*pBytesRead = *pBytesRead - bufferLength;
}
}

return keepProcess;
}

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

static bool _preprocessLine( CellularContext_t * pContext,
char * pLine,
uint32_t * pBytesRead,
Expand Down Expand Up @@ -992,8 +1085,14 @@ static void _handleAllReceived( CellularContext_t * pContext,
bytesRead = bytesRead - 1U;
}

/* Preprocess Urc Data from the input buffer. */
keepProcess = _preprocessUrcData( pContext, &pTempLine, &bytesRead );

/* Preprocess line. */
keepProcess = _preprocessLine( pContext, pTempLine, &bytesRead, &pStartOfData );
if( keepProcess == true )
{
keepProcess = _preprocessLine( pContext, pTempLine, &bytesRead, &pStartOfData );
}

if( keepProcess == true )
{
Expand Down
37 changes: 37 additions & 0 deletions source/include/common/cellular_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,25 @@ typedef CellularPktStatus_t ( * CellularATCommandDataSendPrefixCallback_t ) ( vo
typedef CellularPktStatus_t ( * CellularUndefinedRespCallback_t )( void * pCallbackContext,
const char * pLine );

/**
* @ingroup cellular_common_datatypes_functionpointers
* @brief Callback used to process URC data buffer.
*
* @param[in] pUrcDataCallbackContext The pCallbackContext in _Cellular_TimeoutAtcmdDataRecvRequestWithCallback.
* @param[in] pBuffer The data buffer with modem response data.
* @param[in] bufferLength The length of the input buffer.
* @param[out] pUrcDataLength The length of the URC data in the buffer.
*
* @return CELLULAR_PKT_STATUS_OK if the operation is successful.
* CELLULAR_PKT_STATUS_SIZE_MISMATCH if more data is required.
* CELLULAR_PKT_STATUS_PREFIX_MISMATCH if this is not a URC data buffer
* Otherwise an error code indicating the cause of the error.
*/
typedef CellularPktStatus_t ( * CellularUrcDataCallback_t ) ( void * pUrcDataCallbackContext,
char * pBuffer,
uint32_t bufferLength,
uint32_t * pUrcDataLength );

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

/**
Expand Down Expand Up @@ -623,6 +642,24 @@ CellularError_t _Cellular_RegisterUndefinedRespCallback( CellularContext_t * pCo
CellularUndefinedRespCallback_t undefinedRespCallback,
void * pCallbackContext );

/**
* @brief Register URC data callback.
*
* Cellular module can register the callback function to handle URC data from input
* buffer.
*
* @param[in] pContext The opaque cellular context pointer created by Cellular_Init.
* @param[in] urcDataCallback The callback function to handle the URC data.
* @param[in] pUrcDataCallbackContext The pUrcDataCallbackContext passed to the urcDataCallback
* callback function if urcDataCallback is not NULL.
*
* @return CELLULAR_SUCCESS if the operation is successful, otherwise an error code
* indicating the cause of the error.
*/
CellularError_t _Cellular_RegisterUrcDataCallback( CellularContext_t * pContext,
CellularUrcDataCallback_t urcDataCallback,
void * pUrcDataCallbackContext );

/* *INDENT-OFF* */
#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions source/include/private/cellular_common_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ struct CellularContext
_atRespType_t recvdMsgType; /**< The received AT response type. */
CellularUndefinedRespCallback_t undefinedRespCallback; /**< Undefined response callback function. */
void * pUndefinedRespCBContext; /**< The pCallbackContext passed to CellularUndefinedRespCallback_t. */
CellularUrcDataCallback_t urcDataCallback; /**< URC data preprocess callback function. */
void * pUrcDataCallbackContext; /**< the callback context passed to urcDataCallback. */

/* PktIo data handling. */
uint32_t dataLength; /**< The data length in pLine. */
Expand Down

0 comments on commit 92ae20f

Please sign in to comment.