Skip to content

Commit 936d4f7

Browse files
authored
Add CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR config (#117)
* Update cellular library to MIT license * Add CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR to support different modem * Differnt modem may use different leading char for prefix string. Add config CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR to support. * Use Cellular_ATIsPrefixPresent to check URC with prefix in pkthandler * Fix CI failures * Fix lecicon * Add test case to coverage URC string only with leading char * Fix lexicon * Fix lexicon space * Update comments * include CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR in CELLULAR_CHECK_IS_PREFIX_CHAR * Fix bug
1 parent 92702e5 commit 936d4f7

File tree

7 files changed

+189
-18
lines changed

7 files changed

+189
-18
lines changed

docs/doxygen/portingCellularModule.dox

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,10 @@ They can be used to reduce porting effort. <br>
167167
@page cellular_module_urc_handler cellular_module_urc_handler
168168
@brief Implement URC handler to handle URC event and call the corresponding callback function. <br>
169169
- @ref CellularTokenTable_t.pCellularUrcHandlerTable : URC handler table of @ref CellularAtParseTokenHandler_t
170-
- @ref CellularTokenTable_t.cellularPrefixToParserMapSize
171-
Example URC handler table.
170+
- @ref CellularTokenTable_t.cellularPrefixToParserMapSize : The size of the URC handler table
171+
<br>
172+
173+
<b>Example URC handler table</b>:
172174
```
173175
CellularAtParseTokenMap_t CellularUrcHandlerTable[] =
174176
{
@@ -179,9 +181,44 @@ CellularAtParseTokenMap_t CellularUrcHandlerTable[] =
179181
}
180182
uint32_t CellularUrcHandlerTableSize = 4;
181183
```
184+
<br>
185+
There are two types of URC strings can be handled with this table:
186+
- <b>URC with prefix</b><br>
187+
This type of URC string is of the following format:<br>
188+
> <b>\<URC_leading_char\>\<URC_prefix\>":"\<URC_payload\></b><br>
189+
The logic to check the URC prefix can be referenced in @ref Cellular_ATIsPrefixPresent<br>
190+
Example of URC with prefix: <b>"+CREG:2,0"</b><br>
191+
In this example, <br>
192+
<b>URC_leading_char</b> is "+"<br>
193+
<b>URC_prefix</b> is "CREG"<br>
194+
<b>URC_payload</b> is "2,0"<br>
195+
The URC callback function, @ref CellularAtParseTokenHandler_t, will be called with
196+
parameter <b>pInputStr</b> point to string URC_payload, <b>"2,0"</b> in this example.
197+
> The default prefix leading char can be referenced in this config @ref CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR.<br>
198+
> The default valid prefix string chars can be referenced in this config @ref CELLULAR_CHECK_IS_PREFIX_CHAR.<br>
199+
> Reference @subpage cellular_prefix_string_customize_config for more information.
200+
201+
- <b>URC without prefix</b><br>
202+
This type of URC string is of fixed format.<br>
203+
Example of URC without prefix : <b>"NORMAL POWER DOWN"</b><br>
204+
The URC callback function, @ref CellularAtParseTokenHandler_t, will be called with
205+
parameter <b>pInputStr</b> point to URC string, <b>"NORMAL POWER DOWN"</b> in this example.
206+
<br>
207+
182208
@image html cellular_URC_handler_implementation.png width=80%
183209
*/
184210

211+
/**
212+
@page cellular_prefix_string_customize_config Customization config for prefix string.
213+
@brief The config can be redefined in cellular_config.h to support different modem prefix string format. <br>
214+
215+
@section CELLULAR_CHECK_IS_PREFIX_CHAR
216+
@copydoc CELLULAR_CHECK_IS_PREFIX_CHAR
217+
218+
@section CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR
219+
@copydoc CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR
220+
*/
221+
185222
/**
186223
@paramstructs_group{cellular_common,Cellular_common}
187224
@paramstructs_brief{cellular_common,cellular_common}

lexicon.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ firmwareversion
293293
freertos
294294
freertosconfig
295295
fucntion
296+
fso
296297
functionpointers
297298
fw
298299
gcc
@@ -468,6 +469,7 @@ parsetimezoneinfo
468469
parseyearmonthdayincclkresponse
469470
partialdata
470471
partialdatarcvdlen
472+
passcomparestring
471473
patbuf
472474
patcmd
473475
patcommandpayload
@@ -495,6 +497,7 @@ pcomminterface
495497
pcomminterfacehandle
496498
pcommintf
497499
pcontext
500+
pcomparestring
498501
pcurrentcmd
499502
pcwriteto
500503
pdata
@@ -529,6 +532,7 @@ phexdata
529532
pinputbuf
530533
pinputline
531534
pinputptr
535+
pinputstr
532536
pitm
533537
pkio
534538
pkt
@@ -751,6 +755,7 @@ simcardstate
751755
simlockstate
752756
sinr
753757
sms
758+
smso
754759
snprintf
755760
socketclose
756761
socketconnect

source/cellular_at_core.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@
4545

4646
/*-----------------------------------------------------------*/
4747

48-
#ifndef CELLULAR_CHECK_IS_PREFIX_CHAR
49-
#define CELLULAR_CHECK_IS_PREFIX_CHAR( inputChar ) \
50-
( ( ( ( int32_t ) isalpha( ( ( int8_t ) ( inputChar ) ) ) ) == 0 ) && \
51-
( ( ( int32_t ) isdigit( ( ( int8_t ) ( inputChar ) ) ) ) == 0 ) && \
52-
( ( inputChar ) != '+' ) && ( ( inputChar ) != '_' ) )
53-
#endif
54-
55-
/*-----------------------------------------------------------*/
56-
5748
/**
5849
* @brief String validation results.
5950
*/
@@ -136,6 +127,10 @@ CellularATError_t Cellular_ATIsPrefixPresent( const char * pString,
136127
{
137128
*pResult = false;
138129
}
130+
else if( !CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR( *pString ) )
131+
{
132+
*pResult = false;
133+
}
139134
else
140135
{
141136
/* There should be only '+', '_', characters or digit before seperator. */

source/cellular_pkthandler.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,22 @@ static CellularPktStatus_t urcParseToken( CellularContext_t * pContext,
133133
char * pInputLine )
134134
{
135135
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
136+
bool inputWithPrefix = false;
136137

137138
/* pInputLine = "+" pTokenPtr + ":" + pSavePtr.
138139
* if string not start with "+", then pTokenPtr = pSavePtr = pInputPtr. */
139140
char * pSavePtr = pInputLine, * pTokenPtr = pInputLine;
140141

141-
142142
LogDebug( ( "Next URC token to parse [%s]", pInputLine ) );
143143

144-
/* First check for + at the beginning and advance to point to the next
145-
* byte. Use that string to pass to strtok and retrieve the token. Once the
146-
* token use is retrieved, get the function handler map and call that
147-
* function. */
148-
if( *pSavePtr == '+' )
144+
/* Check if prefix exist in the input string. The pInputLine is checked in _processUrcPacket. */
145+
( void ) Cellular_ATIsPrefixPresent( pInputLine, &inputWithPrefix );
146+
147+
if( inputWithPrefix == true )
149148
{
149+
/* Cellular_ATIsPrefixPresent check the prefix string is valid and start with
150+
* leading char. ":" is also checked in Cellular_ATIsPrefixPresent. Remove
151+
* the leading char and split the string. */
150152
pSavePtr++;
151153
pTokenPtr = strtok_r( pSavePtr, ":", &pSavePtr );
152154

@@ -156,6 +158,12 @@ static CellularPktStatus_t urcParseToken( CellularContext_t * pContext,
156158
pktStatus = CELLULAR_PKT_STATUS_BAD_REQUEST;
157159
}
158160
}
161+
else
162+
{
163+
/* This is the input without prefix case. Nothing need to be done for this case.
164+
* There are some special cases. For example, "+URC" the string without ":" should
165+
* be regarded as URC without prefix. */
166+
}
159167

160168
if( pktStatus == CELLULAR_PKT_STATUS_OK )
161169
{

source/include/cellular_config_defaults.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,45 @@
401401
#define CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH ( 32U )
402402
#endif
403403

404+
/**
405+
* @brief Macro to check prefix leading char.<br>
406+
*
407+
* Cellular interface requires prefix string starts with "+". Some cellular modem
408+
* uses different leading char. This macro can be defined in cellular_config.h to
409+
* support different leading char.<br>
410+
*
411+
* <b>Default value (if undefined):</b> '+'
412+
*
413+
* For example:
414+
* > ^SMSO:(list of supported<fso>s)<br>
415+
* The prefix string contains <b>"^"</b> which is not default leading char for prefix
416+
* string. User can define this config to support this prefix string.
417+
*/
418+
#ifndef CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR
419+
#define CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR( x ) ( ( x ) == '+' )
420+
#endif
421+
422+
/**
423+
* @brief Macro to check prefix chars.<br>
424+
*
425+
* The macro to check prefix string contains valid char. Modem with different prefix
426+
* strings can be supported with this config.<br>
427+
*
428+
* <b>Default value (if undefined):</b> alphabet, digit, '+' and '_'
429+
*
430+
* For example:
431+
* > +APP PDP: 0,ACTIVE<br>
432+
* The prefix string contains space which is not default valid char. User can define
433+
* this config to support this prefix string.
434+
*/
435+
#ifndef CELLULAR_CHECK_IS_PREFIX_CHAR
436+
#define CELLULAR_CHECK_IS_PREFIX_CHAR( inputChar ) \
437+
( ( ( ( int32_t ) isalpha( ( ( int8_t ) ( inputChar ) ) ) ) == 0 ) && \
438+
( ( ( int32_t ) isdigit( ( ( int8_t ) ( inputChar ) ) ) ) == 0 ) && \
439+
( ( inputChar ) != '_' ) && \
440+
( !( CELLULAR_CHECK_IS_PREFIX_LEADING_CHAR( inputChar ) ) ) )
441+
#endif
442+
404443
/**
405444
* @brief Macro that is called in the cellular library for logging "Error" level
406445
* messages.

test/unit-test/cellular_at_core_utest.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@
167167
*/
168168
#define CELLULAR_SAMPLE_PREFIX_STRING_STAR_FIRST_INPUT "*CPIN:READY"
169169

170+
/**
171+
* @brief Cellular sample prefix string with invalid prefix char.
172+
*/
173+
#define CELLULAR_SAMPLE_PREFIX_STRING_INVALID_PREFIX_CHAR "+*CPIN:READY"
174+
170175
static int mallocAllocFail = 0;
171176

172177
/* ============================ UNITY FIXTURES ============================ */
@@ -1055,3 +1060,17 @@ void test_Cellular_ATIsPrefixPresent_Wrong_Prefix( void )
10551060
TEST_ASSERT_EQUAL( CELLULAR_AT_SUCCESS, cellularStatus );
10561061
TEST_ASSERT_EQUAL( false, Result );
10571062
}
1063+
1064+
/**
1065+
* @brief Test the string with wrong prefix case for Cellular_ATIsPrefixPresent to return CELLULAR_AT_BAD_PARAMETER.
1066+
*/
1067+
void test_Cellular_ATIsPrefixPresent_Invalid_Prefix_Char( void )
1068+
{
1069+
CellularATError_t cellularStatus = CELLULAR_AT_SUCCESS;
1070+
char pString[] = CELLULAR_SAMPLE_PREFIX_STRING_INVALID_PREFIX_CHAR;
1071+
bool Result;
1072+
1073+
cellularStatus = Cellular_ATIsPrefixPresent( pString, &Result );
1074+
TEST_ASSERT_EQUAL( CELLULAR_AT_SUCCESS, cellularStatus );
1075+
TEST_ASSERT_EQUAL( false, Result );
1076+
}

test/unit-test/cellular_pkthandler_utest.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#define CELLULAR_AT_MULTI_DATA_WO_PREFIX_STRING_RESP "+QIRD: 32\r123243154354364576587utrhfgdghfg"
5353
#define CELLULAR_URC_TOKEN_STRING_INPUT "RDY"
5454
#define CELLULAR_URC_TOKEN_STRING_INPUT_START_PLUS "+RDY"
55+
#define CELLULAR_URC_TOKEN_STRING_INPUT_WITH_PAYLOAD "+RDY:START"
5556
#define CELLULAR_URC_TOKEN_STRING_GREATER_INPUT "RDYY"
5657
#define CELLULAR_URC_TOKEN_STRING_SMALLER_INPUT "RD"
5758
#define CELLULAR_PLUS_TOKEN_ONLY_STRING "+"
@@ -327,6 +328,38 @@ uint16_t MockvQueueDelete( QueueHandle_t queue )
327328
return 1;
328329
}
329330

331+
CellularATError_t Cellular_ATIsPrefixPresent( const char * pString,
332+
bool * pResult )
333+
{
334+
CellularATError_t atStatus = CELLULAR_AT_SUCCESS;
335+
336+
TEST_ASSERT( pString != NULL );
337+
TEST_ASSERT( pResult != NULL );
338+
339+
if( strcmp( pString, CELLULAR_AT_MULTI_DATA_WO_PREFIX_STRING_RESP ) == 0 )
340+
{
341+
*pResult = true;
342+
}
343+
else if( strcmp( pString, CELLULAR_PLUS_TOKEN_ONLY_STRING ) == 0 )
344+
{
345+
*pResult = true;
346+
}
347+
else if( strcmp( pString, CELLULAR_URC_TOKEN_STRING_INPUT_WITH_PAYLOAD ) == 0 )
348+
{
349+
*pResult = true;
350+
}
351+
else if( strcmp( pString, CELLULAR_URC_TOKEN_STRING_INPUT_START_PLUS ) == 0 )
352+
{
353+
*pResult = false;
354+
}
355+
else
356+
{
357+
*pResult = false;
358+
}
359+
360+
return atStatus;
361+
}
362+
330363
CellularATError_t _CMOCK_Cellular_ATStrDup_CALLBACK( char ** ppDst,
331364
const char * pSrc,
332365
int cmock_num_calls )
@@ -623,10 +656,45 @@ void test__Cellular_HandlePacket_AT_UNSOLICITED_Happy_Path( void )
623656

624657
/* set for cellularAtParseTokenHandler function */
625658
passCompareString = false;
626-
pCompareString = getStringAfterColon( CELLULAR_URC_TOKEN_STRING_INPUT_START_PLUS );
659+
pCompareString = getStringAfterColon( CELLULAR_URC_TOKEN_STRING_INPUT_WITH_PAYLOAD );
660+
661+
pktStatus = _Cellular_HandlePacket( &context, AT_UNSOLICITED, CELLULAR_URC_TOKEN_STRING_INPUT_WITH_PAYLOAD );
662+
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
663+
TEST_ASSERT_EQUAL( true, passCompareString );
664+
}
665+
666+
/**
667+
* @brief Test input string without payload for _Cellular_HandlePacket.
668+
*
669+
* URC input string "+RDY" should be regarded as URC without prefix.
670+
* If there is a handler function registered in the table, the handler function is
671+
* called with pInputStr point to "+RDY" string.
672+
*/
673+
void test__Cellular_HandlePacket_AT_UNSOLICITED_Input_String_without_payload( void )
674+
{
675+
CellularContext_t context;
676+
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
677+
CellularAtParseTokenMap_t cellularTestUrcHandlerTable[] =
678+
{
679+
/* Use the URC string instead of the URC prefix in the mapping table. */
680+
{ CELLULAR_URC_TOKEN_STRING_INPUT_START_PLUS, cellularAtParseTokenHandler }
681+
};
682+
683+
memset( &context, 0, sizeof( CellularContext_t ) );
684+
context.tokenTable.pCellularUrcHandlerTable = cellularTestUrcHandlerTable;
685+
context.tokenTable.cellularPrefixToParserMapSize = 1;
686+
687+
Cellular_ATStrDup_StubWithCallback( _CMOCK_Cellular_ATStrDup_CALLBACK );
688+
689+
/* set for cellularAtParseTokenHandler function */
690+
passCompareString = false;
691+
pCompareString = CELLULAR_URC_TOKEN_STRING_INPUT_START_PLUS;
627692

628693
pktStatus = _Cellular_HandlePacket( &context, AT_UNSOLICITED, CELLULAR_URC_TOKEN_STRING_INPUT_START_PLUS );
629694
TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus );
695+
696+
/* passCompareString is set to true in cellularAtParseTokenHandler if pCompareString
697+
* equals to parameter pInputStr. */
630698
TEST_ASSERT_EQUAL( true, passCompareString );
631699
}
632700

0 commit comments

Comments
 (0)