📄 smsenc.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:
smsenc.cpp
Abstract:
Code to create an outgoing SMS message in a form that RIL can send
Notes:
--*/
#include "precomp.h"
#undef assert
#include "safeint.hxx"
//
// Convert a RILMSGDCS struct into a TP-DCS BYTE for Submit messages
// see GSM 03.38
//
static HRESULT EncodeMsgDCS(const RILMSGDCS& rmdDCS, BYTE* const pbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgDCS);
DEBUGCHK(NULL != pbOut);
HRESULT hr = S_OK;
rcbUsed = 0;
if (!(rmdDCS.dwParams & RIL_PARAM_MDCS_TYPE)) {
hr = E_INVALIDARG;
goto Error;
}
*pbOut = 0x00;
switch (rmdDCS.dwType)
{
case RIL_DCSTYPE_GENERAL:
if ((rmdDCS.dwParams & RIL_PARAM_MDCS_FLAGS) &&
(rmdDCS.dwFlags & RIL_DCSFLAG_COMPRESSED)) {
*pbOut |= 0x20;
}
if (rmdDCS.dwParams & RIL_PARAM_MDCS_MSGCLASS) {
switch (rmdDCS.dwMsgClass)
{
case RIL_DCSMSGCLASS_0:
*pbOut |= 0x10;
break;
case RIL_DCSMSGCLASS_1:
*pbOut |= 0x11;
break;
case RIL_DCSMSGCLASS_2:
*pbOut |= 0x12;
break;
case RIL_DCSMSGCLASS_3:
*pbOut |= 0x13;
break;
default:
hr = E_INVALIDARG;
goto Error;
}
}
if (rmdDCS.dwParams & RIL_PARAM_MDCS_ALPHABET) {
switch (rmdDCS.dwAlphabet)
{
case RIL_DCSALPHABET_DEFAULT:
*pbOut |= 0x00;
break;
case RIL_DCSALPHABET_8BIT:
*pbOut |= 0x04;
break;
case RIL_DCSALPHABET_UCS2:
*pbOut |= 0x08;
break;
default:
hr = E_INVALIDARG;
goto Error;
}
} else {
hr = E_INVALIDARG;
goto Error;
}
break;
case RIL_DCSTYPE_MSGWAIT:
if (!(rmdDCS.dwParams & RIL_PARAM_MDCS_FLAGS)) {
hr = E_INVALIDARG;
goto Error;
}
if (rmdDCS.dwFlags & RIL_DCSFLAG_DISCARD) {
*pbOut |= 0xc0;
} else if (rmdDCS.dwParams & RIL_PARAM_MDCS_ALPHABET) {
switch (rmdDCS.dwAlphabet)
{
case RIL_DCSALPHABET_DEFAULT:
*pbOut |= 0xd0;
break;
case RIL_DCSALPHABET_UCS2:
*pbOut |= 0xe0;
break;
default:
hr = E_INVALIDARG;
goto Error;
}
} else {
hr = E_INVALIDARG;
goto Error;
}
if (rmdDCS.dwParams & RIL_PARAM_MDCS_INDICATION &&
rmdDCS.dwFlags & RIL_DCSFLAG_INDICATIONACTIVE) {
switch (rmdDCS.dwIndication)
{
case RIL_DCSINDICATION_VOICEMAIL:
*pbOut |= 0x08;
break;
case RIL_DCSINDICATION_FAX:
*pbOut |= 0x09;
break;
case RIL_DCSINDICATION_EMAIL:
*pbOut |= 0x0a;
break;
default:
hr = E_INVALIDARG;
goto Error;
}
}
break;
case RIL_DCSTYPE_MSGCLASS:
// This type is currently not implemented
hr = E_INVALIDARG;
goto Error;
default:
hr = E_FAIL;
goto Error;
}
rcbUsed = 1;
Error:
return hr;
}
//
// Encode the Service Center Time Stamp in a SYSTEMTIME struct
// see 9.2.3.11
//
static void EncodeMsgTimeStamp(const SYSTEMTIME& stTimeStamp, BYTE* const pbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgTimeStamp);
DEBUGCHK(NULL != pbOut);
BYTE* pbWalk = pbOut;
rcbUsed = 0;
*pbWalk++ = ((stTimeStamp.wYear % 10) << 4) | ((stTimeStamp.wYear / 10) % 10);
*pbWalk++ = ((stTimeStamp.wMonth % 10) << 4) | (stTimeStamp.wMonth / 10);
*pbWalk++ = ((stTimeStamp.wDay % 10) << 4) | (stTimeStamp.wDay / 10);
*pbWalk++ = ((stTimeStamp.wHour % 10) << 4) | (stTimeStamp.wHour / 10);
*pbWalk++ = ((stTimeStamp.wMinute % 10) << 4) | (stTimeStamp.wMinute / 10);
*pbWalk++ = ((stTimeStamp.wSecond % 10) << 4) | (stTimeStamp.wSecond / 10);
*pbWalk++ = 0; // Set time zone to UTC
rcbUsed = pbWalk - pbOut;
}
//
//
//
// GSM 3.40, Section 9.2.3.12.1
//
// TP-VP Value Validity period value Range
// ----------------------------------
// 0 - 143 (TP-VP + 1) x 5 minutes 5 mins - 720 mins (.5 day)
// 144 - 167 12 hours + ((TP-VP - 143) x 30 minutes) 750 mins - 1440 mins (1 day)
// 168 - 196 (TP-VP - 166) x 1 day 2 days - 30 days (43200 mins)
// 197 - 255 (TP-VP - 192) x 1 week 35 days - 441 days (635040 mins)
//
//
// This function encodes a SYSTEMTIME structure into a TP-VP Value according to the chart above.
// Only a subset of the SYSTEMTIME structure is used: wDay, wHour, wMinute. These are the only
// units that have a consistent conversion, and values greater than 441 days are not used, so
// these members are sufficient for expressing any supported validity period.
//
// If the expressed system time does not fall exactly onto a validity period increment, then
// the period is rounded up to the next increment.
//
static void EncodeRelativeValidityPeriod(const SYSTEMTIME& stVP, BYTE* const pbOut, UINT& rcbUsed)
{
UINT uMinutes = 0;
uMinutes = stVP.wMinute + 60 * (stVP.wHour + 24 * stVP.wDay);
if (0 == uMinutes)
{
*pbOut = 0;
}
else if (uMinutes <= 720)
{
*pbOut = (BYTE)((uMinutes+4) / 5) - 1;
}
else if (uMinutes <= 1440)
{
*pbOut = (BYTE)((uMinutes+29) / 30) + 119;
}
else if (uMinutes <= 43200)
{
*pbOut = (BYTE)((uMinutes+1439) / 1440) + 166;
}
else if (uMinutes <= 635040)
{
*pbOut = (BYTE)((uMinutes+10079) / 10080) + 192;
}
else
{
*pbOut = 255;
}
rcbUsed = 1;
}
//
// Convert a VP time stamp to BYTE data
// see GSM 03.40 section 9.2.3.12
//
static HRESULT EncodeMsgValidityPeriod(const SYSTEMTIME& stVP, const DWORD dwVPFormat, BYTE* const pbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgValidityPeriod);
DEBUGCHK(NULL != pbOut);
HRESULT hr = S_OK;
BYTE* pbWalk = pbOut;
rcbUsed = 0;
if (RIL_MSGVP_ABSOLUTE == dwVPFormat) {
EncodeMsgTimeStamp(stVP, pbOut, rcbUsed);
} else {
switch (dwVPFormat)
{
case RIL_MSGVP_NONE:
// Do nothing
break;
case RIL_MSGVP_ENHANCED:
// Enhanced isn't supported. We should never get here,
// but just in case, treat the SYSTEMTIME as relative.
case RIL_MSGVP_RELATIVE:
EncodeRelativeValidityPeriod(stVP, pbOut, rcbUsed);
break;
default:
hr = E_INVALIDARG;
goto Error;
}
}
Error:
return hr;
}
//
// Function to encode an address from an RILADDRESS struct
// see GSM 03.40 section 9.1.2.5
//
static HRESULT EncodeMsgAddress(const RILADDRESS& raAddress, const BOOL fBeforePDU, BYTE* const pbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgAddress);
DEBUGCHK(NULL != pbOut);
HRESULT hr = S_OK;
UINT j;
UINT cchAddressLen;
BYTE bTypeOfAddress;
UINT nTemp;
WCHAR wszRILAddress[MAXLENGTH_ADDRESS + 1];
LPWSTR wszRILAddressWalk;
char szAddress[MAXLENGTH_ADDRESS + 1];
WCHAR wszBuffer[2];
BYTE* pbWalk = pbOut;
rcbUsed = 0;
if (!(raAddress.dwParams & RIL_PARAM_A_ADDRESS) ||
!(raAddress.dwParams & RIL_PARAM_A_TYPE)) {
// Address and type must be specified
hr = E_INVALIDARG;
goto Error;
}
if (NUM_ADDRTYPES <= raAddress.dwType) {
// Incorrect type specified
hr = E_INVALIDARG;
goto Error;
}
// Set address type, top bit is always set
bTypeOfAddress = 0x80 | (g_rgbAddrTypes[raAddress.dwType] << 4);
// Set numplan type, if necessary
if (RIL_ADDRTYPE_UNKNOWN == raAddress.dwType ||
RIL_ADDRTYPE_INTERNATIONAL == raAddress.dwType ||
RIL_ADDRTYPE_NATIONAL == raAddress.dwType) {
if (!(raAddress.dwParams & RIL_PARAM_A_NUMPLAN) ||
NUM_NUMPLANS <= raAddress.dwNumPlan) {
hr = E_INVALIDARG;
goto Error;
}
bTypeOfAddress |= g_rgbNumPlans[raAddress.dwNumPlan];
}
// Copy the address, removing all unwanted characters (Ex: '(', '-', '.')
// Note that '+' is automatically removed from INTERNATIONAL addresses
wszRILAddressWalk = wszRILAddress;
C_ASSERT(ARRAY_LENGTH(raAddress.wszAddress) < ARRAY_LENGTH(wszRILAddress));
for(j = 0 ; j < ARRAY_LENGTH(raAddress.wszAddress) ; j++) {
if(strchr("1234567890*#ABCD", raAddress.wszAddress[j])) {
*wszRILAddressWalk++ = raAddress.wszAddress[j];
} else if(L'\0' == raAddress.wszAddress[j]) {
break; // Done
}
}
*wszRILAddressWalk = L'\0';
// Note: Untested for ALPHANUM addresses
cchAddressLen = wcslen(wszRILAddress);
if (fBeforePDU) {
*pbWalk++ = ((cchAddressLen + 1)/ 2) + 1;
} else {
*pbWalk++ = cchAddressLen;
}
*pbWalk++ = bTypeOfAddress;
if (RIL_ADDRTYPE_ALPHANUM == raAddress.dwType) {
hr = RILAddressToString(raAddress, szAddress, MAXLENGTH_ADDRESS + 1, bTypeOfAddress);
if (FAILED(hr)) {
goto Error;
}
DEBUGCHK(strlen(szAddress) <= MAXLENGTH_ADDRESS);
memcpy(pbWalk, szAddress, strlen(szAddress));
} else {
wszBuffer[1] = L'\0'; // Not changed below
for (j = 0; j < cchAddressLen; j += 2) {
wszBuffer[0] = wszRILAddress[j];
nTemp = _wtoi(wszBuffer);
*pbWalk = nTemp;
if (j + 1 < cchAddressLen) {
wszBuffer[0] = wszRILAddress[j + 1];
nTemp = _wtoi(wszBuffer);
*pbWalk++ |= nTemp << 4;
} else {
*pbWalk++ |= 0xf0;
}
}
}
rcbUsed = pbWalk - pbOut;
Error:
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -