📄 misc.cpp
字号:
// Invalid Tag
return FALSE;
}
// Encoded length starts at index 1
BYTE bValuePos = 0;
UINT uLen = 0;
if (0x80 == (0x80 & pRawData[1])) {
BYTE bLenBytes = 0x7F & pRawData[1];
if (1 < bLenBytes ||
3 > cbSize) {
// Currently only support 1 extra length byte
return FALSE;
}
uLen = pRawData[2];
bValuePos = 3;
}
else {
uLen = pRawData[1];
bValuePos = 2;
}
// Verify there is enough data available for the value
if (uLen + bValuePos > cbSize) {
return FALSE;
}
// Verify length and value size are consistent.
if (cbSize - bValuePos < uLen) {
// Try and recover using the minimum value.
uLen = cbSize - bValuePos;
}
m_bTag = bTag;
m_uLen = uLen;
m_pbValue = pRawData + bValuePos;
m_uTotalSize = uLen + bValuePos;
return TRUE;
}
//
//
//
BOOL ParseGetUsimRecordStatus(RILSIMRESPONSE* prsr, RILSIMRECORDSTATUS* prsrs, HRESULT* phr)
{
BOOL fRet = FALSE;
const BYTE FCP_TAG = 0x62;
const BYTE FILE_SIZE_TAG = 0x80;
const BYTE FILE_DESCRIPTOR_TAG = 0x82;
const BYTE FILE_ID_TAG = 0x83;
const MASTER_FILE_ID = 0x3F00;
DWORD dwRecordType = SIM_RECORDTYPE_UNKNOWN;
DWORD dwParams = 0;
DWORD dwItemCount = 0;
DWORD dwRecordLength = 0;
DWORD dwSize = 0;
BerTlv tlvFileDescriptor;
BerTlv tlvFcp;
if (NULL == prsr ||
NULL == prsrs ||
NULL == phr) {
goto Exit;
}
DWORD cbDataResponseSize = prsr->cbSize - sizeof(RILSIMRESPONSE);
// Need at least 2 bytes for response data FCP (file control parameters)
if (2 > cbDataResponseSize) {
goto Exit;
}
// Validate this response is a 3GPP 102 221 SELECT response.
tlvFcp.Parse(prsr->pbResponse, prsr->cbSize);
if (FCP_TAG != tlvFcp.GetTag()) {
goto Exit;
}
ASSERT(cbDataResponseSize == tlvFcp.GetTotalSize());
const BYTE* pbFcpData = tlvFcp.GetValue();
UINT cbFcpDataSize = tlvFcp.GetLength();
// Retrieve the File Descriptor data object
tlvFileDescriptor.Parse(pbFcpData, cbFcpDataSize);
if (FILE_DESCRIPTOR_TAG != tlvFileDescriptor.GetTag()) {
goto Exit;
}
UINT cbDataUsed = tlvFileDescriptor.GetTotalSize();
if (cbDataUsed > cbFcpDataSize) {
goto Exit;
}
const BYTE* pbFileDescData = tlvFileDescriptor.GetValue();
UINT cbFileDescDataSize = tlvFileDescriptor.GetLength();
// File descriptors should only be 2 or 5 bytes long.
ASSERT(2 == cbFileDescDataSize || 5 == cbFileDescDataSize);
if (2 > cbFileDescDataSize) {
goto Exit;
}
BOOL fIsDf = (0x38 == (0x38 & pbFileDescData[0]));
BYTE bEfStructure = 0x07 & pbFileDescData[0];
dwParams |= RIL_PARAM_SRS_RECORDTYPE;
if (fIsDf) {
dwRecordType = RIL_SIMRECORDTYPE_DEDICATED;
}
// or it is an EF or MF.
else {
switch (bEfStructure) {
// Transparent
case 0x01:
dwRecordType = RIL_SIMRECORDTYPE_TRANSPARENT;
break;
// Linear Fixed
case 0x02:
dwRecordType = RIL_SIMRECORDTYPE_LINEAR;
break;
// Cyclic
case 0x06:
dwRecordType = RIL_SIMRECORDTYPE_CYCLIC;
break;
default:
break;
}
if (RIL_SIMRECORDTYPE_LINEAR == dwRecordType ||
RIL_SIMRECORDTYPE_CYCLIC == dwRecordType) {
// Need at least 5 bytes
if (5 > cbFileDescDataSize) {
goto Exit;
}
dwItemCount = pbFileDescData[4];
dwRecordLength = (pbFileDescData[2] << 4) + (pbFileDescData[3]);
// Skip checking of consistency with the File Size data object to
// save time.
dwSize = dwRecordLength;
dwParams |= RIL_PARAM_SRS_ITEMCOUNT | RIL_PARAM_SRS_SIZE;
}
else if(RIL_SIMRECORDTYPE_TRANSPARENT == dwRecordType) {
// Retrieve the file size.
BerTlv tlvCurrent;
while (cbFcpDataSize > cbDataUsed) {
if (!tlvCurrent.Parse(
pbFcpData + cbDataUsed,
cbFcpDataSize - cbDataUsed)) {
goto Exit;
}
cbDataUsed += tlvCurrent.GetTotalSize();
if (FILE_SIZE_TAG == tlvCurrent.GetTag()) {
if (2 > tlvCurrent.GetLength()) {
goto Exit;
}
const BYTE* pbFileSize = tlvCurrent.GetValue();
dwSize = (pbFileSize[0] << 4) + pbFileSize[1];
dwParams |= RIL_PARAM_SRS_SIZE;
// Size found. Leave loop
break;
}
}
}
}
// if record type has not been resolved, check for Master file.
if (RIL_SIMRECORDTYPE_UNKNOWN == dwRecordType) {
// Next data object should be File ID.
BerTlv tlvFileId(
pbFcpData + cbFcpDataSize,
cbFcpDataSize - cbDataUsed);
if (FILE_ID_TAG != tlvFileId.GetTag()) {
goto Exit;
}
if (2 != tlvFileId.GetLength()) {
goto Exit;
}
const BYTE* pbFileId = tlvFileId.GetValue();
UINT uFileId = (pbFileId[0] << 4) + pbFileId[1];
if (MASTER_FILE_ID != uFileId) {
goto Exit;
}
dwRecordType = RIL_SIMRECORDTYPE_MASTER;
}
prsrs->cbSize = sizeof(RILSIMRECORDSTATUS);
prsrs->dwParams = dwParams;
prsrs->dwRecordType = dwRecordType;
prsrs->dwItemCount = dwItemCount;
prsrs->dwSize = dwSize;
fRet = TRUE;
Exit:
return fRet;
}
#endif
#endif
//
//
//
HRESULT ParseGetSimRecordStatus(LPCSTR szRsp, void*& pBlob, UINT& cbBlob)
{
FUNCTION_TRACE(ParseGetSimRecordStatus);
HRESULT hr = S_OK;
RILSIMRESPONSE* prsr = NULL;
RILSIMRECORDSTATUS *prsrs = NULL;
UINT cbStruct = sizeof(RILSIMRECORDSTATUS);
DWORD dwFileID;
DWORD dwTotalSize;
pBlob = NULL;
cbBlob = 0;
// First fill in the RILSIMRESPONSE structure
void *pBlobTmp=NULL;
UINT cbBlobTmp=0;
hr = ParseSendRestrictedSimCmd(szRsp, pBlobTmp, cbBlobTmp);
prsr = (RILSIMRESPONSE *)pBlobTmp;
if (FAILED(hr)) {
goto Error;
}
// Now we need to munge this to be a RILSIMRECORDSTATUS structure instead
prsrs = (RILSIMRECORDSTATUS*)AllocBlob(cbStruct);
if (!prsrs) {
hr = E_OUTOFMEMORY;
goto Error;
}
memset(prsrs, 0x00, cbStruct);
// Was there an error of some sort?
DEBUGCHK((prsr->dwParams & RIL_PARAM_SR_STATUSWORD1) && (prsr->dwParams & RIL_PARAM_SR_STATUSWORD2));
hr = DetermineSimResponseError(prsr->dwStatusWord1, prsr->dwStatusWord2);
if (FAILED(hr)) {
goto Error;
}
#if defined(EMP_DRIVER)
if (ParseGetUsimRecordStatus(prsr, prsrs, &hr)) {
if (SUCCEEDED(hr))
{
pBlob = (void*)prsrs;
cbBlob = cbStruct;
}
goto Error;
}
#endif
// The response has to be present and at least 7 bytes long
if ((!(prsr->dwParams & RIL_PARAM_SR_RESPONSE)) || (prsr->cbSize - sizeof(RILSIMRESPONSE) < 7))
{
hr = E_FAIL;
goto Error;
}
// The file ID should be in bytes 5 and 6 -- in either case, we need at least 7 bytes
dwFileID = (prsr->pbResponse[4] << 8) | prsr->pbResponse[5];
prsrs->cbSize = cbStruct;
prsrs->dwParams = (RIL_PARAM_SRS_SIZE | RIL_PARAM_SRS_RECORDTYPE);
prsrs->dwRecordType = RIL_SIMRECORDTYPE_UNKNOWN;
if (IsElementarySimFile(dwFileID))
{
// Need at least 14 bytes for an elementary file
if (prsr->cbSize - sizeof(RILSIMRESPONSE) < 14)
{
hr = E_FAIL;
goto Error;
}
// Byte 14 tells us the file type
switch (prsr->pbResponse[13])
{
case 0x00:
case 0x02: // This is what OEM1 gives us, but it's not in 11.11!
prsrs->dwRecordType = RIL_SIMRECORDTYPE_TRANSPARENT;
break;
case 0x01:
prsrs->dwRecordType = RIL_SIMRECORDTYPE_LINEAR;
break;
case 0x03:
prsrs->dwRecordType = RIL_SIMRECORDTYPE_CYCLIC;
break;
default:
break;
}
// Set more fields based on the file type
dwTotalSize = (prsr->pbResponse[2] << 8) | prsr->pbResponse[3];
if (prsrs->dwRecordType == RIL_SIMRECORDTYPE_TRANSPARENT)
{
// Size is bytes 3 and 4
prsrs->dwParams |= RIL_PARAM_SRS_SIZE;
prsrs->dwSize = dwTotalSize;
}
else if (prsrs->dwRecordType != RIL_SIMRECORDTYPE_UNKNOWN)
{
// Make sure we have a fifteenth byte in this case
if (prsr->cbSize - sizeof(RILSIMRESPONSE) < 15)
{
hr = E_FAIL;
goto Error;
}
prsrs->dwParams |= (RIL_PARAM_SRS_SIZE | RIL_PARAM_SRS_ITEMCOUNT);
prsrs->dwSize = prsr->pbResponse[14];
prsrs->dwItemCount = dwTotalSize / prsrs->dwSize;
}
}
else
{
// We only set the file type, which is determined by byte 7
switch (prsr->pbResponse[6])
{
case 0x01:
prsrs->dwRecordType = RIL_SIMRECORDTYPE_MASTER;
break;
case 0x02:
prsrs->dwRecordType = RIL_SIMRECORDTYPE_DEDICATED;
break;
default:
break;
}
}
pBlob = (void*)prsrs;
cbBlob = cbStruct;
Error:
if (FAILED(hr)) {
FreeBlob(prsrs);
}
FreeBlob(prsr);
return hr;
}
//
//
//
HRESULT RILDrv_GetSimRecordStatus(DWORD dwParam, DWORD dwFileID)
{
FUNCTION_TRACE(RILDrv_GetSimRecordStatus);
#if defined(OEM1_DRIVER) || defined(OEM2_DRIVER) || defined(EMP_DRIVER)
// HW-SPECIFIC: OEM1 uses a different set of AT commands than implied by 11.11
DWORD dwParameter1, dwParameter2, dwParameter3;
DWORD dwRestrictedSIMCmd;
WORD wFileID = (WORD) (dwFileID & 0xffff);
LPBYTE lpbData = NULL;
DWORD dwDataSize = 0;
LPSTR szCmd = NULL;
char szPrefix[MAX_PATH];
LPSTR szPrefixWalk = szPrefix;
HRESULT hr = S_OK;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle) {
hr = E_FAIL;
goto Error;
}
dwParameter1 = 0x00;
dwParameter2 = 0x00;
#if defined(EMP_DRIVER)
// Always request the max size to allow for USIM responses, which
// differ in structure from GSM SIM responses.
dwParameter3 = 255;
#else
// Is this an elementary file?
if (IsElementarySimFile(dwFileID))
{
// This is an elementary file -- send GET RESPONSE
dwParameter3 = 15; // min required length of response for EF
}
else
{
// This is not an elementary file
dwParameter3 = 22; // min required length of response for DF/MF
}
#endif
#if defined(OEM1_DRIVER) || defined(EMP_DRIVER)
dwRestrictedSIMCmd = g_rgdwRestrictedSIMCmds[RIL_SIMCMD_GETRESPONSE];
#else
dwRestrictedSIMCmd = g_rgdwRestrictedSIMCmds[RIL_SIMCMD_STATUS];
#endif
// Add "AT+CRSM=<command>" to prefix string
(void)_snprintfz(szPrefixWalk, MAX_PATH - (szPrefixWalk - szPrefix), "AT+CRSM=%u", dwRestrictedSIMCmd);
szPrefixWalk = strchr(szPrefixWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szPrefixWalk);
// Add ",<fileid>" to prefix string
(void)_snprintfz(szPrefixWalk, MAX_PATH - (szPrefixWalk - szPrefix), ",%u", dwFileID);
szPrefixWalk = strchr(szPrefixWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szPrefixWalk);
// Add ",<p1>,<p2>,<p3>" to prefix string
(void)_snprintfz(szPrefixWalk, MAX_PATH - (szPrefixWalk - szPrefix), ",%u,%u,%u",
dwParameter1, dwParameter2, dwParameter3);
// If there's data, add a comma before that data
if (dwDataSize)
{
strcat(szPrefixWalk, ",");
}
// Add "<prefix>\"<data>\"<CR>"
// NOTE: we take ownership of allocated szCmd
if (!ComposeCmdWithByteArray(szPrefix, lpbData, dwDataSize, "\r", szCmd)) {
hr = E_OUTOFMEMORY;
goto Error;
}
if (!QueueCmd(pHandle, szCmd, CMDOPT_NONE, APIID_GETSIMRECORDSTATUS, ParseGetSimRecordStatus, NULL, hr)) {
hr = E_FAIL;
goto Error;
}
Error:
delete szCmd;
#elif ((!defined(WAVECOM_DRIVER)) && (!defined(PHILIP_DRIVER)) )
// HW-SPECIFIC: WaveCom doesn't support AT+CSIM
// Send down a SELECT command to find out information about this file
BYTE rgbSelect[] = { 0xA4, 0x00, 0x00, 0x02, 0x00, 0x00 };
DWORD dwSize = sizeof(rgbSelect);
LPSTR szCmd = NULL;
char szPrefix[MAX_PATH];
HRESULT hr = S_OK;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle) {
hr = E_FAIL;
goto Error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -