📄 ttpcom.cpp
字号:
g_rsq.cbSize = sizeof(RILSIGNALQUALITY);
// OEM2 provides signal strength notifications
if (!ParseSignalQualityData(szPointer, &g_rsq, szPointer))
{
fRetVal = FALSE;
goto Error;
}
m_fUnsolicited = TRUE;
m_dwCode = RIL_NOTIFY_SIGNALQUALITY;
if (!SetBlob((void*)&g_rsq, sizeof(RILSIGNALQUALITY)))
{
fRetVal = FALSE;
goto Error;
}
g_fSignalQualityReceived = TRUE;
}
else if (MatchStringBeginning(szPointer, "+CBCN: ", szPointer))
{
// OEM2 provides battery level notifications, need more work on this topic
ParseJunk(1, szPointer);
}
// OEM2 Some notifications have similar syntax to command responses. THe best way to tell that
// they are notifcations is that they come in on the notification COM port. Parse those here.
else if(fDataOnNotificationPort && MatchStringBeginning(szPointer, "+CFUN: ", szPointer))
{
ParseJunk(1, szPointer);
}
else if(fDataOnNotificationPort && MatchStringBeginning(szPointer, "+CPIN: ", szPointer))
{
if (!ParseCPIN(szPointer))
{
fRetVal = FALSE;
goto Error;
}
SetEvent(g_hCPINNEvent);
}
else if (MatchStringBeginning(szPointer, "+CGURC: ", szPointer))
{
UINT nCode;
m_fUnsolicited = TRUE;
ParseUInt(szPointer, FALSE, nCode, szPointer);
// We retrieve the cause, but we don't use it because we don't have an associated call id. CLCC processing
// is invoked below to sync up the call states. If the call ID was present here, we could simply send the
// CPI notification and not generate the CLCC.
// Here is the breakdown of the nCodes:
// Parse the following integer codes (call state change notifications) as follows:
// 0 Active call cleared with held calls
// 1, We are attempting to make an MO call
// 2, MO Call has failed for some reason
// 3, MO call is ringing
// 4, MT call is queued (Call waiting?)
// 5, M0 call now connected
// 6, M0/MT call has disconnected
// 7, MO/MT call hung up
// 8, MO call emergency only
// 9. MO call No Answer
// 10. MO call Busy
// 11, MO call terminated due to network congestion - not yet implemented by OEM2
// 12, MO call terminated due to network dropped call - not yet implemented by OEM2
// 1, 2, 5, 6, 10, 11, and 12 are the only state changes that require action from us.
// There is one excption to the CLCC-Only handling case: nCode == 1. If we are attempting to make a
// call, we should send a CPI. The reason for this is because the CLCC may be blocked from going out
// while the call is in progress. We do have to guess at the call id. The fact is that without call id's we can't
// handle multiple call cases properly.
if ( 1 == nCode )
{
RILCALLINFO rci;
memset ( &rci, 0, sizeof(rci));
rci.cbSize = sizeof ( rci );
rci.dwStatus = RIL_CPISTAT_NEW_OUTGOING;
rci.dwParams |= RIL_PARAM_CI_CPISTATUS;
rci.dwDirection = RIL_CALLDIR_OUTGOING; // fill this in for completeness sake
rci.dwParams |= RIL_PARAM_CI_DIRECTION;
rci.dwID = 1;
rci.dwParams |= RIL_PARAM_CI_ID;
SendRilCPIMessage ( &rci );
}
SetPotentialBogusResponseFlag ();
// If we are getting a CGURC command, then we know that CLCC has changed in some what that is important to us.
// So, now we will request the call list and parse it to see what is different than the last time that we got the call list
// since we get the call list everytime that the radio tells us something in the call list has changed. This will be done
// in the ParseGetCallList function when this returns.
// This should be the only place that the CLCC is needed to be called in actual usage, otherwise the information
// is sent through notifications via CPI notification, which this will turn into if changed in the ParseGetCallList function.
if (!SetupCallListEvaluation ())
{
DEBUGMSG(ZONE_ERROR, (TEXT("ParseNotification : E : Error setting up Call List Evaluation\r\n")));
}
// CSS_TODO: Figure out a more elegant way of getting through this than this setup as invalid thingy.
goto Error; // This prevents anything from trying to be sent anywhere.
}
// OEM2 sends up CPINN notifications of the same form.
else if (MatchStringBeginning(szPointer, "+CPINN: ", szPointer))
{
if (!ParseCPIN(szPointer))
{
goto Error;
}
m_fUnsolicited = TRUE;
// In the CPINN case, we don't want to send up a notification of RIL_RESULT_OK
// or RIL_RESULT_ERROR. This will just upset the proxy.
m_fUnrecognized = TRUE;
SetEvent(g_hCPINNEvent);
}
else
{
// Treat the "no match" case as an error
fRetVal = FALSE;
goto Error;
}
Error:
return fRetVal;
}
BOOL CResponseTTPCOM::ParseSIMToolkitCmdOrRspOEM
(
LPCSTR& rszPointer, // IN, OUT
const DWORD dwNotifyCode, // IN
RILSIMTOOLKITCMD*& pCmd, // OUT
DWORD& dwCmdSize // OUT
)
{
BYTE* pbData = NULL;
UINT cbData = 0;
CRilSimToolkitCommand rstcCmd;
DWORD dwSIMResponse=SIM_RESPONSE_OK;
BOOL fRet = FALSE;
LPCSTR pszEnd = NULL;
if (RIL_NOTIFY_SIMTOOLKITEVENT == dwNotifyCode)
{
// Look for a "<postfix>"
if (!FindRspPostfix(rszPointer, pszEnd))
{
// This isn't a complete SIM Toolkit notification -- no need to parse it
goto Error;
}
}
else
{
// Pass entire response to the sim toolkit layer to parse.
// Because of the multi-line SetupMenu(ID25)/SelectItem(ID24) command, we cannot
// just check for the response postfix to appear anywhere.
// It is assumed the result is always ok or error at end for now, but this should be improved.
//
// Also, we need to move the end pointer before the OK/Error response.
// This insures the result code is left at the end of the string so further
// parsing picks up the result code and exits from the notification cleanly.
if (MatchStringEnd(rszPointer, "\r\n0\r", pszEnd) ||
MatchStringEnd(rszPointer, "\r\n4\r", pszEnd))
{
pszEnd -= strlen("0\r");
}
else if (MatchStringEnd(rszPointer, "\r\nOK\r", pszEnd))
{
pszEnd -= strlen("OK\r");
}
else if (MatchStringEnd(rszPointer, "\r\nERROR\r", pszEnd))
{
pszEnd -= strlen("ERROR\r");
}
else
{
// This isn't a complete SIM Toolkit notification -- no need to parse it
goto Error;
}
}
// Copy the data to a temporary blob so we can hold on to the data and place it into
// cached toolkit commands if the shell isn't ready.
if ( (pszEnd > rszPointer) && ((pszEnd - rszPointer) >= (INT)strlen("\r\n")) )
{
cbData = pszEnd - rszPointer + 1;
pbData = (BYTE*)AllocBlob(cbData);
}
if ( NULL == pbData )
{
goto Error;
}
memcpy((void*)pbData, rszPointer, cbData-1);
// Null terminate the memory buffer
pbData[cbData-1] = '\0';
// Advance the parse pointer to the end of the data, but before
// postfix of the AT command for correct further parsing.
rszPointer = pszEnd - strlen("\r\n");
pCmd = NULL;
dwCmdSize = 0;
dwSIMResponse = SIM_RESPONSE_OK;
dwSIMResponse = rstcCmd.ParseCommand((LPSTR)pbData, cbData, &pCmd, &dwCmdSize);
if (SIM_RESPONSE_OK != dwSIMResponse)
{
// Error parsing the command.
// There was a critical error if an error notification was not created.
if (NULL == pCmd || (0 >= dwCmdSize))
{
goto Error;
}
//RILSIMTOOLKITCMD* pTmpCmd = pCmd;
// Send a response to the radio
if (FAILED(SendSIMToolkitErrorRsp(pCmd)))
{
DEBUGCHK(FALSE);
}
}
if ( !SetBlob((void*)pCmd, dwCmdSize) )
{
goto Error;
}
// Always send cmd notification.
m_dwCode = RIL_NOTIFY_SIMTOOLKITCMD;
m_fUnsolicited = TRUE;
fRet = TRUE;
Error:
FreeBlob(pbData);
return fRet;
}
void CResponseTTPCOM::Post_ParseCPINOEM(char* szState)
{
// On TTPCOM, we process only these 5 CPINN commands and throw away the other CPINN commands.
if (!strcmp(szState, "SIM PIN2"))
{
MakeError(RIL_E_SIMPIN2REQUIRED);
}
else if (!strcmp(szState, "SIM PUK2"))
{
MakeError(RIL_E_SIMPUK2REQUIRED);
}
else if (!strcmp(szState, "SIM PIN"))
{
MakeError(RIL_E_SIMPINREQUIRED);
}
else if (!strcmp(szState, "SIM PUK"))
{
MakeError(RIL_E_SIMPUKREQUIRED);
}
else if (!strcmp(szState, "READY"))
{
m_dwCode = RIL_RESULT_OK;
HRESULT hr = S_OK;
if (!SetBlob((void*)&hr, sizeof(hr)))
{
// Error condition
}
}
else
{
m_fUnrecognized = TRUE;
}
}
HRESULT PDD_CreateCommand_GetATR(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd)
{
return E_NOTIMPL;
}
HRESULT PDD_CreateCommand_TerminateSimToolkitSession(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const DWORD dwCause)
{
return E_NOTIMPL;
}
HRESULT PDD_CreateCommand_EnableSignalQualityNotification(__out_ecount(cchCmd) LPSTR szCmd, __in const size_t cchCmd, __in const bool fEnable)
{
return E_NOTIMPL;
}
// NDIS stuff
DWORD WINAPI NdisNotifyThreadProc(LPVOID lpParameter);
#define MAX_NDIS_EVENT_NAME 100
#define MAX_IP_ADDRESS_LENGTH 4
HINSTANCE g_hinstOEMNDIS /*= NULL*/;
CRilNDISTTPCOM* g_pCRilNdis = NULL;
#define OEM_LIBRARY TEXT("ttpmux")
#define OEM_NdisInitialize TEXT("ttpcomNdisInitialise")
#define OEM_NdisShutdown TEXT("ttpcomNdisShutdown")
#define OEM_NdisReceiveEvent TEXT("ttpcomNdisReceiveEvent")
#define OEM_NdisTransmitEvent TEXT("ttpcomNdisTransmitEvent")
typedef HANDLE (*PFN_NDIS_INITIALIZE)(DWORD);
typedef BOOL (*PFN_NDIS_SHUTDOWN)(HANDLE);
typedef BOOL (*PFN_NDIS_RECEIVE_EVENT)(HANDLE, OEMNDISEVENT*,BOOL*);
typedef BOOL (*PFN_NDIS_TRANSMIT_EVENT)(HANDLE, const OEMNDISEVENT*);
PFN_NDIS_INITIALIZE g_pfnNdisInitialize;
PFN_NDIS_SHUTDOWN g_pfnNdisShutdown;
PFN_NDIS_RECEIVE_EVENT g_pfnNdisReceiveEvent;
PFN_NDIS_TRANSMIT_EVENT g_pfnNdisTransmitEvent;
HINSTANCE LoadPacketLib()
{
if (!g_hinstOEMNDIS)
{
g_hinstOEMNDIS = LoadLibrary(OEM_LIBRARY);
ASSERT(g_hinstOEMNDIS);
}
return g_hinstOEMNDIS;
}
HRESULT GetPacketInterface()
{
HRESULT hr = E_FAIL;
HINSTANCE hinst;
hinst = LoadPacketLib();
if (!hinst)
{
ASSERT(0);
goto Error;
}
g_pfnNdisInitialize = (PFN_NDIS_INITIALIZE)GetProcAddress(hinst, OEM_NdisInitialize );
g_pfnNdisShutdown = (PFN_NDIS_SHUTDOWN)GetProcAddress(hinst, OEM_NdisShutdown );
g_pfnNdisReceiveEvent = (PFN_NDIS_RECEIVE_EVENT)GetProcAddress(hinst, OEM_NdisReceiveEvent);
g_pfnNdisTransmitEvent = (PFN_NDIS_TRANSMIT_EVENT)GetProcAddress(hinst, OEM_NdisTransmitEvent);
if (!g_pfnNdisInitialize || !g_pfnNdisShutdown || !g_pfnNdisReceiveEvent || !g_pfnNdisTransmitEvent)
{
ASSERT(0);
goto Error;
}
else
{
hr = S_OK;
}
Error:
return hr;
}
BOOL ValidChannelIndex ( DWORD dwIndex )
{
return ((dwIndex >= FIRST_VALID_NDIS_INDEX) && (dwIndex <= MAX_OEMNDIS_CHANNELS)) ? TRUE : FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -