CellularError_t Cellular_DeactivatePdn()

in modules/sara_r4/cellular_r4_api.c [991:1107]


CellularError_t Cellular_DeactivatePdn( CellularHandle_t cellularHandle,
                                        uint8_t contextId )
{
    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' };
    bool packetSwitchStatus = false;
    uint32_t i = 0;

    CellularServiceStatus_t serviceStatus = { 0 };
    CellularPdnContextActInfo_t pdpContextsActInfo = { 0 };

    CellularAtReq_t atReqDeactPdn =
    {
        NULL,
        CELLULAR_AT_NO_RESULT,
        NULL,
        NULL,
        NULL,
        0,
    };

    atReqDeactPdn.pAtCmd = cmdBuf;

    cellularStatus = _Cellular_IsValidPdn( contextId );

    if( cellularStatus == CELLULAR_SUCCESS )
    {
        /* Make sure the library is open. */
        cellularStatus = _Cellular_CheckLibraryStatus( pContext );
    }

    if( cellularStatus == CELLULAR_SUCCESS )
    {
        /* Get current network operator settings. */
        cellularStatus = Cellular_CommonGetServiceStatus( cellularHandle, &serviceStatus );

        if( cellularStatus == CELLULAR_SUCCESS )
        {
            /* Check the current <Act> status of context. */
            cellularStatus = _Cellular_GetContextActivationStatus( cellularHandle, &pdpContextsActInfo );
        }

        if( cellularStatus == CELLULAR_SUCCESS )
        {
            LogDebug( ( "Cellular_DeactivatePdn: Listing operator and context details below." ) );

            for( i = 0U; i < ( MAX_PDP_CONTEXTS - 1 ); i++ )
            {
                /* Print only those contexts that are present in +CGACT response */
                if( pdpContextsActInfo.contextsPresent[ i ] )
                {
                    LogDebug( ( "Context [%d], Act State [%d], Operator <Act> [%d]\r\n", i + 1,
                                pdpContextsActInfo.contextActState[ i ], serviceStatus.rat ) );
                }
            }

            /* Deactivate context if active */
            if( pdpContextsActInfo.contextActState[ contextId - 1 ] == true )
            {
                /* Don't deactivate LTE default bearer context */
                /* Otherwise sending AT command "+CGACT=0,1" for deactivation will result in ERROR */
                if( ( serviceStatus.rat >= CELLULAR_RAT_LTE ) && ( contextId == DEFAULT_BEARER_CONTEXT_ID ) )
                {
                    LogInfo( ( "Cellular_DeactivatePdn: Default Bearer context %d Active. Not allowed to deactivate.", contextId ) );
                    cellularStatus = CELLULAR_NOT_ALLOWED;
                }
                else
                {
                    ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s=0,%u", "AT+CGACT", contextId );
                    pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqDeactPdn, PDN_DEACT_PACKET_REQ_TIMEOUT_MS );
                    cellularStatus = _Cellular_TranslatePktStatus( pktStatus );
                }

                if( ( cellularStatus != CELLULAR_SUCCESS ) && ( cellularStatus != CELLULAR_NOT_ALLOWED ) )
                {
                    LogError( ( "Cellular_DeactivatePdn: can't deactivate PDN, PktRet: %d", pktStatus ) );

                    /* Sometimes +CGACT deactivation fails in 2G. Then check packet switch attach. If attached, detach packet switch. */
                    if( ( serviceStatus.rat == CELLULAR_RAT_GSM ) || ( serviceStatus.rat == CELLULAR_RAT_EDGE ) )
                    {
                        cellularStatus = _Cellular_GetPacketSwitchStatus( cellularHandle, &packetSwitchStatus );

                        if( ( cellularStatus == CELLULAR_SUCCESS ) && ( packetSwitchStatus == true ) )
                        {
                            LogError( ( "Deactivate Packet switch" ) );
                            ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s", "AT+CGATT=0" );
                            pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqDeactPdn, GPRS_ATTACH_REQ_TIMEOUT_MS );
                            cellularStatus = _Cellular_TranslatePktStatus( pktStatus );
                        }
                        else if( cellularStatus != CELLULAR_SUCCESS )
                        {
                            LogError( ( "Packet switch query failed" ) );
                            pktStatus = CELLULAR_PKT_STATUS_FAILURE;
                            cellularStatus = _Cellular_TranslatePktStatus( pktStatus );
                        }
                        else
                        {
                            LogInfo( ( "Packet switch detached" ) );
                        }
                    }
                }
            }
            else
            {
                LogInfo( ( "Cellular_DeactivatePdn: Context id [%d] is already deactive", contextId ) );
            }
        }
        else
        {
            LogError( ( "Cellular_DeactivatePdn: Unable to list operator and context details." ) );
        }
    }

    return cellularStatus;
}