📄 enfora.cpp
字号:
HRESULT PDD_CreateCommand_GetPostRebootDiagnostics(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd)
{
// HW specific OEM1 uses %DAR to query the cause of the last radio crash. We want this in the radio log or watson report
return StringCchCopyA( szCmd, cchCmd, "AT%DAR\r" );
}
static HRESULT ParseDAR(LPCSTR szRsp, void*& pBlob, UINT& cbBlob)
{
#if RIL_WATSON_REPORT
g_fWatsonCalled = FALSE;
SignalCriticalError(RILLOG_EVENT_RADIOFAILUREREASON, __LINE__, __FILE__);
#endif // RIL_WATSON_REPORT
return S_OK;
}
HRESULT
PDD_CreateCommand_GetNITZSupported(
__out_ecount(cchCmd) LPSTR szCmd,
__in size_t cchCmd
)
{
return StringCchCopyA( szCmd, cchCmd, "AT%CTZV?\r" );
}
HRESULT PDD_GetResponseObject(__out CResponse*& pNewRsp, __in const CResponse* pSrcRsp)
{
if (NULL == pSrcRsp) {
pNewRsp = new CResponseTI;
}
else {
pNewRsp = new CResponseTI(*(static_cast<const CResponseTI*>(pSrcRsp)));
}
return (pNewRsp ? S_OK : E_OUTOFMEMORY);
}
HRESULT PDD_Initialize(__out const RILPDDParams*& prppRILPDDParams)
{
InitializeCriticalSection(&g_csGPRSDeactLock);
prppRILPDDParams = &rppTIPDDParams;
return S_OK;
}
HRESULT PDD_Deinitialize()
{
DeleteCriticalSection(&g_csGPRSDeactLock);
return S_OK;
}
HRESULT PDD_CreateCommand_ChangeLockingPassword(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const DWORD dwFacility, __in LPCSTR lpszOldPassword, __in LPCSTR lpszNewPassword)
{
// This hardware uses ATD to get the desired functionality
return StringCchPrintfA( szCmd, cchCmd, "ATD**05%s*%s*%s*%s#\r", ((RIL_LOCKFACILITY_SIM_PIN2 == dwFacility) ? "2" : ""), lpszOldPassword, lpszNewPassword, lpszNewPassword );
}
HRESULT PDD_SetDownlinkVolume(__in const DWORD dwDownlinkVolume)
{
g_dwCacheDownlinkVolume = dwDownlinkVolume;
return S_OK;
}
HRESULT PDD_GetDownlinkVolume(__in const bool fNormalized, __out UINT& uiDownlinkVolume)
{
if (fNormalized)
{
uiDownlinkVolume = g_dwCacheDownlinkVolume / DOWNLINK_V0LUME_NORMALIZE;
}
else
{
uiDownlinkVolume = g_dwCacheDownlinkVolume;
}
return S_OK;
}
HRESULT PDD_SetUplinkVolume(__in const DWORD dwUplinkVolume)
{
g_dwCacheUplinkVolume = dwUplinkVolume;
return S_OK;
}
HRESULT PDD_GetUplinkVolume(__out UINT& uiUplinkVolume)
{
uiUplinkVolume = g_dwCacheUplinkVolume;
return S_OK;
}
BOOL CResponseTI::ParseCallProgressInformation(LPCSTR& rszPointer)
{
RILCALLINFO rci;
LPCSTR szDummy;
UINT nCid, nMsgType, nIbt, nTch, nDir, nMode, nType, nReason, nLine;
char szAddress[MAXLENGTH_ADDRESS];
BOOL fRet = FALSE, fHaveAddress = FALSE;
// Default values for our processing status. If we recognize the correct status below, we will change these two state.
m_fUnrecognized = TRUE;
m_fUnsolicited = TRUE;
// Parse "<cId>,<msgType>,<ibt>,<tch>"
if (!FindRspPostfix(rszPointer, szDummy) ||
!ParseUInt(rszPointer, FALSE, nCid, rszPointer) ||
!MatchStringBeginning(rszPointer, ",", rszPointer) ||
!ParseUIntAndVerifyAbove(rszPointer, FALSE, LAST_CPI_ID, nMsgType, rszPointer) ||
!MatchStringBeginning(rszPointer, ",", rszPointer) ||
!ParseUInt(rszPointer, FALSE, nIbt, rszPointer) ||
!MatchStringBeginning(rszPointer, ",", rszPointer) ||
!ParseUInt(rszPointer, FALSE, nTch, rszPointer))
{
goto Error;
}
// Throw away any unrecognized notificaitons
if (nMsgType >= LAST_CPI_ID)
{
m_fUnrecognized = TRUE;
fRet = TRUE;
goto Error;
}
memset(&rci, 0x00, sizeof(RILCALLINFO));
rci.cbSize = sizeof(RILCALLINFO);
rci.raAddress.cbSize = sizeof(RILADDRESS);
// default status set to RIL_CPISTAT_UNKNOWN by above memset
// Set <cId>
rci.dwID = nCid;
rci.dwParams |= RIL_PARAM_CI_ID;
// <ibt> (in-band tones) is ignored
// <tch> (TCH assignment) is used to reject premature disconnect messages (see below)
// remaining parameters are all optional with commas used to separate vars even if not
// present. So if a "," is followed immediately by another "," the var is missing
// ",[<dir>],[<mode>],[<number>],[<type>],[<alpha>],[<cause>],[<line>]" is optionally present
// Parse "," and look for <dir>
if(MatchStringBeginning(rszPointer, ",", rszPointer)) // get the first comma - if not there then we are done
{
// ignore error - if value not found we just skip and look fo the next comma
ParseUInt(rszPointer, FALSE, nDir, rszPointer);
}
// Parse "," and look for <mode>
if(MatchStringBeginning(rszPointer, ",", rszPointer))
{
nMode = 0;
ParseUInt(rszPointer, NUM_CALLTYPES, nMode, rszPointer);
if(nMode > NUM_CALLTYPES)
goto Error;
}
// Set <dir>
rci.dwDirection = nDir ? RIL_CALLDIR_INCOMING : RIL_CALLDIR_OUTGOING;
rci.dwParams |= RIL_PARAM_CI_DIRECTION;
// celltsp requirements:
//
// - there cannot be more than one RIL_CPISTAT_xxx notification of the same type for the same call
// - a RIL_CPISTAT_xxx notification should be sent only after a call is in true xxx state
// (eg. RIL_CPISTAT_DISCONNECTED is sent up when we receieve TI_CPISTAT_RELEASE because that is
// when the call is actually released. If an attempt to dial is made before getting TI_CPISTAT_RELEASE,
// the call could fail. We do capture the disconnect code when we receive TI_CPISTAT_DISCONNECTED
// so that it can be used when we send up RIL_CPISTAT_DISCONNECTED later on)
// - RIL_NOTIFY_CALLPROGRESSINFO can be one of:
// RIL_CPISTAT_UNKNOWN - celltsp ignores this
// RIL_CPISTAT_NEW_OUTGOING - required by celltsp for MO calls to learn RIL call id
// RIL_CPISTAT_NEW_INCOMING - required by celltsp for MT calls to learn RIL call id
// RIL_CPISTAT_CONNECTED - required by celltsp when a call goes into a true connected state
// RIL_CPISTAT_DISCONNECTED - required by celltsp when a call goes into a true disconnected state
// RIL_CPISTAT_ONHOLD - required by celltsp when a call goes into a true hold state
//
// celltsp RIL message sequence (only showing radio and corresponding RIL notifications):
//
// - MO successful setup
// TI_CPISTAT_CALLPROCEED -> RIL_CPISTAT_NEW_OUTGOING (with RIL call id)
// TI_CPISTAT_SYNCH -> (ignored)
// TI_CPISTAT_ALERT -> (ignored)
// TI_CPISTAT_CONNECTED -> RIL_CPISTAT_CONNECTED
// - MO failed setup
// TI_CPISTAT_CALLPROCEED -> RIL_CPISTAT_NEW_OUTGOING (with RIL call id)
// TI_CPISTAT_SYNCH -> (ignored)
// TI_CPISTAT_ALERT -> (ignored)
// TI_CPISTAT_DISCONNECT -> (cache disconnect code)
// TI_CPISTAT_RELEASE -> RIL_CPISTAT_DISCONNECTED (with cached disconnect code)
// - MT successful setup
// TI_CPISTAT_SETUP -> (ignored)
// V.25 code 2 (ring notification) -> RIL_NOTIFY_RING
// TI_CPISTAT_SYNCH -> RIL_CPISTAT_NEW_INCOMING (with RIL call id)
// TI_CPISTAT_CONNECTED -> RIL_CPISTAT_CONNECTED
// - MT successful setup during active call (call waiting)
// TI_CPISTAT_SETUP -> (ignored)
// CCWA notification -> RIL_NOTIFY_CALLWAITING
// (RIL call id learned by CLCC request/response)
// TI_CPISTAT_CONNECTED -> RIL_CPISTAT_CONNECTED
// - Call teardown
// TI_CPISTAT_DISCONNECT -> (cache disconnect code)
// TI_CPISTAT_RELEASE -> RIL_CPISTAT_DISCONNECTED (with cached disconnect code)
/*
By default, we don't set the RIL_PARAM_CI_CPISTATUS bit. It is set for states that celltsp will recognize. The global call
state list must be udpated.
*/
switch ( nMsgType )
{
case TI_CPISTAT_CALLPROCEED:
rci.dwStatus = RIL_CPISTAT_NEW_OUTGOING;
rci.dwParams |= RIL_PARAM_CI_CPISTATUS;
EnterCriticalSection(&g_csCallStates);
g_rgfCallStates[ rci.dwID ].dwDisconnectCode = 0; // Remove any stale disconnect data.
g_rgfCallStates[ rci.dwID ].dwParams &= ~RIL_PARAM_CI_DISCONNECTCODE;
LeaveCriticalSection(&g_csCallStates);
break;
case TI_CPISTAT_SYNCH:
if ( RIL_CALLDIR_INCOMING == rci.dwDirection )
{
rci.dwStatus = RIL_CPISTAT_NEW_INCOMING;
rci.dwParams |= RIL_PARAM_CI_CPISTATUS;
EnterCriticalSection(&g_csCallStates);
g_rgfCallStates[ rci.dwID ].dwDisconnectCode = 0; // Remove any stale disconnect data.
g_rgfCallStates[ rci.dwID ].dwParams &= ~RIL_PARAM_CI_DISCONNECTCODE;
LeaveCriticalSection(&g_csCallStates);
}
break;
case TI_CPISTAT_CONNECTED:
rci.dwStatus = RIL_CPISTAT_CONNECTED;
rci.dwParams |= RIL_PARAM_CI_CPISTATUS;
break;
case TI_CPISTAT_RELEASE:
case TI_CPISTAT_REJECT:
rci.dwStatus = RIL_CPISTAT_DISCONNECTED;
rci.dwParams |= RIL_PARAM_CI_CPISTATUS;
if ( g_rgfCallStates[ rci.dwID ].dwDisconnectCode ) // see if a disconnect code has been cached prior to this
{
rci.dwDisconnectCode = g_rgfCallStates[ rci.dwID ].dwDisconnectCode; // copy over the cached value into this rci struct
rci.dwParams |= RIL_PARAM_CI_DISCONNECTCODE;
}
break;
case TI_CPISTAT_DISCONNECTED:
// Don't set the RIL_PARAM_CI_CPISTATUS because we have to wait for the RELEASE or REJECT. Do reflect that we have
// a disconnect code so that we can copy it to our global structure later on.
// set a default disconnect code. This is used when we disconnect locally
rci.dwDisconnectCode = RIL_RESULT_CALLABORTED;
rci.dwParams |= RIL_PARAM_CI_DISCONNECTCODE;
break;
case TI_CPISTAT_ALERT:
case TI_CPISTAT_SETUP:
case TI_CPISTAT_PROGRESS:
case TI_CPISTAT_MOSETUP:
default:
break;
}
// Set <mode>
rci.dwType = g_rgdwCallTypes[nMode];
rci.dwParams |= RIL_PARAM_CI_TYPE;
// Parse "," and look for <address>
if (MatchStringBeginning(rszPointer, ",", rszPointer))
{
if(ParseString(rszPointer, szAddress, MAXLENGTH_ADDRESS, rszPointer))
fHaveAddress = TRUE;
}
// Parse "," and look for <type>
if (MatchStringBeginning(rszPointer, ",", rszPointer))
{
nType = 0;
if(ParseUInt(rszPointer, FALSE, nType, rszPointer))
{
if(( nType < 0x100) && fHaveAddress)
{
if(StringToRILAddress(szAddress, (BYTE)nType, rci.raAddress))
{
rci.dwParams |= RIL_PARAM_CI_ADDRESS;
DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Parse CPI: found address and type \r\n")));
}
else
goto Error;
}
}
}
// Parse "," and look for <alpha>
#ifdef ALPHA_IN_CPI
if (MatchStringBeginning(rszPointer, ",", rszPointer))
{
if(ParseQuotedEncodedString(g_rppPDDParams->etEncodingTECharset, rszPointer, rci.wszDescription, rci.wszDescription + MAXLENGTH_DESCRIPTION))
{
rci.dwParams |= RIL_PARAM_CI_DESCRIPTION;
}
}
#endif
// Parse "," and look for the disconnect reason for extended CPI notifications
if (MatchStringBeginning(rszPointer, ",", rszPointer))
{
if(ParseUInt(rszPointer, FALSE, nReason, rszPointer))
{
DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Parse CPI: got reason code %d\r\n"), nReason));
if(TI_CPISTAT_DISCONNECTED == nMsgType)
{
// numeric codes below are from GSM 3G TS 24.008 Annex H
// for now we only process busy
if(17 == nReason)
{
rci.dwDisconnectCode = RIL_RESULT_BUSY;
rci.dwParams |= RIL_PARAM_CI_DISCONNECTCODE;
}
else if(16 != nReason)
{
rci.dwDisconnectCode = RIL_RESULT_NOCARRIER; // add reject code
rci.dwParams |= RIL_PARAM_CI_DISCONNECTCODE;
}
DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Parse CPI: disconnect code %d\r\n"), rci.dwDisconnectCode));
}
}
}
// Parse "," and look for <line>
if (MatchStringBeginning(rszPointer, ",", rszPointer))
{
if(!ParseUInt(rszPointer, FALSE, nLine, rszPointer))
goto Error;
}
if (g_rfExternalCalltypeDetermination)
{
SetCalltypeFromCallInfo(&rci);
}
// add the call to the callstates array
DEBUGCHK((0 <= rci.dwID) && (rci.dwID < RIL_MAX_TRACKED_CALL_ID)); // Otherwise, it may be necessary to increase MAX_TRACKED_CALLS
// The global list is updated if we have either a recognized status or we have collected a disconnect.
if ( (rci.dwParams & RIL_PARAM_CI_CPISTATUS) || (rci.dwParams & RIL_PARAM_CI_DISCONNECTCODE))
{
EnterCriticalSection(&g_csCallStates);
g_rgfCallStates[rci.dwID] = rci;
LeaveCriticalSection(&g_csCallStates);
// Indicate call is inactive to audio driver only if call list is empty
IndicateCallActivityToAudioSubsystem (FALSE, TRUE);
if ( rci.dwParams & RIL_PARAM_CI_CPISTATUS )
{
DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Parse CPI: sending notification type %d\r\n"), nMsgType));
m_fUnsolicited = TRUE;
m_fUnrecognized = FALSE;
m_dwCode = RIL_NOTIFY_CALLPROGRESSINFO;
if (!SetBlob((void*)&rci, sizeof(RILCALLINFO)))
goto Error;
// Special case. If we are establishing a new call and one is already active, query CLCC to see it it is held.
if ( RIL_CPISTAT_NEW_OUTGOING == rci.dwStatus)
{
for (uint GlobalCallStateIndex = 1 /* first valid call ID */; GlobalCallStateIndex < RIL_MAX_TRACKED_CALL_ID; GlobalCallStateIndex++ )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -