📄 smsenc.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
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.
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"
//
// Address types
//
const BYTE g_rgbAddrTypes[] =
{
0x00, // RIL_ADDRTYPE_UNKNOWN
0x01, // RIL_ADDRTYPE_INTERNATIONAL
0x02, // RIL_ADDRTYPE_NATIONAL
0x03, // RIL_ADDRTYPE_NETWKSPECIFIC
0x04, // RIL_ADDRTYPE_SUBSCRIBER
0x05, // RIL_ADDRTYPE_ALPHANUM
0x06, // RIL_ADDRTYPE_ABBREV
};
const size_t fAddrTypesEcount = (sizeof(g_rgbAddrTypes) / sizeof(*g_rgbAddrTypes));
//
// Numbering plans
//
const BYTE g_rgbNumPlans[] =
{
0x00, // RIL_NUMPLAN_UNKNOWN
0x01, // RIL_NUMPLAN_TELEPHONE
0x03, // RIL_NUMPLAN_DATA
0x04, // RIL_NUMPLAN_TELEX
0x08, // RIL_NUMPLAN_NATIONAL
0x09, // RIL_NUMPLAN_PRIVATE
0x0a, // RIL_NUMPLAN_ERMES
};
const size_t fNumPlansEcount = (sizeof(g_rgbNumPlans) / sizeof(BYTE));
//
// ProtocolID types
//
const DWORD g_rgdwProtocolIDs[] =
{
0x00, // RIL_MSGPROTOCOL_UNKNOWN
0x00, // RIL_MSGPROTOCOL_SMETOSME
0x20, // RIL_MSGPROTOCOL_IMPLICIT
0x21, // RIL_MSGPROTOCOL_TELEX
0x22, // RIL_MSGPROTOCOL_TELEFAX_GROUP3
0x23, // RIL_MSGPROTOCOL_TELEFAX_GROUP4
0x24, // RIL_MSGPROTOCOL_VOICEPHONE
0x25, // RIL_MSGPROTOCOL_ERMES
0x26, // RIL_MSGPROTOCOL_PAGING
0x27, // RIL_MSGPROTOCOL_VIDEOTEX
0x28, // RIL_MSGPROTOCOL_TELETEX
0x29, // RIL_MSGPROTOCOL_TELETEX_PSPDN
0x2a, // RIL_MSGPROTOCOL_TELETEX_CSPDN
0x2b, // RIL_MSGPROTOCOL_TELETEX_PSTN
0x2c, // RIL_MSGPROTOCOL_TELETEX_ISDN
0x2d, // RIL_MSGPROTOCOL_UCI
0x30, // RIL_MSGPROTOCOL_MSGHANDLING
0x31, // RIL_MSGPROTOCOL_X400
0x32, // RIL_MSGPROTOCOL_EMAIL
0x38, // RIL_MSGPROTOCOL_SCSPECIFIC1
0x39, // RIL_MSGPROTOCOL_SCSPECIFIC2
0x3a, // RIL_MSGPROTOCOL_SCSPECIFIC3
0x3b, // RIL_MSGPROTOCOL_SCSPECIFIC4
0x3c, // RIL_MSGPROTOCOL_SCSPECIFIC5
0x3d, // RIL_MSGPROTOCOL_SCSPECIFIC6
0x3e, // RIL_MSGPROTOCOL_SCSPECIFIC7
0x3f, // RIL_MSGPROTOCOL_GSMSTATION
0x40, // RIL_MSGPROTOCOL_SM_TYPE0
0x41, // RIL_MSGPROTOCOL_RSM_TYPE1
0x42, // RIL_MSGPROTOCOL_RSM_TYPE2
0x43, // RIL_MSGPROTOCOL_RSM_TYPE3
0x44, // RIL_MSGPROTOCOL_RSM_TYPE4
0x45, // RIL_MSGPROTOCOL_RSM_TYPE5
0x46, // RIL_MSGPROTOCOL_RSM_TYPE6
0x47, // RIL_MSGPROTOCOL_RSM_TYPE7
0x5f, // RIL_MSGPROTOCOL_RETURNCALL
0x7d, // RIL_MSGPROTOCOL_ME_DOWNLOAD
0x7e, // RIL_MSGPROTOCOL_DEPERSONALIZATION
0x7f, // RIL_MSGPROTOCOL_SIM_DOWNLOAD
};
const size_t fProtocolIdsEcount = (sizeof(g_rgdwProtocolIDs) / sizeof(DWORD));
//
// Status-Report values
//
const DWORD g_rgdwDlvStatus[] =
{
0xff, // UNUSED
0x00, // RIL_MSGDLVSTATUS_RECEIVEDBYSME
0x01, // RIL_MSGDLVSTATUS_FORWARDEDTOSME
0x02, // RIL_MSGDLVSTATUS_REPLACEDBYSC
0x20, // RIL_MSGDLVSTATUS_CONGESTION_TRYING
0x21, // RIL_MSGDLVSTATUS_SMEBUSY_TRYING
0x22, // RIL_MSGDLVSTATUS_SMENOTRESPONDING_TRYING
0x23, // RIL_MSGDLVSTATUS_SVCREJECTED_TRYING
0x24, // RIL_MSGDLVSTATUS_QUALITYUNAVAIL_TRYING
0x25, // RIL_MSGDLVSTATUS_SMEERROR_TRYING
0x60, // RIL_MSGDLVSTATUS_CONGESTION
0x61, // RIL_MSGDLVSTATUS_SMEBUSY
0x62, // RIL_MSGDLVSTATUS_SMENOTRESPONDING
0x63, // RIL_MSGDLVSTATUS_SVCREJECTED
0x64, // RIL_MSGDLVSTATUS_QUALITYUNAVAIL_TEMP
0x65, // RIL_MSGDLVSTATUS_SMEERROR
0x40, // RIL_MSGDLVSTATUS_REMOTEPROCERROR
0x41, // RIL_MSGDLVSTATUS_INCOMPATIBLEDEST
0x42, // RIL_MSGDLVSTATUS_CONNECTIONREJECTED
0x43, // RIL_MSGDLVSTATUS_NOTOBTAINABLE
0x44, // RIL_MSGDLVSTATUS_QUALITYUNAVAIL
0x45, // RIL_MSGDLVSTATUS_NOINTERNETWORKING
0x46, // RIL_MSGDLVSTATUS_VPEXPIRED
0x47, // RIL_MSGDLVSTATUS_DELETEDBYORIGSME
0x48, // RIL_MSGDLVSTATUS_DELETEDBYSC
0x49, // RIL_MSGDLVSTATUS_NOLONGEREXISTS
};
const size_t fDlvStatusEcount = (sizeof(g_rgdwDlvStatus) / sizeof(DWORD));
//
// Convert a RILMSGDCS struct into a TP-DCS BYTE for Submit messages
// see GSM 03.38
//
static HRESULT EncodeMsgDCS(const RILMSGDCS& rmdDCS, __out_bcount( cbOut ) BYTE* const pbOut, const UINT cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgDCS);
DEBUGCHK(NULL != pbOut && cbOut);
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !(rmdDCS.dwParams & RIL_PARAM_MDCS_TYPE) || !pbOut || !cbOut ) {
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 HRESULT EncodeMsgTimeStamp(const SYSTEMTIME& stTimeStamp, __out_bcount( cbOut ) BYTE* const pbOut, const size_t cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgTimeStamp);
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !pbOut || cbOut < 7 ) // 7 bytes for the encoded timestamp
{
hr = E_INVALIDARG;
ASSERT( FALSE );
goto error_label;
}
BYTE* pbWalk = pbOut;
*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;
error_label:
return hr;
}
//
//
//
// 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 HRESULT EncodeRelativeValidityPeriod(const SYSTEMTIME& stVP, __out_bcount( cbOut ) BYTE* const pbOut, const UINT cbOut, UINT& rcbUsed)
{
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !pbOut || !cbOut ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto error_label;
}
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;
error_label:
return hr;
}
//
// 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, __out_bcount( cbOut ) BYTE* const pbOut, const size_t cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgValidityPeriod);
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !pbOut || !cbOut ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
if (RIL_MSGVP_ABSOLUTE == dwVPFormat) {
hr = EncodeMsgTimeStamp(stVP, pbOut, cbOut, rcbUsed);
if ( FAILED( hr ) ) {
goto Error;
}
} 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:
hr = EncodeRelativeValidityPeriod(stVP, pbOut, cbOut, rcbUsed);
if ( FAILED( hr ) ) {
goto Error;
}
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, __out_bcount( cbOut ) BYTE* const pbOut, size_t cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeMsgAddress);
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 ( !pbOut || cbOut < 2 ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -