101101#define DATA_PREFIX_STRING_LENGTH ( 6U )
102102#define DATA_PREFIX_STRING_CHANGELINE_LENGTH ( 2U ) /* The length of the change line "\r\n". */
103103
104- #define MAX_QIRD_STRING_PREFIX_STRING ( 14U ) /* The max data prefix string is "+QIRD: 1460\r\n" */
104+ #define MAX_QIRD_PREFIX_STRING_LENGTH ( 14U ) /* The max data prefix string is "+QIRD: 1460\r\n" */
105105
106106/*-----------------------------------------------------------*/
107107
110110 */
111111typedef struct _socketDataRecv
112112{
113- uint32_t * pDataLen ;
113+ uint32_t * pReceivedDataLength ;
114114 uint8_t * pData ;
115- CellularSocketAddress_t * pRemoteSocketAddress ;
115+ uint32_t dataLength ;
116116} _socketDataRecv_t ;
117117
118118/**
@@ -1314,16 +1314,16 @@ static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pA
13141314 uint32_t dataLenToCopy = 0 ;
13151315
13161316 /* Check if the received data size is greater than the output buffer size. */
1317- if ( * pDataRecv -> pDataLen > outBufSize )
1317+ if ( * pDataRecv -> pReceivedDataLength > outBufSize )
13181318 {
13191319 LogError ( ( "Data is turncated, received data length %d, out buffer size %d" ,
1320- * pDataRecv -> pDataLen , outBufSize ) );
1320+ * pDataRecv -> pReceivedDataLength , outBufSize ) );
13211321 dataLenToCopy = outBufSize ;
1322- * pDataRecv -> pDataLen = outBufSize ;
1322+ * pDataRecv -> pReceivedDataLength = outBufSize ;
13231323 }
13241324 else
13251325 {
1326- dataLenToCopy = * pDataRecv -> pDataLen ;
1326+ dataLenToCopy = * pDataRecv -> pReceivedDataLength ;
13271327 }
13281328
13291329 /* Data is stored in the next intermediate response. */
@@ -1342,7 +1342,7 @@ static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pA
13421342 atCoreStatus = CELLULAR_AT_BAD_PARAMETER ;
13431343 }
13441344 }
1345- else if ( * pDataRecv -> pDataLen == 0U )
1345+ else if ( * pDataRecv -> pReceivedDataLength == 0U )
13461346 {
13471347 /* Receive command success but no data. */
13481348 LogDebug ( ( "Receive Data: no data" ) );
@@ -1381,11 +1381,16 @@ static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext,
13811381 LogError ( ( "Receive Data: response is invalid" ) );
13821382 pktStatus = CELLULAR_PKT_STATUS_FAILURE ;
13831383 }
1384- else if ( ( pDataRecv == NULL ) || ( pDataRecv -> pData == NULL ) || ( pDataRecv -> pDataLen == NULL ) )
1384+ else if ( ( pDataRecv == NULL ) || ( pDataRecv -> pData == NULL ) || ( pDataRecv -> pReceivedDataLength == NULL ) )
13851385 {
13861386 LogError ( ( "Receive Data: Bad param" ) );
13871387 pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM ;
13881388 }
1389+ else if ( dataLen != sizeof ( _socketDataRecv_t ) )
1390+ {
1391+ LogError ( ( "Receive Data: Bad data length. Data length should be the size of _socketDataRecv_t." ) );
1392+ pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM ;
1393+ }
13891394 else
13901395 {
13911396 pInputLine = pAtResp -> pItm -> pLine ;
@@ -1405,7 +1410,7 @@ static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext,
14051410 {
14061411 if ( ( tempValue >= ( int32_t ) 0 ) && ( tempValue < ( ( int32_t ) CELLULAR_MAX_RECV_DATA_LEN + 1 ) ) )
14071412 {
1408- * pDataRecv -> pDataLen = ( uint32_t ) tempValue ;
1413+ * pDataRecv -> pReceivedDataLength = ( uint32_t ) tempValue ;
14091414 }
14101415 else
14111416 {
@@ -1418,7 +1423,7 @@ static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext,
14181423 /* Process the data buffer. */
14191424 if ( atCoreStatus == CELLULAR_AT_SUCCESS )
14201425 {
1421- atCoreStatus = getDataFromResp ( pAtResp , pDataRecv , dataLen );
1426+ atCoreStatus = getDataFromResp ( pAtResp , pDataRecv , pDataRecv -> dataLength );
14221427 }
14231428
14241429 pktStatus = _Cellular_TranslateAtCoreStatus ( atCoreStatus );
@@ -1773,6 +1778,21 @@ static CellularPktStatus_t _Cellular_RecvFuncGetPsmSettings( CellularContext_t *
17731778
17741779/*-----------------------------------------------------------*/
17751780
1781+ /* This function returns the start of the data stream in ppDataStart and length in
1782+ * pDataLength. ppDataStart should indicate the memory address within pLine[ 0 ] ~ pLine[ lineLength ]
1783+ *
1784+ * Example BG96 QIRD AT command response:
1785+ * => AT+QIRD=0,15000\r\n
1786+ * <= +QIRD: 5\r\n
1787+ * <= test1\r\n
1788+ * <= OK\r\n
1789+ *
1790+ * pLine points to "+QIRD: 5\r\ntest1\r\n". ppDataStart should points to &pline[ 10 ]
1791+ * ,which stores the start of "test1". Length 5 should be returned in pDataLength.
1792+ *
1793+ * pLine may point to an incomplete line and a line with mismatched prefix. This
1794+ * callback function returns different packet status code accordingly.
1795+ */
17761796static CellularPktStatus_t socketRecvDataPrefix ( void * pCallbackContext ,
17771797 char * pLine ,
17781798 uint32_t lineLength ,
@@ -1781,15 +1801,26 @@ static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext,
17811801{
17821802 char * pDataStart = NULL ;
17831803 uint32_t prefixLineLength = 0U ;
1784- int32_t tempValue = 0 ;
1804+ int32_t receivedDataLength = 0 ;
17851805 CellularATError_t atResult = CELLULAR_AT_SUCCESS ;
1786- CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK ;
1806+ CellularPktStatus_t pktStatus ;
17871807 uint32_t i = 0 ;
1788- char pLocalLine [ MAX_QIRD_STRING_PREFIX_STRING + 1 ] = "\0" ;
1789- uint32_t localLineLength = MAX_QIRD_STRING_PREFIX_STRING > lineLength ? lineLength : MAX_QIRD_STRING_PREFIX_STRING ;
1808+ char pLocalLine [ MAX_QIRD_PREFIX_STRING_LENGTH + 1 ] = "\0" ;
1809+ uint32_t localLineLength = 0 ;
17901810
1811+ /* Callback context is not used in this function. */
17911812 ( void ) pCallbackContext ;
17921813
1814+ /* localLineLength keeps the maximum string length to compare. */
1815+ if ( MAX_QIRD_PREFIX_STRING_LENGTH > lineLength )
1816+ {
1817+ localLineLength = lineLength ;
1818+ }
1819+ else
1820+ {
1821+ localLineLength = MAX_QIRD_PREFIX_STRING_LENGTH ;
1822+ }
1823+
17931824 if ( ( pLine == NULL ) || ( ppDataStart == NULL ) || ( pDataLength == NULL ) )
17941825 {
17951826 pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM ;
@@ -1799,8 +1830,10 @@ static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext,
17991830 /* Check if the message is a data response. */
18001831 if ( strncmp ( pLine , DATA_PREFIX_STRING , DATA_PREFIX_STRING_LENGTH ) == 0 )
18011832 {
1802- strncpy ( pLocalLine , pLine , MAX_QIRD_STRING_PREFIX_STRING );
1803- pLocalLine [ MAX_QIRD_STRING_PREFIX_STRING ] = '\0' ;
1833+ /* In order not to change the input buffer pLine, copy the maximum QIRD
1834+ * prefix string to the local buffer. */
1835+ strncpy ( pLocalLine , pLine , MAX_QIRD_PREFIX_STRING_LENGTH );
1836+ pLocalLine [ MAX_QIRD_PREFIX_STRING_LENGTH ] = '\0' ;
18041837 pDataStart = pLocalLine ;
18051838
18061839 /* Add a '\0' char at the end of the line. */
@@ -1814,46 +1847,71 @@ static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext,
18141847 }
18151848 }
18161849
1850+ /* BG96 expects a complete line to be received then the data stream. The
1851+ * input buffer doesn't contain a complete line. */
18171852 if ( i == localLineLength )
18181853 {
1819- LogDebug ( ( "Data prefix invalid line : %s" , pLocalLine ) );
1820- pDataStart = NULL ;
1821- }
1822- }
1823-
1824- if ( pDataStart != NULL )
1825- {
1826- atResult = Cellular_ATStrtoi ( & pDataStart [ DATA_PREFIX_STRING_LENGTH ], 10 , & tempValue );
1827-
1828- if ( ( atResult == CELLULAR_AT_SUCCESS ) && ( tempValue >= 0 ) &&
1829- ( tempValue <= ( int32_t ) CELLULAR_MAX_RECV_DATA_LEN ) )
1830- {
1831- if ( ( prefixLineLength + DATA_PREFIX_STRING_CHANGELINE_LENGTH ) > lineLength )
1854+ if ( localLineLength == MAX_QIRD_PREFIX_STRING_LENGTH )
18321855 {
1833- /* More data is required. */
1834- * pDataLength = 0 ;
1835- pDataStart = NULL ;
1836- pktStatus = CELLULAR_PKT_STATUS_SIZE_MISMATCH ;
1856+ /* A complete line is not found within MAX_QIRD_PREFIX_STRING_LENGTH.
1857+ * Returns prefix mismatch here. Pktio can continue to parse
1858+ * the string. */
1859+ LogDebug ( ( "Data prefix matched incomplete line : %s" , pLocalLine ) );
1860+ pktStatus = CELLULAR_PKT_STATUS_PREFIX_MISMATCH ;
18371861 }
18381862 else
18391863 {
1840- pDataStart = & pLine [ prefixLineLength ];
1841- pDataStart [ 0 ] = '\0' ;
1842- pDataStart = & pDataStart [ DATA_PREFIX_STRING_CHANGELINE_LENGTH ];
1843- * pDataLength = ( uint32_t ) tempValue ;
1864+ /* A complete line is not found. The line doesn't contains enough
1865+ * bytes for the prefix string. Pktio will call this callback
1866+ * again with more data. */
1867+ LogDebug ( ( "Data prefix incomplete line : %s" , pLocalLine ) );
1868+ pktStatus = CELLULAR_PKT_STATUS_SIZE_MISMATCH ;
18441869 }
1870+ }
1871+ else if ( ( prefixLineLength + DATA_PREFIX_STRING_CHANGELINE_LENGTH ) > lineLength )
1872+ {
1873+ /* The complete changeline "\r\n" is not received. Returns size mismatch
1874+ * to pktio. Pktio will call this callback again with more data. */
1875+ LogDebug ( ( "Data prefix incomplete line : %s" , pLocalLine ) );
1876+ pktStatus = CELLULAR_PKT_STATUS_SIZE_MISMATCH ;
1877+ }
1878+ else
1879+ {
1880+ /* The input steam contains valid prefix and the line is ended with
1881+ * "\r\n". Continue to parse the received data length. */
1882+ pktStatus = CELLULAR_PKT_STATUS_OK ;
1883+ }
1884+ }
1885+ else
1886+ {
1887+ /* The prefix is not expected "+QIRD:". This is probably a URC response.
1888+ * returns CELLULAR_PKT_STATUS_PREFIX_MISMATCH to pktio. Pktio can continue
1889+ * to parse the string. */
1890+ pktStatus = CELLULAR_PKT_STATUS_PREFIX_MISMATCH ;
1891+ }
18451892
1893+ /* This line contains a valid response prefix and a complete line. Continue
1894+ * to parse the <read_actual_length> field in this line. */
1895+ if ( pktStatus == CELLULAR_PKT_STATUS_OK )
1896+ {
1897+ atResult = Cellular_ATStrtoi ( & pDataStart [ DATA_PREFIX_STRING_LENGTH ], 10 , & receivedDataLength );
1898+
1899+ if ( ( atResult == CELLULAR_AT_SUCCESS ) &&
1900+ ( receivedDataLength >= 0 ) &&
1901+ ( receivedDataLength <= ( int32_t ) CELLULAR_MAX_RECV_DATA_LEN ) )
1902+ {
1903+ /* The input stream contains valid line. prefixLineLength + DATA_PREFIX_STRING_CHANGELINE_LENGTH
1904+ * is the offset to the start of the data stream. */
1905+ * pDataLength = ( uint32_t ) receivedDataLength ;
1906+ * ppDataStart = & pLine [ prefixLineLength + DATA_PREFIX_STRING_CHANGELINE_LENGTH ];
18461907 LogDebug ( ( "DataLength %p at pktIo = %d" , pDataStart , * pDataLength ) );
18471908 }
18481909 else
18491910 {
1850- * pDataLength = 0 ;
1851- pDataStart = NULL ;
1852- LogError ( ( "Data response received with wrong size" ) );
1911+ LogError ( ( "Data response received with wrong size %s." , & pDataStart [ DATA_PREFIX_STRING_LENGTH ] ) );
1912+ pktStatus = CELLULAR_PKT_STATUS_FAILURE ;
18531913 }
18541914 }
1855-
1856- * ppDataStart = pDataStart ;
18571915 }
18581916
18591917 return pktStatus ;
@@ -2599,18 +2657,18 @@ CellularError_t Cellular_SocketRecv( CellularHandle_t cellularHandle,
25992657 uint32_t recvLen = bufferLength ;
26002658 _socketDataRecv_t dataRecv =
26012659 {
2602- pReceivedDataLength ,
2603- pBuffer ,
2604- NULL
2660+ . pReceivedDataLength = pReceivedDataLength ,
2661+ . pData = pBuffer ,
2662+ . dataLength = bufferLength
26052663 };
26062664 CellularAtReq_t atReqSocketRecv =
26072665 {
2608- cmdBuf ,
2609- CELLULAR_AT_MULTI_DATA_WO_PREFIX ,
2610- "+QIRD" ,
2611- _Cellular_RecvFuncData ,
2612- ( void * ) & dataRecv ,
2613- bufferLength ,
2666+ . pAtCmd = cmdBuf ,
2667+ . atCmdType = CELLULAR_AT_MULTI_DATA_WO_PREFIX ,
2668+ . pAtRspPrefix = "+QIRD" ,
2669+ . respCallback = _Cellular_RecvFuncData ,
2670+ . pData = ( void * ) & dataRecv ,
2671+ . dataLen = sizeof ( dataRecv )
26142672 };
26152673
26162674 cellularStatus = _Cellular_CheckLibraryStatus ( pContext );
0 commit comments