char* CSilo_IMS::GetURCInitString()
{
    char szEnableIMS[MAX_BUFFER_SIZE] = {'\0'};

    // IMS Modem Centric
    if (CTE::GetTE().IsIMSCapable())
    {
        PrintStringNullTerminate(szEnableIMS, MAX_BUFFER_SIZE,
                "|+CISRVCC=1|+CIREP=1|+CIREG=1|+XISMSCFG=%d",
                CTE::GetTE().IsSMSOverIPCapable() ? 1 : 0);
    }
    // IMS AP Centric
    else if (CTE::GetTE().IsIMSApCentric())
    {
        PrintStringNullTerminate(szEnableIMS, MAX_BUFFER_SIZE, "+CIREP=1|+XISRVCC=1");
    }

    if (szEnableIMS != '\0')
    {
        if (!ConcatenateStringNullTerminate(m_szURCInitString,
                sizeof(m_szURCInitString), szEnableIMS))
        {
            RIL_LOG_CRITICAL("CSilo_IMS::GetURCInitString() : Failed to concat XICFG CISRVCC "
                    "CIREP XISMSCFG to URC init string!\r\n");
            return NULL;
        }
    }
    return m_szURCInitString;
}
void triggerQueryBearerParams(void* param)
{
    REQUEST_DATA rReqDataTFT;
    REQUEST_DATA rReqDataQOS;
    memset(&rReqDataTFT, 0, sizeof(REQUEST_DATA));
    memset(&rReqDataQOS, 0, sizeof(REQUEST_DATA));
    CChannel_Data* pChannelData = NULL;
    UINT32 uiPCID = 0;
    UINT32 uiCID = 0;
    void** callbackParams = NULL;

    if (param == NULL)
        return;

    callbackParams = (void**)param;
    uiPCID = (UINT32)callbackParams[0];
    uiCID = (UINT32)callbackParams[1];
    pChannelData = (CChannel_Data*)callbackParams[2];

    delete callbackParams;

    RIL_LOG_VERBOSE("triggerQueryBearerParams - uiPCID: %u, uiCID: %u\r\n", uiPCID, uiCID);

    if (PrintStringNullTerminate(rReqDataTFT.szCmd1, sizeof(rReqDataTFT.szCmd1), "AT+CGTFTRDP=%u\r",
            uiCID))
    {
        CCommand* pCmdTFT = new CCommand(pChannelData->GetRilChannel(), NULL, REQ_ID_NONE,
                rReqDataTFT, &CTE::ParseReadBearerTFTParams);
        if (pCmdTFT)
        {
            if (!CCommand::AddCmdToQueue(pCmdTFT))
            {
                RIL_LOG_CRITICAL("triggerQueryBearerParams - "
                        "Unable to queue AT+CGTFTRDP command!\r\n");
                delete pCmdTFT;
            }
        }
    }

    if (PrintStringNullTerminate(rReqDataQOS.szCmd1, sizeof(rReqDataQOS.szCmd1), "AT+CGEQOS=%u\r",
            uiCID))
    {
        CCommand* pCmdQOS = new CCommand(pChannelData->GetRilChannel(), NULL, REQ_ID_NONE,
                rReqDataQOS, &CTE::ParseReadBearerQOSParams);
        if (pCmdQOS)
        {
            if (!CCommand::AddCmdToQueue(pCmdQOS))
            {
                RIL_LOG_CRITICAL("triggerQueryBearerParams - "
                        "Unable to queue AT+CGEQOS command!\r\n");
                delete pCmdQOS;
            }
        }
    }
}
void triggerHangup(UINT32 uiCallId)
{
    REQUEST_DATA rReqData;

    memset(&rReqData, 0, sizeof(REQUEST_DATA));
    if (!PrintStringNullTerminate(rReqData.szCmd1, sizeof(rReqData.szCmd1),
             "AT+XSETCAUSE=1,21;+CHLD=1%u\r", uiCallId))
    {
        RIL_LOG_CRITICAL("triggerHangup() - Unable to create hangup command!\r\n");
        return;
    }

    CCommand* pCmd = new CCommand(g_pReqInfo[RIL_REQUEST_HANGUP].uiChannel,
                                    NULL, REQ_ID_NONE, rReqData);
    if (pCmd)
    {
        if (!CCommand::AddCmdToQueue(pCmd, TRUE))
        {
            RIL_LOG_CRITICAL("triggerHangup() - Unable to queue command!\r\n");
            delete pCmd;
            pCmd = NULL;
        }
    }
    else
    {
        RIL_LOG_CRITICAL("triggerHangup() - Unable to allocate memory for new command!\r\n");
    }
}
void triggerQueryDefaultPDNContextParams(void* param)
{
    REQUEST_DATA rReqData;
    memset(&rReqData, 0, sizeof(REQUEST_DATA));
    CChannel_Data* pChannelData = NULL;
    UINT32 uiCID = 0;

    if (param == NULL)
        return;

    pChannelData = (CChannel_Data*)param;

    uiCID = pChannelData->GetContextID();

    RIL_LOG_VERBOSE("triggerQueryDefaultPDNContextParams - uiCID: %u\r\n", uiCID);

    if (PrintStringNullTerminate(rReqData.szCmd1, sizeof(rReqData.szCmd1), "AT+CGCONTRDP=%u\r",
            uiCID))
    {
        CCommand* pCmd = new CCommand(pChannelData->GetRilChannel(), NULL, REQ_ID_NONE,
                rReqData, &CTE::ParseReadContextParams,
                &CTE::PostReadDefaultPDNContextParams);
        if (pCmd)
        {
            if (!CCommand::AddCmdToQueue(pCmd))
            {
                RIL_LOG_CRITICAL("triggerQueryDefaultPDNContextParams - "
                        "Unable to queue AT+CGCONTRDP command!\r\n");
                delete pCmd;
            }
        }
    }
}
void triggerSIMAppError(const void* param)
{
    sOEM_HOOK_RAW_UNSOL_SIM_APP_ERR_IND data;

    data.command = RIL_OEM_HOOK_RAW_UNSOL_SIM_APP_ERR_IND;
    PrintStringNullTerminate(data.szSimError, SIM_APP_ERROR_SIZE+1, (char*)param);

    RIL_onUnsolicitedResponse(RIL_UNSOL_OEM_HOOK_RAW, (void*)&data,
            sizeof(sOEM_HOOK_RAW_UNSOL_SIM_APP_ERR_IND));
}
// [in] param = 1 for mobile release and 0 for network release
void triggerDropCallEvent(void* param)
{
    sOEM_HOOK_RAW_UNSOL_CRASHTOOL_EVENT_IND data;
    char szBuffer[CRASHTOOL_BUFFER_SIZE];

    BOOL bMobileRelease = (1 == (UINT32)param);

    data.command = RIL_OEM_HOOK_RAW_UNSOL_CRASHTOOL_EVENT_IND;
    data.type = CRASHTOOL_STATS;
    PrintStringNullTerminate(data.name, CRASHTOOL_NAME_SIZE, "TFT_STAT_CDROP");
    data.nameSize = strnlen(data.name, CRASHTOOL_NAME_SIZE);

    // Pre-initialize all data size to 0
    for (int i = 0; i < CRASHTOOL_NB_DATA; i++)
    {
        data.dataSize[i] = 0;
    }

    // See the definition of sOEM_HOOK_RAW_UNSOL_CRASHTOOL_EVENT_IND in
    // CORE/oemhookids.h for the raw unsol content.
    if (bMobileRelease)
    {
        PrintStringNullTerminate(data.data0, CRASHTOOL_BUFFER_SIZE, "MOBILE RELEASE");
        data.dataSize[0] = strnlen(data.data0, CRASHTOOL_BUFFER_SIZE);
    }
    else
    {
        data.dataSize[0] = snprintf(data.data0, CRASHTOOL_BUFFER_SIZE, "%s",
                CTE::GetTE().GetLastCEER());
    }

    if (strlen(CTE::GetTE().GetNetworkData(LAST_NETWORK_CREG)) != 0)
    {
        data.dataSize[1] = snprintf(data.data1, CRASHTOOL_BUFFER_SIZE, "+CREG: %s;",
                CTE::GetTE().GetNetworkData(LAST_NETWORK_CREG));
    }

    if (strlen(CTE::GetTE().GetNetworkData(LAST_NETWORK_XREG)) != 0)
    {
        data.dataSize[1] += snprintf(szBuffer, CRASHTOOL_BUFFER_SIZE - data.dataSize[1],
                "+XREG: %s;", CTE::GetTE().GetNetworkData(LAST_NETWORK_XREG));
        strncat(data.data1, szBuffer, CRASHTOOL_BUFFER_SIZE);
    }

    if (strlen(CTE::GetTE().GetNetworkData(LAST_NETWORK_XCSQ)) != 0)
    {
        data.dataSize[2] = snprintf(data.data2, CRASHTOOL_LARGE_BUFFER_SIZE, "%s;",
                CTE::GetTE().GetNetworkData(LAST_NETWORK_XCSQ));
    }

    data.dataSize[3] = snprintf(data.data3, CRASHTOOL_BUFFER_SIZE, "%s,%s,%s",
            CTE::GetTE().GetNetworkData(LAST_NETWORK_OP_NAME_NUMERIC),
            CTE::GetTE().GetNetworkData(LAST_NETWORK_LAC),
            CTE::GetTE().GetNetworkData(LAST_NETWORK_CID));

    data.dataSize[4] = snprintf(data.data4, CRASHTOOL_LARGE_BUFFER_SIZE, "%s",
            CTE::GetTE().GetNetworkData(LAST_NETWORK_OP_NAME_SHORT));

    RIL_onUnsolicitedResponse (RIL_UNSOL_OEM_HOOK_RAW, (void*)&data,
            sizeof(sOEM_HOOK_RAW_UNSOL_CRASHTOOL_EVENT_IND));
}
// [in] param = context id.
void triggerDeactivateDataCall(void* param)
{
    RIL_LOG_VERBOSE("triggerDeactivateDataCall() - Enter\r\n");

    UINT32 uiCID;
    REQUEST_DATA rReqData;
    BOOL bSuccess = FALSE;
    CCommand* pCmd = NULL;
    UINT32* pCID = NULL;

    if (param == NULL)
        return;

    uiCID = (UINT32)param;

    pCID = (UINT32*)malloc(sizeof(UINT32));
    if (NULL == pCID)
        return;

    *pCID = uiCID;
    memset(&rReqData, 0, sizeof(REQUEST_DATA));

    if (!PrintStringNullTerminate(rReqData.szCmd1, sizeof(rReqData.szCmd1),
                                                "AT+CGACT=0,%d\r", uiCID))
    {
        RIL_LOG_CRITICAL("triggerDeactivateDataCall() - Unable to create CGACT command!\r\n");
        goto Error;
    }

    rReqData.pContextData = pCID;
    rReqData.cbContextData = sizeof(UINT32);

    pCmd = new CCommand(g_pReqInfo[RIL_REQUEST_DEACTIVATE_DATA_CALL].uiChannel,
                            NULL, RIL_REQUEST_DEACTIVATE_DATA_CALL, rReqData,
                            &CTE::ParseDeactivateDataCall,
                            &CTE::PostDeactivateDataCallCmdHandler);

    if (pCmd)
    {
        pCmd->SetHighPriority();
        if (!CCommand::AddCmdToQueue(pCmd, TRUE))
        {
            RIL_LOG_CRITICAL("triggerDeactivateDataCall() - Unable to queue command!\r\n");
            goto Error;
        }
    }
    else
    {
        RIL_LOG_CRITICAL("triggerDeactivateDataCall() - Unable to allocate memory for new command!\r\n");
    }

    bSuccess = TRUE;
Error:
    if (!bSuccess)
    {
        free(pCID);
        delete pCmd;
    }

    RIL_LOG_VERBOSE("triggerDeactivateDataCall() - Exit\r\n");
}