📄 rilsimtkitbyte.cpp
字号:
case 0x81:
// Mixed encoding -- the next byte is the length of the string, the byte after that
// gives us information about the base code page, and then comes the string
dwTextLen = (DWORD) *(m_lpbParse + 1);
if (dwTextLen > (dwLength - 4))
{
// That doesn't make sense
hr = E_INVALIDARG;
goto Exit;
}
// Base page is bits 15 to 7
uiBasePage = ((DWORD) *(m_lpbParse + 2)) << 7;
fRetVal = ConvertGSMMixedToUnicode(uiBasePage, (LPCSTR) (m_lpbParse + 3), dwTextLen,
pwsz, dwLength, uiUsedLen);
break;
case 0x82:
// Mixed encoding -- the next byte is the length of the string, the next two bytes
// give us information about the base code page, and then comes the string
dwTextLen = (DWORD) *(m_lpbParse + 1);
if (dwTextLen > (dwLength - 5))
{
// That doesn't make sense
hr = E_INVALIDARG;
goto Exit;
}
// Base page is bits 15 to 7
uiBasePage = (((DWORD) *(m_lpbParse + 2)) << 8) + ((DWORD) *(m_lpbParse + 3));
fRetVal = ConvertGSMMixedToUnicode(uiBasePage, (LPCSTR) (m_lpbParse + 4), dwTextLen,
pwsz, dwLength, uiUsedLen);
break;
default:
// Note that in the default case the encoding byte is part of the string itself
// This means it's the default GSM 7-bit alphabet, unpacked
// Per GSM 11.11, Annex B, we should ignore any FF characters at the end of this string
lpbTemp = m_lpbParse + dwLength - 1;
while ((lpbTemp >= m_lpbParse) && (*lpbTemp == 0xFF))
{
lpbTemp--;
}
// Start parsing at the first byte, up to the last non-0xFF byte.
fRetVal = ConvertUnpackedGSMToUnicode((LPCSTR) m_lpbParse, (lpbTemp + 1 - m_lpbParse), pwsz, dwLength, uiUsedLen);
if(!fRetVal)
{
RETAILMSG(1, (TEXT("[TI]RilDrv : SIMTKit: CRilSimToolkitCommand::ReadEFADNText ConvertUnpackedGSMToUnicode fail, encoding %x, dwLength is %d\r\n"), bEncode, dwLength));
fRetVal = Convert8bitGSMToUnicode(m_lpbParse, (lpbTemp + 1 - m_lpbParse), pwsz, dwLength, uiUsedLen);
}
break;
}
if (!fRetVal)
{
// This wasn't set
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Failed to parse bytes, encoding %x\r\n"), bEncode));
hr = E_INVALIDARG;
goto Exit;
}
}
// OK, NULL terminate this
pwsz[uiUsedLen] = TEXT('\0');
m_lpbParse += dwLength;
m_dwParseLen -= dwLength;
// DEBUGMSG(ZONE_INFO, (TEXT("RilDrv : SIMTKit: Text %s, length remaining %d\r\n"), pwsz, m_dwParseLen));
Exit:
if (FAILED(hr))
{
*pdwUsedLen = 0;
delete [] pwsz;
pwsz = NULL;
}
else
{
*pdwUsedLen = (uiUsedLen + 1) * sizeof(TCHAR);
}
if (NULL != ppwszText)
{
*ppwszText = pwsz;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: -CRilSimToolkitCommand::ReadEFADNText\r\n")));
return hr;
}
/****************************************************************************
FUNCTION: ReadCmdLength
PURPOSE: The length can be either 1 or 2 bytes (per Annex D, 11.14)
PARAMETERS: pdwLength - The length
RETURNS: HRESULT
****************************************************************************/
HRESULT CRilSimToolkitCommand::ReadCmdLength(DWORD *pdwLength)
{
HRESULT hr = E_FAIL;
DWORD dwLength = 0;
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: +CRilSimToolkitCommand::ReadCmdLength\r\n")));
// m_dwParseLen better be at least 1
if (m_dwParseLen >= 1)
{
// Next comes the length of what follows, it can be 1 or 2 bytes in length
dwLength = (DWORD) (*(m_lpbParse++));
m_dwParseLen--;
if (dwLength == 0x81)
{
// This means the length is really in the second byte -- better have another byte
if (m_dwParseLen >= 1)
{
dwLength = (DWORD) (*(m_lpbParse++));
m_dwParseLen--;
if ((dwLength >= 0x80) && (dwLength <= 0xff))
{
// This is good
hr = S_OK;
}
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Length of %d in second byte invalid\r\n"), dwLength));
}
}
}
else if ((dwLength >= 0x00) && (dwLength <= 0x7F))
{
// This is good
hr = S_OK;
}
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: CmdLength first byte of %d is invalid\r\n"), dwLength));
}
}
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Not enough bytes left to read CmdLength\r\n")));
}
*pdwLength = dwLength;
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: -CRilSimToolkitCommand::ReadCmdLength\r\n")));
return hr;
}
/****************************************************************************
FUNCTION: ReadCommonTextString
PURPOSE: Reads a text string
PARAMETERS: ppwszText - Pointer to the text to read (we allocate it)
pdwLen - The length of this string, in bytes
RETURNS: HRESULT
****************************************************************************/
HRESULT CRilSimToolkitCommand::ReadCommonTextString(TCHAR **ppwszText, DWORD *pdwLen)
{
HRESULT hr = S_OK;
DWORD dwLength;
UINT uiLen;
UINT uiUsedLen = 0;
BYTE bEncode, bScheme;
LPCSTR lpcstr;
BOOL fRetVal = FALSE;
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: +CRilSimToolkitCommand::ReadCommonTextString\r\n")));
ASSERT(*ppwszText == NULL);
// First read the length of the text
hr = ReadCmdLength(&dwLength);
if (FAILED(hr))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: ReadCmdLength failed %x\r\n"), hr));
goto Exit;
}
if (m_dwParseLen < dwLength)
{
// Well, that can't be
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Expected %d bytes, only have %d\r\n"), dwLength, m_dwParseLen));
hr = E_FAIL;
goto Exit;
}
if (!dwLength)
{
// We've received a null text string which is valid, No further work is necessary,
// so just return a positive result.
hr = S_OK;
goto Exit;
}
// OK, figure out the encoding
bEncode = *(m_lpbParse++);
lpcstr = (LPCSTR) m_lpbParse;
// Allocate enough space -- the worst it could be is 8/7 times the number of characters
// that are remaining
uiLen = 1 + ((8 * dwLength) / 7);
*ppwszText = new TCHAR[uiLen];
if (!(*ppwszText))
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Coded as per SMS Data Coding in 03.38 (section 4)
// We will set bScheme to 0-3 to indicate how this is encoded, 0 = 8-bit, 1 = default alphabet,
// 2 = default alphabet uncompressed, 3 = UCS2
if ((bEncode & 0xf0) == 0xf0)
{
bScheme = (BYTE) ((bEncode & 0x04) ? 0x0 : 0x1);
}
else if ((bEncode & 0xc0) == 0x00)
{
if (bEncode & 0x08)
{
// This is UCS2 format
bScheme = 3;
}
else
{
// Is it packed or not?
if (bEncode & 0x20)
{
// This is packed format
bScheme = 1;
}
else if (bEncode & 0x04)
{
// 8-bit data format
bScheme = 0;
}
else if (bEncode == 0x00)
{
// Special case, all bits zero means packed format
bScheme = 1;
}
else
{
// Use unpacked format
bScheme = 2;
}
}
}
else
{
// This shouldn't happen -- assert and assume it's 8bit information
ASSERT(FALSE);
bScheme = 0;
}
switch (bScheme)
{
case 1:
// This is packed format
fRetVal = ConvertGSMToUnicode(lpcstr, dwLength - 1, *ppwszText, uiLen, uiUsedLen);
break;
// As per 11.14, section 12.15.1, 8-bit data is really meant to be interpreted as unpacked
// SMS default alphabet.
case 0:
case 2:
// Use unpacked format
fRetVal = ConvertUnpackedGSMToUnicode(lpcstr, dwLength - 1, *ppwszText, uiLen, uiUsedLen);
if(!fRetVal)
{
RETAILMSG(1,(TEXT("[TI]RilDrv : SIMTKit: CRilSimToolkitCommand::ReadCommonTextString dwLength is %d\r\n"), dwLength));
fRetVal = Convert8bitGSMToUnicode(m_lpbParse, dwLength - 1, *ppwszText, uiLen, uiUsedLen);
}
break;
case 3:
// This is UCS2 format
fRetVal = ConvertUCS2ToUnicode(lpcstr, dwLength - 1, *ppwszText, uiLen, uiUsedLen);
break;
default:
// Huh?
ASSERT(FALSE);
break;
}
if (!fRetVal)
{
// There was a problem
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Couldn't convert string with scheme %x\r\n"), bScheme));
DebugBreak();
hr = E_FAIL;
goto Exit;
}
// Add the NULL terminator
(*ppwszText)[uiUsedLen] = TEXT('\0');
*pdwLen = ((uiUsedLen + 1) * sizeof(TCHAR));
m_lpbParse += (dwLength - 1);
m_dwParseLen -= dwLength;
// DEBUGMSG(ZONE_INFO, (TEXT("RilDrv : SIMTKit: CommonTextString %s, length remaining %d\r\n"), *ppwszText, m_dwParseLen));
Exit:
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: -CRilSimToolkitCommand::ReadCommonTextString\r\n")));
return hr;
}
/****************************************************************************
FUNCTION: ReadCommonEFADNText
PURPOSE: Parses text encoded as per EF-ADN.
PARAMETERS: ppwszText - Pointer to the text to read (we allocate it)
pdwLen - The length of this string, in bytes
RETURNS: HRESULT
****************************************************************************/
HRESULT CRilSimToolkitCommand::ReadCommonEFADNText(TCHAR **ppwszText, DWORD *pdwLen)
{
HRESULT hr = S_OK;
DWORD dwLength;
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: +CRilSimToolkitCommand::ReadCommonEFADNText\r\n")));
ASSERT(*ppwszText == NULL);
// First read the length of the text
hr = ReadCmdLength(&dwLength);
if (FAILED(hr))
{
goto Exit;
}
// The text is coded as in EF-ADN
hr = ReadEFADNText(ppwszText, dwLength, pdwLen);
DEBUGMSG(ZONE_INFO, (TEXT("RilDrv : SIMTKit: Read EFADN Text %s (%x)\r\n"), *ppwszText, hr));
Exit:
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: -CRilSimToolkitCommand::ReadCommonEFADNText\r\n")));
return hr;
}
/****************************************************************************
FUNCTION: ReadCommonByte
PURPOSE: Reads a byte.
PARAMETERS: pbData - Pointer to the Byte
RETURNS: HRESULT
****************************************************************************/
HRESULT CRilSimToolkitCommand::ReadCommonByte(DWORD *pdwData)
{
HRESULT hr = S_OK;
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: +CRilSimToolkitCommand::ReadCommonByte\r\n")));
// Note, we will now read 2 more bytes, so we'd better have it!
if (m_dwParseLen < 2)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Need 2 bytes, only have %d\r\n"), m_dwParseLen));
hr = E_FAIL;
goto Exit;
}
// Second byte is length, which should be 1
if (*(m_lpbParse++) != 1)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Second byte is %x, should be 1\r\n"), *(m_lpbParse - 1)));
hr = E_FAIL;
goto Exit;
}
// Third byte is data
*pdwData = (DWORD) *(m_lpbParse++);
m_dwParseLen -= 2;
DEBUGMSG(ZONE_INFO, (TEXT("RilDrv : SIMTKit: Byte is 0x%x, length remaining %d\r\n"), *pdwData, m_dwParseLen));
Exit:
DEBUGMSG(ZONE_FUNCTION, (TEXT("RilDrv : SIMTKit: -CRilSimToolkitCommand::ReadCommonByte\r\n")));
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -