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