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

📄 callctrl.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
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.

Module Name:

callctrl.cpp

Abstract:


Notes:


--*/


#include "precomp.h"
#include <rilbacklight.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))

//
// Call type values
//
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
};
const UINT 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

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;

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

VOID SetCalltypeFromCallInfo(RILCALLINFO *prci);

RILCALLINFO g_rgfCallStates[RIL_MAX_TRACKED_CALL_ID] = { 0 };
DWORD g_dwNumCallsInCallList = 0;

extern CRilHandle* g_pRilHandleDevice;

//
//
//
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;
    const char *szDialStringStart = NULL;
    HRESULT hr = S_OK;
    LPCSTR szAddrWalk;
    DWORD dwDialOpts = CMDOPT_DIAL|CMDOPT_RETRYONSIMLOCKED;

    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);

    //  Remember the current call type.
    g_dwCallType = dwType;

    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;
                }
            }
            __fallthrough;

        case RIL_CALLTYPE_DATA:
            strncpyz(szWalk,"D",MAX_PATH - (szWalk - szCmd));
            break;

        case RIL_CALLTYPE_VT:
            //  Currently VT is not supported.
            hr = E_NOTIMPL;
            goto Error;

        case RIL_CALLTYPE_FAX:
            (void)strncpyz(szWalk, "+FCLASS+1;D", MAX_PATH - (szWalk - szCmd));
            break;

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

        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 (dwOptions & RIL_DIALOPT_CLOSEDGROUP) {
        (void)strncpyz(szWalk, "G", MAX_PATH - (szWalk - szCmd));
        szWalk++;
    }

    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 ((dwType==RIL_CALLTYPE_VOICE)||(dwType==RIL_CALLTYPE_PTT))
    {
        // Indicate call is active to audio driver
        IndicateCallActivityToAudioSubsystem(TRUE, FALSE);
    }

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

Error:
    if ( E_FAIL == hr )
    {
        // Indicate call is inactive to audio driver only if call list is empty
        IndicateCallActivityToAudioSubsystem(FALSE, TRUE);
    }

    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 = g_dwCallType;

        // 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;
        }
    }

    // Indicate call is active to audio driver
    IndicateCallActivityToAudioSubsystem(TRUE, FALSE);

    if ( RIL_CALLTYPE_VT == g_dwCallType )
        {
        //  Currently VT is not supported.
        delete pnd;
        pnd = NULL;
        hr = E_FAIL;
        goto Error;
        }
    else if (!QueueCmd(pHandle, "ATA\r", CMDOPT_ANSWER, APIID_ANSWER, NULL, pnd, hr)) {
        hr = E_FAIL;
        goto Error;
    }
    pnd = NULL;

Error:
    if (E_FAIL == hr) 
    {
        // Indicate call is inactive to audio driver only if call list is empty
        IndicateCallActivityToAudioSubsystem(FALSE, TRUE);
    }

    if ( RIL_CALLTYPE_VT == g_dwCallType )
        {
        //  Currently VT is not supported.
        hr = E_NOTIMPL;
        }

    return hr;
}


//
//
//
HRESULT RILDrv_Hangup(DWORD dwParam)
{
    FUNCTION_TRACE(RILDrv_Hangup);
    CNotificationData* pnd = NULL;
    BOOL fSuccess;
    HRESULT hr = S_OK;
    CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
    if (!pHandle) {
        hr = E_FAIL;
        goto Error;
    }

    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);
        }
        if (!fSuccess) {
            delete pnd;

⌨️ 快捷键说明

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