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

📄 smsprs.cpp

📁 windows mobile RIL软件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
            }

            switch (bDCS & 0x0c)
            {
                case 0x00:
                    rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
                    break;

                case 0x04:
                    rrmdDCS.dwAlphabet = RIL_DCSALPHABET_8BIT;
                    break;

                case 0x08:
                    rrmdDCS.dwAlphabet = RIL_DCSALPHABET_UCS2;
                    break;

                default:
                    goto Error;
            }
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
            break;

        case 0xc0:
            rrmdDCS.dwFlags |= RIL_DCSFLAG_DISCARD;
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_FLAGS;
            //
            // Fall through
            //
        case 0xd0:
            rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
            //
            // Fall through
            //
        case 0xe0:
            rrmdDCS.dwType = RIL_DCSTYPE_MSGWAIT;
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;

            if (!(rrmdDCS.dwParams & RIL_PARAM_MDCS_ALPHABET)) {
                rrmdDCS.dwAlphabet = RIL_DCSALPHABET_UCS2;
                rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
            }

            if (bDCS & 0x08) {
                rrmdDCS.dwFlags |= RIL_DCSFLAG_INDICATIONACTIVE;
                rrmdDCS.dwParams |= RIL_PARAM_MDCS_FLAGS;
            }

            switch (bDCS & 0x03)
            {
                case 0x00:
                    rrmdDCS.dwIndication = RIL_DCSINDICATION_VOICEMAIL;
                    break;
                case 0x01:
                    rrmdDCS.dwIndication = RIL_DCSINDICATION_FAX;
                    break;
                case 0x02:
                    rrmdDCS.dwIndication = RIL_DCSINDICATION_EMAIL;
                    break;
                case 0x03:
                    rrmdDCS.dwIndication = RIL_DCSINDICATION_OTHER;
                    break;
                default:
                    goto Error;
            }
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_INDICATION;
            break;

        case 0xf0:
            rrmdDCS.dwType = RIL_DCSTYPE_MSGCLASS;
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;

            if (bDCS & 0x04) {
                rrmdDCS.dwAlphabet = RIL_DCSALPHABET_8BIT;
            } else {
                rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
            }
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;

            switch (bDCS & 0x03)
            {
                case 0x00:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_0;
                    break;
                case 0x01:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_1;
                    break;
                case 0x02:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_2;
                    break;
                case 0x03:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_3;
                    break;
                default:
                    goto Error;
            }
            rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
            break;

        default:
            goto Error;
    }
    rcbParsed = 1;
    fRet = TRUE;

Error:
    return fRet;
}


//
// Set the Status value of a message
// see GSM 03.40 section 9.2.3.15
//
static BOOL ParseMsgStatus(const BYTE* const pbIn, DWORD& rdwStatus, UINT& rcbParsed)
{
    FUNCTION_TRACE(ParseMsgStatus);
    DEBUGCHK(NULL != pbIn);

    DWORD MsgStatus = (DWORD)*pbIn;
    DWORD Status;

    // Search the table for common status mappings
    for (Status = 1; Status < NUM_DLVSTATUS; Status++)
    {
        if (g_rgdwDlvStatus[Status] == MsgStatus)
        {
            break;
        }
    }

    // Did we find it in the table?
    if (Status<NUM_DLVSTATUS)
    {
        // Nothing to do
    }
    else if ((MsgStatus>=0x3) && (MsgStatus<=0xF))
    {
        Status = RIL_MSGDLVSTATUS_RESERVED_COMPLETED;
    }
    else if ((MsgStatus>=0x10) && (MsgStatus<=0x1F))
    {
        Status = RIL_MSGDLVSTATUS_SCSPECIFIC_COMPLETED;
    }
    else if ((MsgStatus>=0x26) && (MsgStatus<=0x2F))
    {
        Status = RIL_MSGDLVSTATUS_RESERVED_TRYING;
    }
    else if ((MsgStatus>=0x30) && (MsgStatus<=0x3F))
    {
        Status = RIL_MSGDLVSTATUS_SCSPECIFIC_TRYING;
    }
    else if ((MsgStatus>=0x4A) && (MsgStatus<=0x4F))
    {
        Status = RIL_MSGDLVSTATUS_RESERVED_ERROR;
    }
    else if ((MsgStatus>=0x50) && (MsgStatus<=0x5F))
    {
        Status = RIL_MSGDLVSTATUS_SCSPECIFIC_ERROR;
    }
    else if ((MsgStatus>=0x66) && (MsgStatus<=0x6F))
    {
        Status = RIL_MSGDLVSTATUS_RESERVED_TMPERROR;
    }
    else if ((MsgStatus>=0x70) && (MsgStatus<=0x7F))
    {
        Status = RIL_MSGDLVSTATUS_SCSPECIFIC_TMPERROR;
    }
    else
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseMsgStatus : Unrecognized message status 0x%x!?\r\n"),MsgStatus));
        rcbParsed=0;
        return FALSE;
    }

    rdwStatus = Status;
    rcbParsed = 1;
    return TRUE;
}


//
// Set the CommandType of an Incoming SMS Message
// see GSM 03.40 section 9.2.3.21
//
static BOOL ParseMsgCommandType(const BYTE* const pbIn, DWORD& rdwCommandType, UINT& rcbParsed)
{
    FUNCTION_TRACE(ParseMsgCommandType);
    DEBUGCHK(NULL != pbIn);

    UINT i;
    BOOL fRet = FALSE;

    rcbParsed = 0;

    for (i = 0; i < NUM_COMMANDTYPES; i++) {
        if (g_rgdwCommandTypes[i] == *pbIn) {
            rdwCommandType = i;
            fRet = TRUE;
            break;
        }
    }

    if (fRet) {
        rcbParsed = 1;
    }
    return fRet;
}


//
// Set Hdr data for an incoming message
//
static void ParseMsgHdr(const BYTE* const pbIn, const DWORD dwAlphabet, BYTE* const pbOut, DWORD& rcbHdrLength, UINT& rcbParsed)
{
    FUNCTION_TRACE(ParseMsgHdr);
    DEBUGCHK(NULL != pbIn);
    DEBUGCHK(NULL != pbOut);

    const BYTE* pbWalk = pbIn;

    rcbHdrLength = *pbWalk;
    pbWalk++;
    rcbParsed = 1;

    if (rcbHdrLength) {
        memcpy(pbOut, pbWalk, min(rcbHdrLength, MAXLENGTH_HDR));
        rcbParsed += rcbHdrLength;
    }
}

//
//
//
void ShiftPackedBufferNBitsRight(BYTE *pbyBuffer, DWORD cBufferBytes, DWORD cShiftBits)
{
    BYTE *pbyCurrentByte = pbyBuffer;
    if (0 != cBufferBytes)
    {
        while (pbyCurrentByte < pbyBuffer + cBufferBytes - 1)
        {
            *pbyCurrentByte++ = ((*pbyCurrentByte >> cShiftBits) |
                                 (*(pbyCurrentByte + 1) << (8 - cShiftBits)));
        }
        *pbyCurrentByte = (*pbyCurrentByte >> cShiftBits);
    }
}

//
//
//
static BOOL ParseMsgHeaderAndBody(const BYTE* const pbIn, const BYTE* const pbEnd, const DWORD dwFlags, const RILMSGDCS& rmdDataCoding, DWORD& rdwParams,
                                  BYTE* const pbHdr, BYTE* const pbMsg, DWORD& rcbHdrLength, DWORD& rcchMsgLength,
                                  UINT& rcbParsed)
{
    FUNCTION_TRACE(ParseMsgHeaderAndBody);
    DEBUGCHK(NULL != pbIn);

    const BYTE* pbWalk = pbIn;
    UINT cchUserDataLength;
    DWORD dwAlphabet;
    UINT cbParsed;
    BOOL fRet = FALSE;
    DWORD dwBitsToShift = 0;

    rcbParsed = 0;

    if (rmdDataCoding.dwParams & RIL_PARAM_MDCS_ALPHABET) {
        dwAlphabet = rmdDataCoding.dwAlphabet;
    } else {
        // Default to 8-bit alphabet
        dwAlphabet = RIL_DCSALPHABET_8BIT;
    }

    // GSM 03.38 section 4 says that we don't need to parse the message body if fDiscard is set, but there's no sense losing data we've already got, so continue on regardless
    // fDiscard = (rmdDataCoding.dwParams & RIL_PARAM_MDCS_FLAGS) && (rmdDataCoding.dwFlags & RIL_DCSFLAG_DISCARD);

    // Figure out message length.  See GSM 03.40 section 9.2.3.24
    cchUserDataLength = *pbWalk++;

    // If there is less data in the buffer than is specified by the data length,
    // then abort now to avoid reading past the end of the buffer.
    if (RIL_DCSALPHABET_DEFAULT == dwAlphabet)
    {
        if (pbWalk + ((cchUserDataLength * 7 + 7) / 8) > pbEnd)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseMsgHeaderAndBody : Data length is greater than remaining buffer length!\r\n")));
            goto Error;
        }
    }
    else
    {
        if (pbWalk + cchUserDataLength > pbEnd)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseMsgHeaderAndBody : Data length is greater than remaining buffer length!\r\n")));
            goto Error;
        }
    }

    if (cchUserDataLength /* && !fDiscard */) {
        if (dwFlags & RIL_MSGFLAG_HEADER) {
            // Header present -- parse it
            ParseMsgHdr(pbWalk, dwAlphabet, pbHdr, rcbHdrLength, cbParsed);

            rdwParams |= (RIL_PARAM_M_HDR | RIL_PARAM_M_HDRLENGTH);
            pbWalk += cbParsed;

        } else {
            // No header present
            cbParsed = 0;
        }
        if (RIL_DCSALPHABET_DEFAULT == dwAlphabet) {
            // for phase 0 compatibility the data will start on a septet boundry
            // We want to pass it back starting at an octet boundry so we may
            // have to shift a little.
            dwBitsToShift = 7-((cbParsed * 8) % 7);
            if (dwBitsToShift == 7) dwBitsToShift = 0;
            ASSERT(((cbParsed * 8 + dwBitsToShift) % 7) == 0);
            rcchMsgLength =  cchUserDataLength - ((cbParsed * 8 + dwBitsToShift) / 7);          
        } else if (RIL_DCSALPHABET_UCS2 == dwAlphabet) {
            DEBUGCHK(0 == (cchUserDataLength - cbParsed) % 2);
            rcchMsgLength = (cchUserDataLength - cbParsed) / 2;
        } else {
            rcchMsgLength = cchUserDataLength - cbParsed;
        }

        // Parse message data
        if (rcchMsgLength) {
            if (RIL_DCSALPHABET_DEFAULT == dwAlphabet) {
                cbParsed = (rcchMsgLength * 7 + 7 + dwBitsToShift) / 8;
            } else if (RIL_DCSALPHABET_UCS2 == dwAlphabet) {
                cbParsed = rcchMsgLength * 2;
            } else {
                cbParsed = rcchMsgLength;
            }

            UINT cbToCopy = min(cbParsed,MAXLENGTH_MSG);

            DEBUGCHK(pbEnd > pbWalk);
            DEBUGCHK(cbToCopy <= (UINT)(pbEnd - pbWalk));

            (void)memcpy(pbMsg, pbWalk, cbToCopy);
            // make sure any GSM characters start on the byte boundry, not on the septet boundry.
            if (dwBitsToShift) {
                ShiftPackedBufferNBitsRight(pbMsg, cbToCopy, dwBitsToShift);
            }
            pbWalk += cbToCopy;

            rdwParams |= (RIL_PARAM_M_MSG | RIL_PARAM_M_MSGLENGTH);
        }
    }
    fRet = TRUE;
Error:
    rcbParsed = pbWalk - pbIn;
    return fRet;
}

//
//
//
// 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)
//
static BOOL ParseRelativeValidityPeriod(const BYTE* const pbIn, SYSTEMTIME& rstVP, UINT& rcbParsed)
{
    UINT uVP = (UINT)*pbIn;
    UINT uMinutes = 0;

    if (uVP <= 143)
    {
        uMinutes = (uVP + 1) * 5;
    }
    else if (uVP <= 167)
    {
        uMinutes = 12 * 60 + (uVP - 143) * 30;
    }
    else if (uVP <= 196)
    {
        uMinutes = (uVP - 166) * 24 * 60;
    }
    else
    {
        uMinutes = (uVP - 192) * 7 * 24 * 60;
    }

    rstVP.wDay = uMinutes / 1440;
    uMinutes = uMinutes % 1440;
    rstVP.wHour = uMinutes / 60;
    rstVP.wMinute = uMinutes % 60;

    rcbParsed = 1;
    return TRUE;
}

static BOOL ParseEnhancedValidityPeriod(const BYTE* const pbIn, SYSTEMTIME& rstVP, UINT& rcbParsed)
{
    const BYTE * pbWalk = pbIn;
    const BYTE * pbEnd = pbWalk + 7;

    // Read function from the first octet
    const BYTE bFunction = *pbWalk;

    // Advance past extended functionality indicators
    for ( ; (*pbWalk & 0x80) && (pbWalk < pbEnd); pbWalk++)
        ;

    switch (bFunction & 0x7)
    {
        case 0x0:
            // None
            break;

        case 0x1:
            // Same as relative
            if (pbWalk < pbEnd)
            {
                (void)ParseRelativeValidityPeriod(pbIn, rstVP, rcbParsed);
            }
            break;

        case 0x2:
            // In seconds
            if (pbWalk < pbEnd)
            {
                rstVP.wSecond = *pbWalk;
            }
            break;

        case 0x3:
            // Semi-octet representation of hours, minutes, and seconds
            if (pbWalk + 3 <= pbEnd)
            {
                // Parse hours
                rstVP.wHour = (*pbWalk & 0x0f) * 10 + ((*pbWalk & 0xf0) >> 4);
                pbWalk++;

                // Parse minutes
                rstVP.wMinute = (*pbWalk & 0x0f) * 10 + ((*pbWalk & 0xf0) >> 4);
                pbWalk++;

                // Parse seconds
                rstVP.wSecond = (*pbWalk & 0x0f) * 10 + ((*pbWalk & 0xf0) >> 4);
                pbWalk++;

            }
            break;

        default:
            break;
    }

    rcbParsed = 7;
    return TRUE;
}

//
// Decode the Validity Period for a message
// see GSM 03.40 section 9.2.3.12

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -