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

📄 callctrl.cpp

📁 windows mobile RIL软件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1999  Microsoft Corporation

Module Name:

callctrl.cpp

Abstract:


Notes:


--*/


#include "precomp.h"
#include <rilbacklight.h>
#include "rilhand.h"


//
// Call status values
//
static const DWORD g_rgdwCallStats[] =
{
    RIL_CALLSTAT_ACTIVE,            // 0
    RIL_CALLSTAT_ONHOLD,            // 1
    RIL_CALLSTAT_DIALING,           // 2
    RIL_CALLSTAT_ALERTING,          // 3
    RIL_CALLSTAT_INCOMING,          // 4
    RIL_CALLSTAT_WAITING,           // 5
};
#define NUM_CALLSTATS   (sizeof(g_rgdwCallStats) / sizeof(DWORD))

#if defined(PHILIP_DRIVER)
extern HANDLE g_hWavDev;
#endif

//
// Call type values
//
static const DWORD g_rgdwCallTypes[] =
{
    RIL_CALLTYPE_VOICE,             // 0
    RIL_CALLTYPE_DATA,              // 1
    RIL_CALLTYPE_FAX,               // 2
    RIL_CALLTYPE_PTT,               // 3
    RIL_CALLTYPE_VT,                // 4
    RIL_CALLTYPE_UNKNOWN,           // 5
    RIL_CALLTYPE_UNKNOWN,           // 6
    RIL_CALLTYPE_UNKNOWN,           // 7
    RIL_CALLTYPE_UNKNOWN,           // 8
    RIL_CALLTYPE_UNKNOWN,           // 9
};
#define NUM_CALLTYPES   (sizeof(g_rgdwCallTypes) / sizeof(DWORD))


//
// Line status values
//
static const DWORD g_rgdwLineStats[] =
{
    RIL_LINESTAT_READY,             // 0
    RIL_LINESTAT_UNAVAILABLE,       // 1
    RIL_LINESTAT_UNKNOWN,           // 2
    RIL_LINESTAT_RINGING,           // 3
    RIL_LINESTAT_CALLINPROGRESS,    // 4
    RIL_LINESTAT_ASLEEP,            // 5
};
#define NUM_LINESTATS   (sizeof(g_rgdwLineStats) / sizeof(DWORD))

// Defines an arbitrary maximum string length for the dial command.
// This maximum is not strictly enforced. It is used only as an aid
// for reporting a more specific error (RIL_E_DIALSTRINGTOOLONG) if
// the radio returns an error that is too generic.
#define MAX_DIAL_STRING_LENGTH      43

BOOL g_rgfCallsInProgress[RIL_MAX_TRACKED_CALL_ID] = { FALSE };   // Initialize to FALSE
RILCALLINFO g_rgfCallStates[RIL_MAX_TRACKED_CALL_ID];

extern BOOL g_rfExternalCalltypeDetermination;

BOOL g_rgfCalltypeChecked[RIL_MAX_TRACKED_CALL_ID] = { FALSE };   // Initialize to FALSE
DWORD g_rgctCalltype[RIL_MAX_TRACKED_CALL_ID] = { 0 };   // Initialize to 0

DIALEDCALLDATA g_rcdDialedCallData;
extern CRITICAL_SECTION g_csDialedCallData;

extern RINGINGCALLDATA g_rcdRingingCallData;
extern CRITICAL_SECTION g_csRingingCallData;

//added by viking wang
#define MAX_NUMBERCALLS 5
RILCALLINFO g_CallInfo[MAX_NUMBERCALLS];
INT g_iNrCallInfo = -1;
CRITICAL_SECTION g_CallInfoSection;
BOOL g_fCallWaiting = FALSE;


#ifdef EMP_DRIVER
// Define a global call type for call dialing, answering and hanging up
DWORD g_dwCallType = RIL_CALLTYPE_UNKNOWN;
#endif

BOOL IsACallActive();

VOID SetCalltypeFromCallInfo(RILCALLINFO *prci);

// BOOL g_rgfFirstParseCLCC;  // use only if g_rgfPreviousCallsInProgress and g_rgfPreviousCallStates are to be added

//
//
//

BOOL IsACallActive()
{
    BOOL bCallActive = FALSE;
#if 0
    if (g_iNrCallInfo > 0) {
        EnterCriticalSection(&g_CallInfoSection);
        if (g_iNrCallInfo > 0) {
            INT i;

            for (i=0; i<g_iNrCallInfo; i++) {
                if (g_CallInfo[i].dwStatus==RIL_CALLSTAT_ACTIVE) {
                    bCallActive = TRUE;
                    break;
                }
            }
        }
        LeaveCriticalSection(&g_CallInfoSection);
    }
#else
	for (char i = 0; i < RIL_MAX_TRACKED_CALL_ID; i++)
    {
    	if (g_rgfCallsInProgress[i])
        {
        	if ( (g_rgfCallStates[i].dwStatus == RIL_CALLSTAT_ACTIVE) 
			)
            {
           		bCallActive = TRUE; 	
            	break;
            }
        }
    }
#endif 
    return bCallActive;
}



HRESULT RILDrv_Dial(DWORD dwParam, LPCSTR szAddress, DWORD dwType, DWORD dwOptions)
{
    FUNCTION_TRACE(RILDrv_Dial);
#if defined (NODIALING) && !defined (SHIP_BUILD)
    bool fNoDialing;
    bool fNoEmergencyDialing;
#endif // NODIALING

    CNotificationData* pnd = NULL;
    RILCONNECTINFO rci; memset(&rci,0,sizeof(rci)); // zero struct
    char szCmd[MAX_PATH];
    LPSTR szWalk = szCmd;
    LPSTR szDialStringStart = NULL;
    HRESULT hr = S_OK;
    LPCSTR szAddrWalk;
    DWORD dwDialOpts = CMDOPT_DIAL|CMDOPT_RETRYONSIMLOCKED;

	DEBUGMSG(ZONE_ERROR, (TEXT("+RILDrv : E : RILDrv_Dial : \r\n")));
    CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
    if (!pHandle || !szAddress) {
        hr = E_FAIL;
        goto Error;
    }

#if defined (NODIALING) && !defined (SHIP_BUILD)
    // See if we want to disable dialing
    if (GetRegistryBoolean(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("NoDialing"), &fNoDialing) && fNoDialing) {
        // We can't allow any dialing (for stress tests)
#ifndef SHIP_BUILD
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RILDrv_Dial : Dialing is prevented: %s\r\n"), TString(szAddress)));
#endif // !SHIP_BUILD
        hr = E_FAIL;
        goto Error;
    }

    // See if we want to disable emergency dialing
    if (GetRegistryBoolean(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("NoEmergencyDialing"), &fNoEmergencyDialing) &&
        fNoEmergencyDialing) {
        if (!strcmp(szAddress, "911") || !strcmp(szAddress, "112") || !strcmp(szAddress, "08")) {
            // We can't allow dialing of emergency numbers (for stress tests)
#ifndef SHIP_BUILD
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RILDrv_Dial : Dialing of an emergency number is prevented: %s\r\n"), TString(szAddress)));
#endif // !SHIP_BUILD
            hr = E_FAIL;
            goto Error;
        }
    }
#endif // NODIALING

    szWalk = BeginLineSpecificCommand(szCmd, MAX_PATH, 0);

#ifdef EMP_DRIVER
    // Write down current call type
    g_dwCallType = dwType;
#endif

    switch (dwType)
    {
        case RIL_CALLTYPE_VOICE:
        case RIL_CALLTYPE_PTT:
            pnd = new CNotificationData;
            if (pnd) {
                rci.cbSize = sizeof(RILCONNECTINFO);
                rci.dwParams = RIL_PARAM_CNI_CALLTYPE;
                rci.dwCallType = dwType;
                if (!pnd->InitFromRealBlob(RIL_NOTIFY_CONNECT, &rci, sizeof(RILCONNECTINFO))) {
                    delete pnd;
                    pnd = NULL;
                }
            }
            // fall through
            //added by viking wang
			 if (IsACallActive())
            {
                // Depending on the SIM card it may be necessary to put the active call
                // on hold manually before initiating the new one.
                strncpyz(szWalk,"+CHLD=2;",MAX_ATCMD_LEN - (szWalk - szCmd));
                szWalk = strchr(szWalk, '\0');
            }
        case RIL_CALLTYPE_DATA:
            strncpyz(szWalk,"D",MAX_PATH - (szWalk - szCmd));
            break;

        case RIL_CALLTYPE_VT:
#ifdef EMP_DRIVER
            // EMP uses "AT*EVD="<number>"\r" to place a VT call
            // Note that <number> is a quoted string
            strncpyz(szWalk,"*EVD=\"",MAX_PATH - (szWalk - szCmd));
            break ;
#else
            // VT is not supported on other platforms
            hr = E_NOTIMPL;
            goto Error;
#endif

        case RIL_CALLTYPE_FAX:
#ifdef EMP_DRIVER
            // EMP does not support FAX
            hr = E_NOTIMPL;
            goto Error;
#else
            (void)strncpyz(szWalk, "+FCLASS+1;D", MAX_PATH - (szWalk - szCmd));
#endif
            break;

        default:
            // This should have been caught in the proxy
            DEBUGCHK(FALSE);

        case RIL_CALLTYPE_UNKNOWN:
            hr = E_INVALIDARG;
            goto Error;
    }

    szWalk = strchr(szWalk, '\0');  // NO_TYPO: 27
    DEBUGCHK(NULL != szWalk);

    szDialStringStart = szWalk;

    // Copy the number in
    szAddrWalk = szAddress;
    const char * const pcszCmdEnd = &szCmd[ ARRAY_LENGTH(szCmd)-1 ];
    while( szWalk < pcszCmdEnd && *szAddrWalk != '\0' )
    {
        // Only allow characters in the set specified by GSM 07.07 section 6.2
        if (strchr("1234567890*#+ABCD,TP!W@",*szAddrWalk))
        {
            *szWalk++ = *szAddrWalk;
        }
        szAddrWalk++;
    }

    // If the dial string is really long, make a note in case the
    // command fails with a generic error. We can then guess that
    // the real error is that the dial string was too long.
    if ((szWalk - szDialStringStart) > MAX_DIAL_STRING_LENGTH)
    {
        dwDialOpts |= CMDOPT_LONGDIALSTRING;
    }

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

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

#if (!defined(WAVECOM_DRIVER) && !defined(EMP_DRIVER) && !defined(PHILIP_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 && EMP_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++;
    }

#ifdef EMP_DRIVER
    // For EMP "I" and "i" should always go before "G"
    if (dwOptions & RIL_DIALOPT_CLOSEDGROUP)
    {
        (void)strncpyz(szWalk, "G", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }
    // VT <number> is a quoted string on EMP platform
    if (g_dwCallType==RIL_CALLTYPE_VT)
    {
        (void)strncpyz(szWalk, "\"", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }
#endif // EMP_DRIVER

    // 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 defined(PHILIP_DRIVER)
#if 0

    BOOL fWaveDevSet = FALSE;
    DWORD dwRet;
    if ((dwType==RIL_CALLTYPE_VOICE)||(dwType==RIL_CALLTYPE_PTT))
    {
        //signal audio driver that at least one call is active
		if(RILDrv_OpenMyWav())
		{
	        if (DeviceIoControl (g_hWavDev, IOCTL_GSM_CALL_ACTIVE, 0, 0, NULL, 0, &dwRet, NULL))
	        {
	        	fWaveDevSet = TRUE;
	        }		
		}
    }
#else
    if ((dwType==RIL_CALLTYPE_VOICE)||(dwType==RIL_CALLTYPE_PTT))
    {
        // Indicate call is Active
        IndicateCallActivityToAudioSubsystem(TRUE, FALSE);
    }

#endif
    Sleep(1500);
    if (!QueueCmd(pHandle, szCmd, dwDialOpts, APIID_DIAL, NULL, pnd, hr)) {
        hr = E_FAIL;
        goto Error;
    }
    pnd = NULL;

Error:
//#if defined(PHILIP_DRIVER)
#if 0

    if ((E_FAIL == hr) && (TRUE == fWaveDevSet))

⌨️ 快捷键说明

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