⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsenc.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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 + -