⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callctrl.cpp

📁 手机RILGSM实现的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {
        dwDialOpts |= CMDOPT_LONGDIALSTRING;
    }

    if ( szWalk == szDialStringStart )
    {
        // No valid chars processed
        hr = E_INVALIDARG;
        goto Error;
    }

    // Remember to paste on the terminating '\0'
    *szWalk='\0';

#ifndef WAVECOM_DRIVER
    // HW-SPECIFIC: WaveCom hardware doesn't support Closed User Groups
    if (dwOptions & RIL_DIALOPT_CLOSEDGROUP) {
        (void)strncpyz(szWalk, "G", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }
#endif // WAVECOM_DRIVER

    if (dwOptions & RIL_DIALOPT_RESTRICTID) {
        (void)strncpyz(szWalk, "I", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }
    else if (dwOptions & RIL_DIALOPT_PRESENTID) {
        (void)strncpyz(szWalk, "i", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }

    // If it's not a data call, terminate with a ; character
    if ((dwType==RIL_CALLTYPE_VOICE)||(dwType==RIL_CALLTYPE_PTT))
    {
        (void)strncpyz(szWalk, ";", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }
    else if (dwType==RIL_CALLTYPE_DATA)
    {
        dwDialOpts |= CMDOPT_DELAYCONNECTRSP;
    }

    (void)strncpyz(szWalk, "\r", MAX_PATH - (szWalk - szCmd));

    // perform external calltype determination processing
    if (g_rfExternalCalltypeDetermination)
    {
        //  There is no call id associated with the the dialed call yet,
        //  so store the calltype so it can be used later
        EnterCriticalSection(&g_csDialedCallData);
        g_rcdDialedCallData.fValid = TRUE;
        g_rcdDialedCallData.dwCalltype = dwType;
        MultiByteToWideChar(CP_ACP, 0, szAddress, MAXLENGTH_ADDRESS, g_rcdDialedCallData.wszAddress, MAXLENGTH_ADDRESS);
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : RILDrv_Dial : Setting g_rcdDialedCallData calltype = %d, address = %s.\r\n"), g_rcdDialedCallData.dwCalltype, g_rcdDialedCallData.wszAddress));
        LeaveCriticalSection(&g_csDialedCallData);
    }
    if(RILDrv_CC_DialCondition(dwType)==E_FAIL)
    {
        hr = E_FAIL;
        goto Error;
    }            
    switch (dwType)
    {

        case RIL_CALLTYPE_VOICE://first voice  mo call
        
            stCCOption.bAddCall = TRUE;
            stCCOption.nCallType = CALL_TYPE_VOICE_FIRST;
            stCCOption.bArranageCID = FALSE;
            stCCOption.bReleaseTotalCID = FALSE ;
            stCCOption.nLocalCID = 0 ;
            stCCOption.nTotalCID = 0 ;
            stCCOption.bVoice2ndTo1st = FALSE;
            stCCOption.bVoice1stToFakeHangUp = FALSE;
            stCCOption.bDial = TRUE;
             
            //change the share memory,set the first voice call flag
            if(ChangePhoneCallStatus(stCCOption,bSendSpechangup))
            {
                RETAILMSG(1, (TEXT("[TI]RILDrv_Dial:VOICE DIAL:call ChangePhoneCallStatus OK\r\n")));
            }
            else
            {
                RETAILMSG(1, (TEXT("[TI]RILDrv_Dial:VOICE DIAL:call ChangePhoneCallStatus failed\r\n")));
            }
            break;
        case RIL_CALLTYPE_DATA://csd call
            stCCOption.bAddCall = TRUE;
            stCCOption.nCallType = CALL_TYPE_CSD;
            stCCOption.bArranageCID = FALSE;
            stCCOption.bReleaseTotalCID = FALSE ;
            stCCOption.nLocalCID = 0 ;
            stCCOption.nTotalCID = 0 ;
            stCCOption.bVoice2ndTo1st = FALSE;
            stCCOption.bVoice1stToFakeHangUp = FALSE;
            stCCOption.bDial = TRUE;
             
            //change the share memory,set the csd call flag
            if(ChangePhoneCallStatus(stCCOption,bSendSpechangup))
            {
                RETAILMSG(1, (TEXT("[TI]RILDrv_Dial:DATA DIAL:call ChangePhoneCallStatus OK\r\n")));
            }
            else
            {
                RETAILMSG(1, (TEXT("[TI]RILDrv_Dial:DATA DIAL:call ChangePhoneCallStatus failed\r\n")));
            }
            break;
    }
#if 0    
    //modify by fengguisen from the Crossbow version RIL
    if ((dwType==RIL_CALLTYPE_VOICE)||(dwType==RIL_CALLTYPE_PTT))
    {
        // Indicate call is Active
        IndicateCallActivityToAudioSubsystem(TRUE);
    }
//end modify by fengguisen
#endif
    if (!QueueCmd(pHandle, szCmd, dwDialOpts, APIID_DIAL, NULL, pnd, hr)) {
      //  bTurnoffAudio = TRUE;
        hr = E_FAIL;
        goto Error;
    }
    pnd = NULL;
    RILDrv_SetCallNetwork(SPECNOTIF_NETSLOT2);    
//add by fengguisen for Simultaneous voice and data call    
    //end add

Error:
#if 0
    //modify by fengguisen from the Crossbow version RIL
    if ( bTurnoffAudio||(g_bRadioOff))
    {
        // Indicate call is inactive to audio driver only if call list is empty.
        RILDrv_CC_TurnOffAudioWetherOrNot();
    }  
#endif    
    //Added by wuguangliang to be consistent with wave driver
    //Although call connect is not established now.
    //2004/4/11  
    g_fInCall = TRUE;
    
//end modify by fengguisen
    if(pnd)
    {
        delete pnd;
    }
    
    return hr;
}


//
//
//
HRESULT RILDrv_Answer(DWORD dwParam)
{
    FUNCTION_TRACE(RILDrv_Answer);
    CNotificationData* pnd = NULL;
    RILCONNECTINFO rci; memset(&rci,0,sizeof(rci)); // zero struct
    HRESULT hr = S_OK;
    CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
    if (!pHandle) {
        hr = E_FAIL;
        goto Error;
    }

    // Set up the voice connect notification. If  incoming call is a data call,
    //    we will get a "CONNECT" instead of "OK", which will prevent this notification
    //    from being sent
    pnd = new CNotificationData;
    if (pnd) {
        rci.cbSize = sizeof(RILCONNECTINFO);
        rci.dwParams = RIL_PARAM_CNI_CALLTYPE;
        rci.dwCallType = RIL_CALLTYPE_VOICE;

        // check for externally determined calltype
        if (g_rfExternalCalltypeDetermination)
        {
            //  There may be no call id associated with the call yet,
            //  so use the previously stored calltype
            EnterCriticalSection(&g_csRingingCallData);
            if (g_rcdRingingCallData.fCalltypeValid)
            {
                rci.dwCallType = g_rcdRingingCallData.dwCalltype;
                DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : RILDrv_Answer : using calltype %d.\r\n"), g_rcdRingingCallData.dwCalltype));
                g_rcdRingingCallData.dwCalltype = RIL_CALLTYPE_UNKNOWN;
                g_rcdRingingCallData.fCalltypeValid = FALSE;
                //  Just in case there was a call id, clear the associated ringing call globals
                g_rcdRingingCallData.fCallIdValid = FALSE;
                g_rcdRingingCallData.dwCallId = RIL_MAX_TRACKED_CALL_ID;
            }
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : RILDrv_Answer : Ringing Call TypeValid = %d, type = %d, IdValid = %d, Id = %d, \r\n"), 
                g_rcdRingingCallData.fCalltypeValid, g_rcdRingingCallData.dwCalltype,g_rcdRingingCallData.fCallIdValid,g_rcdRingingCallData.dwCallId));
            LeaveCriticalSection(&g_csRingingCallData);
        }
        
        if (!pnd->InitFromRealBlob(RIL_NOTIFY_CONNECT, &rci, sizeof(RILCONNECTINFO))) {
            delete pnd;
            pnd = NULL;
        }
    }

    //modify by fengguisen from the Crossbow version RIL
    // Indicate call is Active.
    IndicateCallActivityToAudioSubsystem(TRUE);
//end modify by fengguisen
    if (!QueueCmd(pHandle, "ATA\r", CMDOPT_ANSWER, APIID_ANSWER, NULL, pnd, hr)) {
        hr = E_FAIL;
        goto Error;
    }
    pnd = NULL;

Error:

    //modify by fengguisen from the Crossbow version RIL
    if (E_FAIL == hr) 
    {
        // Indicate call is inactive to audio driver only if call list is empty.
        RILDrv_CC_TurnOffAudioWetherOrNot();    
    }
//end modify by fengguisen
    if(pnd)
    {
        delete pnd;
    }
    
    return hr;
}


//
//
//
HRESULT RILDrv_Hangup(DWORD dwParam)
{
    FUNCTION_TRACE(RILDrv_Hangup);
    CNotificationData* pnd = NULL;
    BOOL fSuccess;
    HRESULT hr = S_OK;
    CALLCTRL_SHARE_MEMORY_OPTION stShareMemOpt;
    
    CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
    if (!pHandle) {
        hr = E_FAIL;
        goto Error;
    }
    
    if(RILDrv_CC_GetShareMemOpt(stShareMemOpt))
    {
        if((!RILDrv_CC_IsCallStatusExist(stShareMemOpt.nRILDriver1CallStatus,CALL_STATUS_VOICE_HOLD))
            &&(!RILDrv_CC_IsCallStatusExist(stShareMemOpt.nRILDriver1CallStatus,CALL_STATUS_VOICE_ACTIVE))
            &&(!RILDrv_CC_IsCallStatusExist(stShareMemOpt.nRILDriver1CallStatus,CALL_STATUS_VOICE_DIALING))
            &&(!RILDrv_CC_IsCallStatusExist(stShareMemOpt.nRILDriver1CallStatus,CALL_STATUS_DATA_ACTIVE))
            &&(!RILDrv_CC_IsCallStatusExist(stShareMemOpt.nRILDriver1CallStatus,CALL_STATUS_DATA_DIALING)))
        {
             RETAILMSG(1, (TEXT("[TI]****TI HASN'T EXSIT RILDrv_Hangup\r\n")));
             goto Error;
        }
        if(!RILDrv_CC_IsCallStatusExist(stShareMemOpt.nRILDriver1CallStatus,CALL_STATUS_VOICE_2ND_INCOMING))
        {
            pnd = new CNotificationData;
            if (pnd) {
                if (pHandle->FPreferred()) {
                    fSuccess = pnd->InitFromRealBlob(RIL_NOTIFY_EMERGENCYHANGUP, NULL, 0);
                } else {
                   // must notify of disconnect here since this lets drivers go to lower power state
                    fSuccess = pnd->InitFromDWORDBlob(RIL_NOTIFY_DISCONNECT, RIL_DISCINIT_LOCAL);
                }
                //RETAILMSG(1, (TEXT("[TI]****RILDrv_Hangup:I:  is called\r\n")));
                if (!fSuccess) {
                    delete pnd;
                    pnd = NULL;
                }
            }
        }
    }
    if (!QueueCmd(pHandle, "ATH\r", CMDOPT_HANGUP, APIID_HANGUP, NULL, pnd, hr)) {
        hr = E_FAIL;
        goto Error;
    }
    pnd = NULL;

Error:
    if(pnd)
    {
        delete pnd;
    }
    return hr;
}


//
//
//
HRESULT RILDrv_SendDTMF(DWORD dwParam, LPCSTR lpszChars, DWORD dwDuration)
{
    FUNCTION_TRACE(RILDrv_SendDTMF);
#ifndef OEM1_DRIVER // SUPPORT_DTMF_DURATION
    UINT nValue;
#endif
    DEBUGCHK(NULL != lpszChars);
    DEBUGCHK(0 < strlen(lpszChars));

    UINT NumVals;
    DWORD dwTimeout;

    char szCmd[MAX_PATH];
    LPSTR szWalk = szCmd;
    LPCSTR pchChars;
    HRESULT hr = S_OK;
    CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
    if (!pHandle || !lpszChars) {
        hr = E_FAIL;
        goto Error;
    }

#ifndef OEM1_DRIVER // SUPPORT_DTMF_DURATION
    if ((dwDuration < 300) || (dwDuration == RIL_DTMFDURATION_DEFAULT))
    {
        dwDuration = 300;
    }

    nValue = (dwDuration + 50 ) / 100;

    (void)_snprintfz(szWalk, MAX_PATH - (szWalk - szCmd), "AT+VTD=%u;", nValue);
#else
    (void)_snprintfz(szWalk, MAX_PATH - (szWalk - szCmd), "AT");
    // Because we're not setting the duration, the radio is using the default
    // duration.  Make sure we use the default value so the timeout calculation
    // below is correct.
    dwDuration = 300;
#endif
    szWalk = strchr(szWalk, '\0');  // NO_TYPO: 27
    DEBUGCHK(NULL != szWalk);

    NumVals=0;
#if !defined(OEM2_DRIVER)
    for (pchChars = lpszChars; *pchChars; pchChars++) {
        NumVals++;
        (void)_snprintfz(szWalk, MAX_PATH - (szWalk - szCmd), "+VTS=%c;", *pchChars);
        szWalk = strchr(szWalk, '\0');  // NO_TYPO: 27
        DEBUGCHK(NULL != szWalk);
    }
    // remove the trailing ";"
    *(--szWalk) = '\0';
#else

    // OEM2 has a special version of AT+VTS which allows up to 20 DTMF tones in a single command

    pchChars = lpszChars;
    if (*pchChars)
    {
        UINT nSent = 0;
        NumVals++;
        (void)_snprintfz(szWalk, MAX_PATH - (szWalk - szCmd), "+VTS=\"%c", *pchChars);
        szWalk = strchr(szWalk, '\0');  // NO_TYPO: 27
        DEBUGCHK(NULL != szWalk);
        pchChars++;
        nSent++;
//modify by fengguisen from the Crossbow version RIL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -