in modules/sara_r4/cellular_r4_api.c [2529:2679]
CellularError_t Cellular_SetPdnConfig( CellularHandle_t cellularHandle,
uint8_t contextId,
const CellularPdnConfig_t * pPdnConfig )
{
CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle;
CellularError_t cellularStatus = CELLULAR_SUCCESS;
CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK;
char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' };
char pPdpTypeStr[ CELULAR_PDN_CONTEXT_TYPE_MAX_SIZE ] = { '\0' };
uint32_t i = 0;
CellularPdnContextInfo_t pdpContextsInfo = { 0 };
CellularPdnContextInfo_t * pPdpContextsInfo = &pdpContextsInfo;
CellularAtReq_t atReqSetPdn =
{
NULL,
CELLULAR_AT_NO_RESULT,
NULL,
NULL,
NULL,
0,
};
atReqSetPdn.pAtCmd = cmdBuf;
if( pPdnConfig == NULL )
{
LogDebug( ( "Cellular_SetPdnConfig: Input parameter is NULL" ) );
cellularStatus = CELLULAR_BAD_PARAMETER;
}
else
{
switch( pPdnConfig->pdnContextType )
{
case CELLULAR_PDN_CONTEXT_IPV4:
( void ) strncpy( pPdpTypeStr, "IP", 3U ); /* 3U is the length of "IP" + '\0'. */
break;
case CELLULAR_PDN_CONTEXT_IPV6:
( void ) strncpy( pPdpTypeStr, "IPV6", 5U ); /* 5U is the length of "IPV6" + '\0'. */
break;
case CELLULAR_PDN_CONTEXT_IPV4V6:
( void ) strncpy( pPdpTypeStr, "IPV4V6", 7U ); /* 7U is the length of "IPV4V6" + '\0'. */
break;
default:
LogDebug( ( "Cellular_SetPdnConfig: Invalid pdn context type %d",
CELLULAR_PDN_CONTEXT_IPV4V6 ) );
cellularStatus = CELLULAR_BAD_PARAMETER;
break;
}
}
if( cellularStatus == CELLULAR_SUCCESS )
{
cellularStatus = _Cellular_IsValidPdn( contextId );
}
if( cellularStatus == CELLULAR_SUCCESS )
{
/* Make sure the library is open. */
cellularStatus = _Cellular_CheckLibraryStatus( pContext );
}
if( cellularStatus == CELLULAR_SUCCESS )
{
/* Check current APN name and IP type of contextId first to avoid unneccessary network de-registration. */
/* TODO: This implementation currently assumes only one context in list. Need to add complete contexts list parsing */
CellularAtReq_t atReqGetCurrentApnName =
{
"AT+CGDCONT?",
CELLULAR_AT_MULTI_WITH_PREFIX,
"+CGDCONT",
_Cellular_RecvFuncGetPdpContextSettings,
NULL,
sizeof( CellularPdnContextInfo_t ),
};
atReqGetCurrentApnName.pData = pPdpContextsInfo;
pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetCurrentApnName );
cellularStatus = _Cellular_TranslatePktStatus( pktStatus );
if( cellularStatus == CELLULAR_SUCCESS )
{
LogDebug( ( "Cellular_SetPdnConfig: Listing operator and context details below." ) );
for( i = 0U; i < ( MAX_PDP_CONTEXTS - 1 ); i++ )
{
/* Print only those contexts that are present in +CGDCONT response */
if( pdpContextsInfo.contextsPresent[ i ] )
{
LogDebug( ( "Context [%d], IP Type [%s], APN Name [%s], IP Address [%s]\r\n", i + 1,
pdpContextsInfo.ipType[ i ], ( char * ) pdpContextsInfo.apnName,
( char * ) pdpContextsInfo.ipAddress ) );
}
}
}
}
if( cellularStatus == CELLULAR_SUCCESS )
{
/* Form the AT command. */
/* The return value of snprintf is not used.
* The max length of the string is fixed and checked offline. */
/* coverity[misra_c_2012_rule_21_6_violation]. */
if( ( strstr( pdpContextsInfo.apnName[ contextId - 1 ], pPdnConfig->apnName ) == NULL ) || ( strcmp( pdpContextsInfo.ipType[ contextId - 1 ], pPdpTypeStr ) != 0 ) )
{
if( strcmp( pdpContextsInfo.ipType[ contextId - 1 ], pPdpTypeStr ) != 0 )
{
LogInfo( ( "Cellular_SetPdnConfig: Setting new IPv (Module IPv:%s != %s)\r\n", pdpContextsInfo.ipType[ contextId - 1 ], pPdpTypeStr ) );
}
if( strstr( pdpContextsInfo.apnName[ contextId - 1 ], pPdnConfig->apnName ) == NULL )
{
LogInfo( ( "Cellular_SetPdnConfig: Setting new APN (Module APN:%s != %s)\r\n", pdpContextsInfo.apnName[ contextId - 1 ], pPdnConfig->apnName ) );
}
/* TODO: Add support if + UAUTHREQ is PAP / CHAP */
( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s%d,\"%s\",\"%s\",,0,0;%s%d,%d%s", /*,\"%s\",\"%s\" TODO: add if +UAUTHREQ is PAP/CHAP */
"AT+COPS=2;+CGDCONT=",
contextId,
pPdpTypeStr,
pPdnConfig->apnName,
"+UAUTHREQ=",
contextId,
pPdnConfig->pdnAuthType,
";+COPS=0" );
/*pPdnConfig->username, */
/*pPdnConfig->password); */
pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetPdn );
if( pktStatus != CELLULAR_PKT_STATUS_OK )
{
LogError( ( "Cellular_SetPdnConfig: can't set PDN, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) );
cellularStatus = _Cellular_TranslatePktStatus( pktStatus );
}
}
else
{
LogInfo( ( "Cellular_SetPdnConfig: APN and IPv already set.\r\n" ) );
}
}
return cellularStatus;
}