📄 misc.cpp
字号:
pbATRDataWalk = pATRInfo->rgbATR;
// Check that the data is not larger than the space available in the structure.
if (cbATRData > ARRAY_LENGTH(pATRInfo->rgbATR))
{
DEBUGCHK(!"ATR Data is larger than the structure buffer.");
hr = E_FAIL;
goto Error;
}
// Walk through the ATR string and convert to bytes.
for (uiCurATRChar = 0 ; uiCurATRChar < cbATRData ; uiCurATRChar++)
{
*pbATRDataWalk = SemiByteCharsToByte(*pchATRStringWalk, *(pchATRStringWalk + 1));
pbATRDataWalk++;
pchATRStringWalk += 2;
}
// Everything is parsed, finish setting all the fields of the structure.
pATRInfo->cbATRSize = cbATRData;
pATRInfo->dwPhase = uiPhase;
pATRInfo->dwParams = RIL_PARAM_ATR_ALL;
// Everything is finished. Assign the results to the output parameters
pBlob = pATRInfo;
cbBlob = sizeof(RILATRINFO);
Error:
if (FAILED(hr))
{
FreeBlob(pATRInfo);
}
return hr;
return S_OK;
}
//
//
//
HRESULT RILDrv_GetATR(DWORD dwParam)
{
FUNCTION_TRACE(RILDrv_GetATR);
#if defined(OEM1_DRIVER)
HRESULT hr = S_OK;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle) {
hr = E_FAIL;
goto Error;
}
if(!QueueCmd(pHandle, "AT%ATR?\r", CMDOPT_IGNORERADIOOFF | CMDOPT_SUPPRESSLOGGING, APIID_GETATR, ParseATRInfo, NULL, hr))
{
hr = E_FAIL;
goto Error;
}
Error:
#else // !defined(OEM1_DRIVER)
HRESULT hr = E_NOTIMPL;
#endif // defined(OEM1_DRIVER)
return hr;
}
//
//
//
HRESULT ParseSendRestrictedSimCmd(LPCSTR szRsp, void*& pBlob, UINT& cbBlob)
{
FUNCTION_TRACE(ParseSendRestrictedSimCmd);
UINT i;
UINT nSW1;
UINT nSW2;
LPSTR szResponseString = NULL;
UINT cbResponseString;
UINT cbStruct;
BYTE* pbResponseWalk;
LPSTR pchResponseStringWalk;
RILSIMRESPONSE* prsr = NULL;
HRESULT hr = S_OK;
pBlob = NULL;
cbBlob = 0;
ASSERT(szRsp);
// Parse "<prefix>+CRSM: <sw1>,<sw2>"
if (!szRsp ||
!ParseRspPrefix(szRsp, szRsp) ||
!MatchStringBeginning(szRsp, "+CRSM: ", szRsp) ||
!ParseUInt(szRsp, TRUE, nSW1, szRsp) ||
!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nSW2, szRsp)) {
hr = E_FAIL;
goto Error;
}
// Parse ","
if (!MatchStringBeginning(szRsp, ",", szRsp)) {
// No response data present
cbStruct = sizeof(RILSIMRESPONSE);
} else {
// Parse "<response>"
// NOTE: we take ownership of allocated szResponseString
#if defined(OEM2_DRIVER)
if (!ParseUnlimitedString(szRsp, szResponseString, cbResponseString, szRsp)) {
#else
if (!ParseUnlimitedUnquotedString(szRsp, '\r', szResponseString, cbResponseString, szRsp)) {
#endif
hr = E_FAIL;
goto Error;
}
DEBUGCHK(0 == (cbResponseString - 1) % 2);
cbStruct = sizeof(RILSIMRESPONSE) + (cbResponseString - 1) / 2;
}
// Allocate the structure of needed size
prsr = (RILSIMRESPONSE*)AllocBlob(cbStruct);
if (!prsr) {
hr = E_OUTOFMEMORY;
goto Error;
}
memset(prsr, 0x00, cbStruct);
prsr->dwParams = (RIL_PARAM_SR_STATUSWORD1 | RIL_PARAM_SR_STATUSWORD2);
// Decode the reponse data, if present
if (sizeof(RILSIMRESPONSE) < cbStruct) {
pbResponseWalk = prsr->pbResponse;
pchResponseStringWalk = szResponseString;
for (i = 0; i < cbStruct - sizeof(RILSIMRESPONSE); i++) {
*pbResponseWalk = SemiByteCharsToByte(*pchResponseStringWalk, *(pchResponseStringWalk + 1));
pbResponseWalk++;
pchResponseStringWalk += 2;
}
prsr->dwParams |= RIL_PARAM_SR_RESPONSE;
}
prsr->cbSize = cbStruct;
prsr->dwStatusWord1 = nSW1;
prsr->dwStatusWord2 = nSW2;
// Parse "<postfix>"
if (!ParseRspPostfix(szRsp, szRsp)) {
hr = E_FAIL;
goto Error;
}
pBlob = (void*)prsr;
cbBlob = cbStruct;
Error:
if (FAILED(hr)) {
FreeBlob(prsr);
}
delete[] szResponseString;
return hr;
}
//
//
//
HRESULT RILDrv_SendRestrictedSimCmd(DWORD dwParam, DWORD dwCommand, const RILSIMCMDPARAMETERS* lpParameters,
const BYTE* lpbData, DWORD dwSize)
{
FUNCTION_TRACE(RILDrv_SendRestrictedSimCmd);
#ifndef WAVECOM_DRIVER
// HW-SPECIFIC: WaveCom hardware doesn't support AT+CRSM
DEBUGCHK(0 != dwCommand);
DEBUGCHK(NUM_RESTRICTEDSIMCMDS > dwCommand);
LPSTR szCmd = NULL;
char szPrefix[MAX_PATH];
LPSTR szPrefixWalk = szPrefix;
UINT cbDataSizeToUse = 0;
HRESULT hr = S_OK;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle || !lpbData) {
hr = E_FAIL;
goto Error;
}
if(g_bRadioOff)
{
// Send a no-op AT command to force an OK response
if (!QueueCmd(pHandle, NULL, CMDOPT_NOOP, APIID_DEVSPECIFIC, NULL, NULL, hr)) {
hr = E_FAIL;
goto Error;
}
}
// Add "AT+CRSM=<command>" to prefix string
(void)_snprintfz(szPrefixWalk, MAX_PATH - (szPrefixWalk - szPrefix), "AT+CRSM=%u", g_rgdwRestrictedSIMCmds[dwCommand]);
szPrefixWalk = strchr(szPrefixWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szPrefixWalk);
if (lpParameters && (lpParameters->dwParams & RIL_PARAM_SCP_FILEID)) {
// Add ",<fileid>" to prefix string
(void)_snprintfz(szPrefixWalk, MAX_PATH - (szPrefixWalk - szPrefix), ",%u", lpParameters->dwFileID);
szPrefixWalk = strchr(szPrefixWalk, '\0'); // NO_TYPO: 27
DEBUGCHK(NULL != szPrefixWalk);
if ((lpParameters->dwParams & RIL_PARAM_SCP_PARAM1) &&
(lpParameters->dwParams & RIL_PARAM_SCP_PARAM2) &&
(lpParameters->dwParams & RIL_PARAM_SCP_PARAM3)) {
// Add ",<p1>,<p2>,<p3>" to prefix string
(void)_snprintfz(szPrefixWalk, MAX_PATH - (szPrefixWalk - szPrefix), ",%u,%u,%u",
lpParameters->dwParameter1, lpParameters->dwParameter2, lpParameters->dwParameter3);
// If there's data, add a comma before that data
if (dwSize)
{
strcat(szPrefixWalk, ",");
cbDataSizeToUse = dwSize;
}
}
}
// Add "<prefix>\"<data>\"<CR>"
// NOTE: we take ownership of allocated szCmd
if (!ComposeCmdWithByteArray(szPrefix, lpbData, cbDataSizeToUse, "\r", szCmd)) {
hr = E_OUTOFMEMORY;
goto Error;
}
if (!QueueCmd(pHandle, szCmd, CMDOPT_NONE, APIID_SENDRESTRICTEDSIMCMD, ParseSendRestrictedSimCmd, NULL, hr)) {
hr = E_FAIL;
goto Error;
}
Error:
delete szCmd;
#else // WAVECOM_DRIVER
HRESULT hr = E_NOTIMPL;
#endif // WAVECOM_DRIVER
return hr;
}
//
//
//
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;
}
// 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)
// 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;
// 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
}
#if defined(OEM1_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -