📄 callctrl.cpp
字号:
/*++
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 + -