📄 ttpcom.cpp
字号:
//
// 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.
//
#include <ttpcom.h>
// Phonebook storage locations - NEEDS to be SORTED
static const LISTSTRINGMAP g_rglsmCapsPBLocations[] =
{
{ "EN", RIL_CAPS_PBLOC_SIMEMERGENCY },
{ "FD", RIL_CAPS_PBLOC_SIMFIXDIALING },
{ "LD", RIL_CAPS_PBLOC_SIMLASTDIALING },
{ "ON", RIL_CAPS_PBLOC_OWNNUMBERS },
{ "SM", RIL_CAPS_PBLOC_SIMPHONEBOOK }, // Used by OEM2 and Wavecom
};
// Phonebook storage locations - does NOT NEED to be SORTED
static const LPCSTR g_rgszPBLocations[] =
{
"", // RIL_PBLOC_UNKNOWN
"EN", // RIL_PBLOC_SIMEMERGENCY
"FD", // RIL_PBLOC_SIMFIXDIALING
"LD", // RIL_PBLOC_SIMLASTDIALING
"ON", // RIL_PBLOC_OWNNUMBERS
"SM", // RIL_PBLOC_SIMPHONEBOOK (Used by OEM2 and Wavecom)
};
// Reboot the radio
#define IOCTL_TTPCOM_REBOOT CTL_CODE( FILE_DEVICE_SERIAL_PORT, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
static const ERRORMAP g_rgemCMSErrors[] =
{
{ RIL_E_PHONEFAILURE, 500},
{ RIL_E_MESSAGINGERROR, 516},
{ RIL_E_MESSAGINGERROR, 517},
};
// RIL registry key
const LPCTSTR g_tszRegKeyRIL = TEXT("Software\\Microsoft\\RIL");
// HW-SPECIFIC: The following init commands are hardware-specific
// NOTES: Z resets the AT interface
// S0=0 disables auto-answer
// E0 disables command echo
// Q0 enable result codes
// V0 enable non-verbose responses
// X4 enable busy signal detection and additional info in CONNECT response
// &C1 enables DCD to be used for carrier detection
// &D1 enables DTR to be used for dropping out of data mode
// +CMEE=1 enables +CME ERROR and +CMS ERROR responses
// +CFUN=0,2 ensures radio is off and radio will not power on at module power on (OEM2 only)
// +CRC=1 enables +CRING notifications
// +CR=1 enables +CR notifications
// +CMOD=0 enables single call mode
// +CREG=1 enables short +CREG notifications
// +CREG=2 enables extended +CREG notifications (w/ <lac> and <ci>)
// +FCLASS=0 enables data mode
// +CSSN=0,1 enables +CSSU notifications
// +CHSR=1 enables +CHSR notifications
// +COLP=1 enables +COLP notifications
// +CCWA=1 enables +CCWA notifications
// +CMGF=0 enables SMS PDU mode
// +CNMI=2,2,2,1,0 enables +CMT, +CBM, and +CDS notifications
// +CSCS="8859-1" sets default alphabet to ISO 8859-1
// +STRT=240",1 (OEM2 only) set the SIM toolkit command timeout in seconds. Currently this is set to match the SIMTK internal timeout
// +EXUNSOL="SQ",1 enables unsolicited signal quality notifications (0 = disable, 1 = enable, 2 = query) (OEM2 only)
// +EXUNSOL="BC",1 enables unsolicited battery notifications (0 = disable, 1 = enable, 2 = query) (OEM2 only)
// +EXUNSOL="UR",1 enables unsolicited call progress notifications (0 = disable, 1 = enable, 2 = query) (OEM2 only)
// only supports two init levels below:
// COM_INIT_INDEX - index 0
// COM_REINIT_INDEX - index 1
const INITSTRING_DATA g_rgisdModuleInit[] =
{
// OEM2 init commands
{ "+CFUN=0,2|Z;S0=0;E0;Q0;V0|X3;&C1;&D1;+CMEE=1;+CRC=1;+CR=1;+CMOD=0;+CREG=1;"
"+FCLASS=0;+CSSN=0,1;+COLP=0;+CCWA=1;+CSCS=\"UCS2\";+CMGF=0|+CGREG=1|+CUSD=1|+CMUT=0|"
"+STRT=240|+EXUNSOL=\"SQ\",1|+EXUNSOL=\"BC\",1|+EXUNSOL=\"UR\",1|", CMDOPT_INIT | CMDOPT_GENERALINIT},
{ "E0|+CMUT=0|", CMDOPT_INIT | CMDOPT_GENERALINIT},
};
HANDLE g_hCPINNEvent = NULL;
// This driver doesn't have a way to query current
// uplink and downlink volume, so we have to cache them.
DWORD g_dwCacheUplinkVolume;
DWORD g_dwCacheDownlinkVolume;
// PDD parameter table
const RILPDDParams rppTTPCOMPDDParams = {
sizeof(rppTTPCOMPDDParams), // cbSize
false, // fRadioSignonRequired
false, // fIgnoreUnsolicitedNoCarrier
NULL, // pfnParseGetCurrentAddressId
NULL, // pfnParseATRInfo
g_rglsmCapsPBLocations, // plsmPhoneBookLocationCapsTable
sizeof(g_rglsmCapsPBLocations) / sizeof(LISTSTRINGMAP), // uiPhoneBookLocationCapsTableSize
RIL_SIMTKN_RADIOIMPLEMENTS_NOTIFICATION, // dwDevCapsSIMTKN_SetUpCall
RIL_SIMTKN_RADIOIMPLEMENTS_REQUESTMEINPUT, // dwDevCapsSIMTKN_SendDTMF
true, // fNotificationPortSupported
RIL_SIMCMD_STATUS, // dwCRSMStatusCommandId
15, // RestrictedSimAccessSetCmdParam3 (3GPP TS 27.007 V6.8.0 (2005-03) sec. 8.18 Restricted SIM access +CRSM)
false, // fGPRSQoSEmptyParameterListAllowed
g_rgszPBLocations, // pstrPhoneBookLocationTable
sizeof(g_rgszPBLocations) / sizeof(LPCSTR), // uiPhoneBookLocationTableSize
true, // fIsRadioOffInMinimumPowerState
true, // fDontTurnRadioOnIfAlreadyOn
false, // fSendSimCmdSupported
true, // fCRSMResponseQuoted
NULL, // pfnParseGetSimToolkitProfile
NULL, // pfnParseSendSimToolkitEnvelopeCmd
false, // fPowerManagementSupported
NULL, // pfnParseBuildInfo
NULL, // pfnParseBatteryInfo
ENCODING_GSMDEFAULT_UNICODE, // etMessageEncodingType
NULL, // pfnParsePostRebootDiagnostics
500, // dwPostRebootInitDelay
NULL, // pemCMEErrorTable
0, // uiCMEErrorTableSize
g_rgemCMSErrors, // pemCMSErrorTable
sizeof(g_rgemCMSErrors) / sizeof(ERRORMAP), // uiCMSErrorTableSize
NULL, // pemEXTErrorTable
0, // uiEXTErrorTableSize
"\r\n> ", // pchSMSIntermediaryPrompt
false, // fIgnoreDeniedNotificationsUntilUnlock
true, // fRequireWaitingForSMSReady
true, // fRequireWaitingForSIMPhoneBookReady
false, // fExplicitRadioReadyNotification
true, // fSIMToolkit_SupportsTextNotifications
true, // fSIMToolkit_SupportsTextFormat
true, // fByteArrayIsQuoted
false, // fSetAudioDevicesSupported
DEFAULT_COM_MASK, // dwDefaultCOMMask
ENCODING_TECHARSET, // etEncodingTECharset
true, // fSendRegStatusChangedAfterEveryReadyStateNotification
false, // fSignalQualityActualLevelSupported
g_rgisdModuleInit, // pisdInitStringDataTable
sizeof(g_rgisdModuleInit) / sizeof(INITSTRING_DATA), // uiInitStringDataTableSize
NULL, // pfnParseGetNITZSupported
};
//Check if this is a SIM PIN notification : SIM PIN (PIN2, PUK2, PIN, PUK)
HRESULT PDD_IsSIMPINNotification(__in const void* rpBlob, __in const UINT rcbBlob, __in const DWORD dwCode, __out bool& fIsSIMPIN)
{
HRESULT hr = E_FAIL;
fIsSIMPIN = false;
if( rpBlob != NULL && rcbBlob == sizeof(HRESULT) )
{
if ( dwCode == RIL_RESULT_ERROR )
{
if((RIL_E_SIMPIN2REQUIRED ==*(HRESULT*)rpBlob) ||(RIL_E_SIMPUK2REQUIRED == *(HRESULT*)rpBlob)
||(RIL_E_SIMPINREQUIRED == *(HRESULT*)rpBlob) ||(RIL_E_SIMPUKREQUIRED == *(HRESULT*)rpBlob))
fIsSIMPIN = true;
}
else if ( dwCode == RIL_RESULT_OK )
{
fIsSIMPIN = ( S_OK == *(HRESULT*)rpBlob );
}
}
else
{
hr = E_INVALIDARG;
goto Error;
}
hr = S_OK;
Error:
return hr;
}
// Given the current command and it's response, should the response be queued
HRESULT PDD_QueueResponse(__in CCommand* pCurrCommand, __inout CResponse* pRsp, __out bool& fQueueResponse)
{
// For this radio, queue response always
fQueueResponse = true;
return S_OK;
}
// Create a AT command string to send the required DTMF tones
// pdwDuration and pNumVals are OUT parameters that are then used to calculate the command timeout period
HRESULT PDD_CreateCommand_SendDTMF(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in LPCSTR lpszChars, __out DWORD& dwDuration, __out UINT& uiNumVals)
{
UINT nValue = 0;
LPSTR szWalk = szCmd;
HRESULT hr = E_FAIL;
if ((dwDuration < 300) || (dwDuration == RIL_DTMFDURATION_DEFAULT))
{
dwDuration = 300;
}
nValue = (dwDuration + 50 ) / 100;
hr = StringCchPrintfA( szWalk, cchCmd, "AT+VTD=%u;", nValue );
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : PDD_CreateCommand_SendDTMF : error in StringCchPrintfA, hr = [0x%08x]\r\n"), hr));
goto Error;
}
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
uiNumVals=0;
// OEM2 has a special version of AT+VTS which allows up to 20 DTMF tones in a single command
LPCSTR pchChars = lpszChars;
if (*pchChars)
{
UINT nSent = 0;
uiNumVals++;
hr = StringCchPrintfA( szWalk, cchCmd - ( szWalk - szCmd ), "+VTS=\"%c", *pchChars );
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : PDD_CreateCommand_SendDTMF : error in StringCchPrintfA, hr = [0x%08x]\r\n"), hr));
goto Error;
}
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
pchChars++;
nSent++;
// The length of szCmd is limited by MAX_PATH(260), thus at most 107 characters can be fit into one AT command
for (; (*pchChars) && (pchChars-lpszChars<=107); pchChars++)
{
uiNumVals++;
if (nSent >= 20)
{
hr = StringCchPrintfA( szWalk, cchCmd - ( szWalk - szCmd ), "\";+VTS=\"%c", *pchChars );
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : PDD_CreateCommand_SendDTMF : error in StringCchPrintfA, hr = [0x%08x]\r\n"), hr));
goto Error;
}
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
nSent = 1;
}
else
{
hr = StringCchPrintfA( szWalk, cchCmd - ( szWalk - szCmd ), ",%c", *pchChars );
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : PDD_CreateCommand_SendDTMF : error in StringCchPrintfA, hr = [0x%08x]\r\n"), hr));
goto Error;
}
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
nSent++;
}
}
hr = StringCchCopyA( szWalk, cchCmd - ( szWalk - szCmd ), "\"" );
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : PDD_CreateCommand_SendDTMF : error in StringCchCopyA, hr = [0x%08x]\r\n"), hr));
goto Error;
}
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
}
hr = StringCchCopyA( szWalk, cchCmd - ( szWalk - szCmd ), "\r" );
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : PDD_CreateCommand_SendDTMF : error in StringCchCopyA, hr = [0x%08x]\r\n"), hr));
goto Error;
}
hr = S_OK;
Error:
return hr;
}
HRESULT PDD_CreateCommand_StartDTMF(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const char ch)
{
return E_NOTIMPL;
}
HRESULT PDD_CreateCommand_StopDTMF(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const char ch)
{
return E_NOTIMPL;
}
// Indicate call activity to audio subsystem
HRESULT PDD_IndicateCallActivityToAudioSubsystem(__in const bool fCallIsActive)
{
return E_NOTIMPL;
}
// Create ReleaseHeld command
HRESULT PDD_CreateCommand_ReleaseHeld(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd)
{
return StringCchCopyA( szCmd, cchCmd, "AT+CHLD=7\r" );
}
HRESULT PDD_CreateCommand_ReleaseCall(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const DWORD dwID)
{
return StringCchPrintfA( szCmd, cchCmd, "AT+CHLD=1%u\r", dwID );
}
// Create HoldActiveAcceptHeld command
HRESULT PDD_CreateCommand_HoldActiveAcceptHeld(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd)
{
return StringCchCopyA( szCmd, cchCmd, "AT+CHLD=6\r" );
}
// Create SetCurrentAddressId command
HRESULT PDD_CreateCommand_SetCurrentAddressId(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const DWORD dwAddressId)
{
return E_NOTIMPL;
}
// Create GetCurrentAddressId command
HRESULT PDD_CreateCommand_GetCurrentAddressId(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd)
{
return E_NOTIMPL;
}
// Prepare to power the radio on
HRESULT PDD_BeginRadioPowerOn()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -