📄 misc.cpp
字号:
!MatchStringBeginning(szRsp, "+CSIM: ", szRsp) ||
!ParseUInt(szRsp, TRUE, nValue, szRsp) ||
!MatchStringBeginning(szRsp, ",", szRsp)) {
hr = E_FAIL;
goto Error;
}
DEBUGCHK(0 == nValue % 2);
if (0 < nValue) {
// Allocate the storage
cbResponse = nValue / 2;
pbResponse = (BYTE *)AllocBlob(cbResponse);
if (!pbResponse) {
hr = E_OUTOFMEMORY;
goto Error;
}
pbResponseWalk = pbResponse;
for (i = 0; i < cbResponse; i++) {
if (!*szRsp || !*(szRsp + 1)) {
hr = E_FAIL;
goto Error;
}
*pbResponseWalk = SemiByteCharsToByte(*szRsp, *(szRsp + 1));
pbResponseWalk++;
szRsp += 2;
}
// Parse "<postfix>"
if (!ParseRspPostfix(szRsp, szRsp)) {
hr = E_FAIL;
goto Error;
}
}
else {
// Special case where the response was 0 length.
// Handle it by trashing the rest of the response.
DEBUGCHK(FALSE);
if (!MatchStringAnywhere(szRsp, "\r\n", szRsp))
{
hr = E_FAIL;
goto Error;
}
}
pBlob = (void*)pbResponse;
cbBlob = cbResponse;
Error:
if (FAILED(hr)) {
FreeBlob(pbResponse);
}
return hr;
}
//
//
//
HRESULT RILDrv_SendSimCmd(DWORD dwParam, const BYTE* lpbCommand, DWORD dwSize)
{
FUNCTION_TRACE(RILDrv_SendSimCmd);
#if defined(OEM1_DRIVER)
// HW-SPECIFIC: WaveCom does not support AT+CSIM
DEBUGCHK(NULL != lpbCommand);
DEBUGCHK(0 != dwSize);
LPSTR szCmd = NULL;
char szPrefix[MAX_PATH];
HRESULT hr = S_OK;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle || !lpbCommand) {
hr = E_FAIL;
goto Error;
}
// Add "AT+CSIM=<length>," to prefix string
(void)_snprintfz(szPrefix, MAX_PATH, "AT+CSIM=%u,", dwSize * 2);
// Add "<prefix>\"<command>\"<CR>"
// NOTE: we take ownership of allocated szCmd
if (!ComposeCmdWithByteArray(szPrefix, lpbCommand, dwSize, "\r", szCmd)) {
hr = E_OUTOFMEMORY;
goto Error;
}
if (!QueueCmd(pHandle, szCmd, CMDOPT_NONE | CMDOPT_SUPPRESSLOGGING, APIID_SENDSIMCMD, ParseSendSimCmd, NULL, hr)) {
hr = E_FAIL;
goto Error;
}
Error:
delete szCmd;
#else // defined(OEM1_DRIVER)
HRESULT hr = E_NOTIMPL;
#endif // defined(OEM1_DRIVER)
return hr;
}
//
//
//
HRESULT ParseATRInfo(LPCSTR szRsp, void*& pBlob, UINT& cbBlob)
{
FUNCTION_TRACE(ParseATRInfo);
HRESULT hr = S_OK;
RILATRINFO* pATRInfo = NULL;
UINT uiPhase;
UINT uiCurATRChar;
UINT cbATRString;
UINT cbATRData;
LPSTR szATRString = NULL;
LPSTR pchATRStringWalk;
BYTE* pbATRDataWalk;
// Check parameters
if (NULL == szRsp)
{
DEBUGCHK(FALSE);
return E_INVALIDARG;
}
// Initialize output parameters
pBlob = NULL;
cbBlob = 0;
pATRInfo = (RILATRINFO*)AllocBlob(sizeof(RILATRINFO));
if (NULL == pATRInfo)
{
DEBUGCHK(FALSE);
hr = E_OUTOFMEMORY;
goto Error;
}
memset(pATRInfo, 0, sizeof(RILATRINFO));
pATRInfo->cbSize = sizeof(RILATRINFO);
// Parse "<prefix>%ATR: <Phase>,<ATR>"
// We take ownership of szATRString and are responsible for freeing the memory.
if (!ParseRspPrefix(szRsp, szRsp) ||
!MatchStringBeginning(szRsp, "%ATR: ", szRsp) ||
!ParseHexUInt(szRsp, TRUE, uiPhase, szRsp) ||
!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUnlimitedUnquotedString(szRsp, '\r', szATRString, cbATRString, szRsp)) {
hr = E_FAIL;
goto Error;
}
// Assert that the data we received is an even length.
DEBUGCHK(0 == (cbATRString-1) % 2);
cbATRData = (cbATRString-1) / 2;
pchATRStringWalk = szATRString;
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) || defined(EMP_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;
}
#ifdef PHILIP_DRIVER
//
//
//
HRESULT RILDrv_SendRestrictedSimCmd(DWORD dwParam, DWORD dwCommand, const RILSIMCMDPARAMETERS* lpParameters,
const BYTE* lpbData, DWORD dwSize)
{
FUNCTION_TRACE(RILDrv_SendRestrictedSimCmd);
HRESULT hr = E_NOTIMPL;
return hr;
}
#else
//
//
//
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;
}
#ifdef EMP_DRIVER
// EMP does not support RIL_SIMCMD_STATUS
if (RIL_SIMCMD_STATUS == dwCommand)
{
hr = E_NOTIMPL;
goto Error;
}
#endif
// 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;
}
#if defined(EMP_DRIVER)
class BerTlv
{
public:
BerTlv() : m_bTag(0), m_uLen(0), m_pbValue(NULL), m_uTotalSize(0) {};
BerTlv(const BYTE* pRawData, UINT cbSize);
~BerTlv() {};
BYTE GetTag() {return m_bTag;};
UINT GetLength() {return m_uLen;};
const BYTE* GetValue() {return m_pbValue;};
UINT GetTotalSize() {return m_uTotalSize;};
BOOL BerTlv::Parse(const BYTE* pRawData, UINT cbSize);
private:
BYTE m_bTag;
UINT m_uLen;
const BYTE* m_pbValue;
UINT m_uTotalSize;
};
BerTlv::BerTlv(const BYTE* pRawData, UINT cbSize)
{
Parse(pRawData, cbSize);
}
BOOL BerTlv::Parse(const BYTE* pRawData, UINT cbSize)
{
if (2 > cbSize) {
// Not enough data for a TLV.
return FALSE;
}
// Tag at index 0.
BYTE bTag = pRawData[0];
if (0 == bTag ||
0xFF == bTag) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -