📄 gprs.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:
gprs.cpp
Abstract:
Notes:
--*/
#include "precomp.h"
// According to GSM 03.60 Section 14.9, APN's meet the DNS naming convention.
#define VALID_GPRS_APN_CHARACTERS L"ABDCEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890.-"
// Note: Remember all LISTSTRINGMAP/LISTVALUEMAP structures must be sorted by the string/value key (not the flags key).
// This is because the range parse functions use bsearch to search for the flags fields.
static const LISTSTRINGMAP g_GprsPDPTypes[] =
{
{"IP", RIL_GPRSPROTOCOL_IP },
{"OSPIH", RIL_GPRSPROTOCOL_IHOSP },
{"PPP", RIL_GPRSPROTOCOL_PPP },
{"X25", RIL_GPRSPROTOCOL_X25 },
};
#define NUM_GPRSPDPTYPES (sizeof(g_GprsPDPTypes) / sizeof(LISTSTRINGMAP))
static const LISTSTRINGMAP g_GprsL2Protocols[] =
{
{"NULL", RIL_GPRSL2PROTOCOL_NULL },
{"PAD", RIL_GPRSL2PROTOCOL_PAD },
{"PPP", RIL_GPRSL2PROTOCOL_PPP },
{"X25", RIL_GPRSL2PROTOCOL_X25 },
};
#define NUM_GPRSL2PROTOCOLS (sizeof(g_GprsL2Protocols) / sizeof(LISTSTRINGMAP))
static const LISTVALUEMAP g_GprsDataComp[] =
{
{0, RIL_GPRSDATACOMP_OFF},
{1, RIL_GPRSDATACOMP_ON}
};
#define NUM_GPRSDATACOMP (sizeof(g_GprsDataComp) / sizeof(LISTVALUEMAP))
static const LISTVALUEMAP g_GprsHeaderComp[] =
{
{0, RIL_GPRSHEADERCOMP_OFF},
{1, RIL_GPRSHEADERCOMP_ON}
};
#define NUM_GPRSHEADERCOMP (sizeof(g_GprsHeaderComp) / sizeof(LISTVALUEMAP))
static const LISTVALUEMAP g_GprsPrecedenceClass[] =
{
{0, RIL_GPRSPRECEDENCECLASS_SUBSCRIBED },
{1, RIL_GPRSPRECEDENCECLASS_HIGH },
{2, RIL_GPRSPRECEDENCECLASS_NORMAL },
{3, RIL_GPRSPRECEDENCECLASS_LOW }
};
#define NUM_GPRSPRECEDENCECLASS (sizeof(g_GprsPrecedenceClass) / sizeof(LISTVALUEMAP))
static const LISTVALUEMAP g_GprsDelayClass[] =
{
{0, RIL_GPRSDELAYCLASS_SUBSCRIBED },
{1, RIL_GPRSDELAYCLASS_PREDICTIVE1 },
{2, RIL_GPRSDELAYCLASS_PREDICTIVE2 },
{3, RIL_GPRSDELAYCLASS_PREDICTIVE3 },
{4, RIL_GPRSDELAYCLASS_BESTEFFORT }
};
#define NUM_GPRSDELAYCLASS (sizeof(g_GprsDelayClass) / sizeof(LISTVALUEMAP))
static const LISTVALUEMAP g_GprsReliabilityClass[] =
{
{0, RIL_GPRSRELIABILITYCLASS_SUBSCRIBED },
{1, RIL_GPRSRELIABILITYCLASS_1 },
{2, RIL_GPRSRELIABILITYCLASS_2 },
{3, RIL_GPRSRELIABILITYCLASS_3 },
{4, RIL_GPRSRELIABILITYCLASS_4 },
{5, RIL_GPRSRELIABILITYCLASS_5 }
};
#define NUM_GPRSRELIABILITYCLASS (sizeof(g_GprsReliabilityClass) / sizeof(LISTVALUEMAP))
static const LISTSTRINGMAP g_GprsClass[] =
{
{"A", RIL_GPRSCLASS_GSMANDGPRS },
{"B", RIL_GPRSCLASS_GSMORGPRS },
{"C", RIL_GPRSCLASS_GSMORGPRS_EXCLUSIVE },
{"CC", RIL_GPRSCLASS_GSMONLY },
{"CG", RIL_GPRSCLASS_GPRSONLY },
};
#define NUM_GPRSCLASS (sizeof(g_GprsClass) / sizeof(LISTSTRINGMAP))
static const LISTVALUEMAP g_GprsPeakThruClass[] =
{
{0, RIL_PEAKTHRUCLASS_SUBSCRIBED },
{1, RIL_PEAKTHRUCLASS_8000 },
{2, RIL_PEAKTHRUCLASS_16000 },
{3, RIL_PEAKTHRUCLASS_32000 },
{4, RIL_PEAKTHRUCLASS_64000 },
{5, RIL_PEAKTHRUCLASS_128000 },
{6, RIL_PEAKTHRUCLASS_256000 },
{7, RIL_PEAKTHRUCLASS_512000 },
{8, RIL_PEAKTHRUCLASS_1024000 },
{9, RIL_PEAKTHRUCLASS_2048000 }
};
#define NUM_GPRSPEAKTHRUCLASS (sizeof(g_GprsPeakThruClass) / sizeof(LISTVALUEMAP))
static const LISTVALUEMAP g_GprsMeanThruClass[] =
{
{0, RIL_MEANTHRUCLASS_SUBSCRIBED },
{1, RIL_MEANTHRUCLASS_100 },
{2, RIL_MEANTHRUCLASS_200 },
{3, RIL_MEANTHRUCLASS_500 },
{4, RIL_MEANTHRUCLASS_1000 },
{5, RIL_MEANTHRUCLASS_2000 },
{6, RIL_MEANTHRUCLASS_5000 },
{7, RIL_MEANTHRUCLASS_10000 },
{8, RIL_MEANTHRUCLASS_20000 },
{9, RIL_MEANTHRUCLASS_50000 },
{10, RIL_MEANTHRUCLASS_100000 },
{11, RIL_MEANTHRUCLASS_200000 },
{12, RIL_MEANTHRUCLASS_500000 },
{13, RIL_MEANTHRUCLASS_1000000 },
{14, RIL_MEANTHRUCLASS_2000000 },
{15, RIL_MEANTHRUCLASS_5000000 },
{16, RIL_MEANTHRUCLASS_10000000 },
{17, RIL_MEANTHRUCLASS_20000000 },
{18, RIL_MEANTHRUCLASS_50000000 },
{31, RIL_MEANTHRUCLASS_DONTCARE }
};
#define NUM_GPRSMEANTHRUCLASS (sizeof(g_GprsMeanThruClass) / sizeof(LISTVALUEMAP))
static const LISTVALUEMAP g_GprsMOSMSService[] =
{
// 3GPP TS 27.007 V6.8.0 (2005-03) section 10.1.20 +CGSMS
{0, RIL_MOSMSSERVICE_GPRS },
{1, RIL_MOSMSSERVICE_CIRCUIT },
{2, RIL_MOSMSSERVICE_GPRSPREFERRED },
{3, RIL_MOSMSSERVICE_CIRCUITPREFERRED }
};
#define NUM_GPRSMOSMSSERVICE (sizeof(g_GprsMOSMSService) / sizeof(LISTVALUEMAP))
/*
+CGDCONT: <cid>, <PDP_type>,<APN>,<PDP_addr>,<data_comp>,<head_comp>[,<pd1>[,...[,pdN]]]
[<CR><LF>+CGDCONT: <cid>, <PDP_type>,<APN>,<PDP_addr>, <data_comp>,<head_comp>[,<pd1>[,...[,pdN]]]
[...]]
Returns a RILGPRSCONTEXT structure
*/
HRESULT ParseGetGPRSContextList(LPCSTR szRsp, void*& pBlob, UINT& cbBlob)
{
FUNCTION_TRACE(ParseGetGPRSContextList);
PBYTE pBuffer=NULL;
DWORD dwBufferSize=0;
RILGPRSCONTEXT GPRSContext, *pGPRSContext;
char szValue[MAX_PATH];
UINT nValue;
LPCSTR szParams, szParamsEnd;
HRESULT hr = E_FAIL;
BOOL bSuccess;
pBlob = NULL;
cbBlob = 0;
// Parse "<prefix>"
if (!ParseRspPrefix(szRsp, szRsp))
{
goto Error;
}
// Parse "+CGDCONT: "
while (MatchStringBeginning(szRsp, "+CGDCONT: ", szRsp))
{
memset(&GPRSContext, 0x00, sizeof(GPRSContext));
// Parse <cid>
if (!ParseUInt(szRsp, TRUE, nValue, szRsp))
{
goto Continue;
}
GPRSContext.dwContextID = nValue;
GPRSContext.dwParams|= RIL_PARAM_GCONT_CONTEXTID;
// Parse ,<PDP_type>
if (!MatchStringBeginning(szRsp, ",", szRsp))
{
goto Continue;
}
if (ParseString(szRsp, szValue, MAX_PATH, szRsp)
&& FlagFromString(szValue, g_GprsPDPTypes, NUM_GPRSPDPTYPES, GPRSContext.dwProtocolType))
{
GPRSContext.dwParams|= RIL_PARAM_GCONT_PROTOCOLTYPE;
}
// Parse ,<APN>
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseString(szRsp, szValue, MAX_PATH, szRsp))
{
goto Continue;
}
(void)wcsncpyz(GPRSContext.wszAccessPointName, WideString(szValue), MAXLENGTH_GPRSACCESSPOINTNAME);
GPRSContext.dwParams|= RIL_PARAM_GCONT_ACCESSPOINTNAME;
#ifdef RIL_WATSON_REPORT
// Copy APN to the info cache.
EnterCriticalSection(&g_csRilInfoCache);
strncpy(g_RilInfoCache.szAPN, szValue, MAXLENGTH_GPRSACCESSPOINTNAME);
LeaveCriticalSection(&g_csRilInfoCache);
#endif // RIL_WATSON_REPORT
// Parse ,<PDP_addr>
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseString(szRsp, szValue, MAX_PATH, szRsp))
{
goto Continue;
}
(void)wcsncpyz(GPRSContext.wszAddress, WideString(szValue), MAXLENGTH_GPRSADDRESS);
GPRSContext.dwParams|= RIL_PARAM_GCONT_ADDRESS;
// Parse ,<data_comp>
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUIntAndVerifyAbove(szRsp, FALSE, 0x2, nValue, szRsp))
{
goto Continue;
}
if (FlagFromValue(nValue, g_GprsDataComp, NUM_GPRSDATACOMP, GPRSContext.dwDataCompression))
{
GPRSContext.dwParams|= RIL_PARAM_GCONT_DATACOMPRESSION;
}
// Parse ,<head_comp>
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUIntAndVerifyAbove(szRsp, FALSE, 0x2, nValue, szRsp))
{
goto Continue;
}
if (FlagFromValue(nValue, g_GprsHeaderComp, NUM_GPRSHEADERCOMP, GPRSContext.dwHeaderCompression))
{
GPRSContext.dwParams|= RIL_PARAM_GCONT_HEADERCOMPRESSION;
}
// Parse ","
if (!MatchStringBeginning(szRsp, ",", szRsp))
{
goto Continue;
}
szParams = szRsp;
// Parse ,<pd1>[,...[,pdN]]
szParamsEnd = strstr(szParams, "\r\n");
if (!szParamsEnd)
{
goto Error;
}
szRsp = szParamsEnd;
// Now all the data between szParams and szParamsEnd is the pd1-N string
GPRSContext.dwParams|= RIL_PARAM_GCONT_PARAMETERS;
// Set dwParameterLength to be size of string in bytes counting null char at end
GPRSContext.dwParameterLength = (szParamsEnd-szParams)+1;
Continue:
// Find "<postfix>"
bSuccess = FindRspPostfix(szRsp, szRsp);
if (!bSuccess)
{
goto Error;
}
// Init size of GPRSContext
GPRSContext.cbSize = sizeof(GPRSContext);
// Add in size of param string
GPRSContext.cbSize += GPRSContext.dwParameterLength;
// Round up to the nearest 32-bit address for alignment
GPRSContext.cbSize = (GPRSContext.cbSize + 3) & (~0x03);
// Reallocate our buffer for the additional data
pBuffer = (PBYTE)ReallocBlob(pBuffer,dwBufferSize+GPRSContext.cbSize);
if (!pBuffer)
{
goto Error;
}
// Point pGPRSContext to the first byte of the newly allocated section
pGPRSContext = (RILGPRSCONTEXT *) (pBuffer+dwBufferSize);
// Copy struct to buffer
*pGPRSContext = GPRSContext;
if (GPRSContext.dwParameterLength)
{
memcpy(GPRSContext.szParameters,szParams,GPRSContext.dwParameterLength);
GPRSContext.szParameters[GPRSContext.dwParameterLength]='\0';
}
dwBufferSize+=GPRSContext.cbSize;
}
pBlob = (void*)pBuffer;
cbBlob = dwBufferSize;
hr = S_OK;
Error:
if (FAILED(hr))
{
FreeBlob(pBuffer);
}
return hr;
}
// +CGDCONT?
HRESULT RILDrv_GetGPRSContextList (DWORD dwParam)
{
FUNCTION_TRACE(RILDrv_GetGPRSContextList);
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RILDrv_GetGPRSContextList\r\n")));
HRESULT hr = E_INVALIDARG;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle)
{
goto Error;
}
if (!QueueCmd(pHandle,
"AT+CGDCONT?\r",
CMDOPT_NONE,
APIID_GETGPRSCONTEXTLIST,
ParseGetGPRSContextList, // Parse fn
NULL, // Ptr to notification data
hr))
{
hr = E_FAIL;
goto Error;
}
Error:
return hr;
}
// +CGDCONT=<params>
// +CGDCONT=[<cid> [,<PDP_type> [,<APN> [,<PDP_addr> [,<d_comp> [,<h_comp> [,<pd1> [,...[,pdN]]]]]]]]]
/*
typedef struct rilgprscontext_tag {
DWORD cbSize; // @field structure size in bytes
DWORD dwParams; // @field indicates valid parameters
DWORD dwContextID; // @field the context number
DWORD dwProtocolType; // @field a RIL_GPRSPROTOCOL_*constant
WCHAR wszAccessPointName[MAXLENGTH_GPRSACCESSPOINTNAME];
// @field a logical name to select the gateway gprs
// (which defines the external packet data network to use)
WCHAR wszAddress[MAXLENGTH_GPRSADDRESS]; // @field the packet address to use (if null, request dynamic)
DWORD dwDataCompression; // @field a RIL_GPRSDATACOMP_*
DWORD dwHeaderCompression; // @field a RIL_GPRSHEADERCOMP_*
DWORD dwParameterLength; // @field length of parameters list
char szParameters[]; // @field parameters specific to the prococol type
} RILGPRSCONTEXT, *LPRILGPRSCONTEXT;
*/
HRESULT RILDrv_SetGPRSContext (DWORD dwParam, const RILGPRSCONTEXT* lpGprsContext)
{
FUNCTION_TRACE(RILDrv_SetGPRSContext);
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RILDrv_SetGPRSContext\r\n")));
HRESULT hr = E_INVALIDARG;
char szCmd[MAX_PATH];
LPSTR szWalk = szCmd;
UINT Value;
RILGPRSCONTEXT RilGprsContextCopy;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle || !lpGprsContext)
{
goto Error;
}
CeSafeCopyMemory((LPVOID)&RilGprsContextCopy, (LPCVOID)lpGprsContext, sizeof(RilGprsContextCopy));
// Build command
(void)_snprintfz(szCmd, MAX_PATH, "AT+CGDCONT=%u,", RilGprsContextCopy.dwContextID);
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
if (RilGprsContextCopy.dwParams & RIL_PARAM_GCONT_PROTOCOLTYPE)
{
LPSTR szString;
if (!StringFromFlag(RilGprsContextCopy.dwProtocolType,g_GprsPDPTypes, NUM_GPRSPDPTYPES, szString))
{
goto Error;
}
(void)_snprintfz(szWalk, MAX_PATH - (szWalk - szCmd), "\"%s\"",szString);
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
}
// Add ","
(void)strncpyz(szWalk, ",", MAX_PATH - (szWalk - szCmd));
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
if (RilGprsContextCopy.dwParams & RIL_PARAM_GCONT_ACCESSPOINTNAME)
{
// Force the NULL-termination
RilGprsContextCopy.wszAccessPointName[ARRAY_LENGTH(RilGprsContextCopy.wszAccessPointName)-1]=WCHAR ('\0');
// Filter the access point name to only contain valid characters.
WCHAR wszFilteredApn[MAXLENGTH_GPRSACCESSPOINTNAME];
if (FAILED( StringFilterW(wszFilteredApn,
ARRAY_LENGTH(wszFilteredApn)-1,
(LPWSTR)RilGprsContextCopy.wszAccessPointName,
VALID_GPRS_APN_CHARACTERS) ))
{
goto Error;
}
// Force the NULL-termination
wszFilteredApn[ARRAY_LENGTH(wszFilteredApn)-1] = WCHAR ('\0');
(void)_snprintfz(szWalk, MAX_PATH - (szWalk - szCmd), "\"%s\"", AnsiString(wszFilteredApn));
szWalk = strchr(szWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szWalk);
#ifdef RIL_WATSON_REPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -