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

📄 smsprs.cpp

📁 windows mobile RIL软件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        goto Error;
    }

    // Parse command type
    if (!ParseMsgCommandType(pbWalk, rrmMsg.msgOutCommand.dwCommandType, cbParsed)) {
        goto Error;
    }
    rrmMsg.dwParams |= RIL_PARAM_M_COMMANDTYPE;
    pbWalk += cbParsed;
    if (pbWalk > pbEnd) {
        goto Error;
    }

    // Parse the target message reference
    rrmMsg.msgOutCommand.dwTgtMsgReference = *pbWalk++;
    rrmMsg.dwParams |= RIL_PARAM_M_TGTMSGREFERENCE;
    if (pbWalk > pbEnd) {
        goto Error;
    }

    // Parse address
    if (!ParseMsgAddress(pbWalk, FALSE, rrmMsg.msgOutCommand.raDestAddress, cbParsed, TRUE)) {
        goto Error;
    }
    rrmMsg.dwParams |= RIL_PARAM_M_DESTADDRESS;
    pbWalk += cbParsed;
    if (pbWalk > pbEnd) {
        goto Error;
    }

    // Parse command data length
    rrmMsg.msgOutCommand.cbCmdLength = *pbWalk++;
    rrmMsg.dwParams |= RIL_PARAM_M_CMDLENGTH;
    if (pbWalk > pbEnd) {
        goto Error;
    }

    // Parse command data
    (void)memcpy(rrmMsg.msgOutCommand.rgbCmd, pbWalk, min(rrmMsg.msgOutCommand.cbCmdLength, MAXLENGTH_CMD));
    rrmMsg.dwParams |= RIL_PARAM_M_CMD;
    pbWalk += cbParsed;
    if (pbWalk > pbEnd) {
        goto Error;
    }
    fRet = TRUE;

Error:
    return fRet;
}


//
// Parse an Incoming SMS message into a RILMESSAGE structure
//
HRESULT ParseSMSMessage(const LPCSTR sIn, const UINT cbIn, BOOL fIncoming, BOOL fPrependedSMSC, RILMESSAGE& rrmMsg)
{
    FUNCTION_TRACE(ParseSMSMessage);
    DEBUGCHK(NULL != sIn);
    DEBUGCHK(0 < cbIn);

    BYTE* pbGSMBytes = NULL;
    UINT cbGSMBytes;
    UINT cbParsed = 0;
    BYTE bMsgType;
    BOOL fRet = TRUE;
    HRESULT hr = S_OK;

    // Zero out the message structure
    (void)memset(&rrmMsg, 0x00, sizeof(RILMESSAGE));
    rrmMsg.cbSize = sizeof(RILMESSAGE);

#if 1 //#ifdef WAVECOM_SERIES2_DRIVER
    // HW-SPECIFIC: WaveCom Series 2 hardware doesn't encode the SMSC address prepended to a message

    if ('+' == *sIn) {
        UINT i;
        LPWSTR pwchAddress;
        LPCSTR pchIn;
        LPCSTR sAfterSMSCAddress;
        UINT cbAfterSMSCAddress;

        // Assume the type and numplan
        rrmMsg.raSvcCtrAddress.dwType = RIL_ADDRTYPE_INTERNATIONAL;
        rrmMsg.raSvcCtrAddress.dwNumPlan = RIL_NUMPLAN_TELEPHONE;

        // Copy the phone number over
        pwchAddress = rrmMsg.raSvcCtrAddress.wszAddress;
        pchIn = sIn + 1;
        for (i = 0; i < WAVECOM_SERIES2_DRIVER_BOGUS_ADDR_LENGTH ; i++) {
            *pwchAddress++ = *pchIn & 0x00ff;
        }
        *pwchAddress = L'\0';

        // Set approproiate param flags
        rrmMsg.raSvcCtrAddress.dwParams |= (RIL_PARAM_A_TYPE | RIL_PARAM_A_NUMPLAN | RIL_PARAM_A_ADDRESS);
        rrmMsg.dwParams |= RIL_PARAM_M_SVCCTRADDRESS;

        // Convert the rest of the message from GSM default HEX represention into GSM default
        sAfterSMSCAddress = sIn + WAVECOM_SERIES2_DRIVER_BOGUS_ADDR_LENGTH;
        cbAfterSMSCAddress = cbIn - WAVECOM_SERIES2_DRIVER_BOGUS_ADDR_LENGTH;
        pbGSMBytes = new BYTE[cbAfterSMSCAddress/ 2 + 1];
        if (!pbGSMBytes) {
            hr = E_OUTOFMEMORY;
            goto Error;
        }
        if (!GSMHexToGSM(sAfterSMSCAddress, cbAfterSMSCAddress, (LPSTR)pbGSMBytes, cbAfterSMSCAddress / 2 + 1, cbGSMBytes)) {
            hr = E_FAIL;
            goto Error;
        }
    } else {
#endif // WAVECOM_SERIES2_DRIVER

    // Convert the whole message from GSM default HEX represention into GSM default
    pbGSMBytes = new BYTE[cbIn / 2 + 1];
    if (!pbGSMBytes) {
        hr = E_OUTOFMEMORY;
        goto Error;
    }
    if (!GSMHexToGSM(sIn, cbIn, (LPSTR)pbGSMBytes, cbIn / 2 + 1, cbGSMBytes)) {
        hr = E_FAIL;
        goto Error;
    }

    if (fPrependedSMSC)
    {
        // Grab the prepended SMSC address
        if (!ParseMsgAddress(pbGSMBytes, TRUE, rrmMsg.raSvcCtrAddress, cbParsed, FALSE)) {
            hr = E_FAIL;
            goto Error;
        }
        rrmMsg.dwParams |= RIL_PARAM_M_SVCCTRADDRESS;
    }

#if 1 //#ifdef WAVECOM_SERIES2_DRIVER
    }
#endif // WAVECOM_SERIES2_DRIVER

    // Mask the bottom two bits to get the message type (GSM 03.40 section 9.2.3.1)
    bMsgType = *(pbGSMBytes + cbParsed) & 0x03;
    switch (bMsgType)
    {
        case 0x00:  // SMS-DELIVER or SMS-DELIVER-REPORT
            if (!fIncoming) {
                // We don't support SMS-DELIVER-REPORTs
                hr = E_FAIL;
                goto Error;
            }
            fRet = ParseDeliverMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
            break;

        case 0x01:  // SMS-SUBMIT or SMS-SUBMIT-REPORT
            if (fIncoming) {
                // We don't support SMS-SUBMIT-REPORTs
                hr = E_FAIL;
                goto Error;
            }
            fRet = ParseSubmitMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
            break;

        case 0x02:  // SMS-STATUS-REPORT or SMS_COMMAND
            if (fIncoming) {
                fRet = ParseStatusMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
            } else {
                fRet = ParseCommandMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
            }
            break;

        default:
            hr = E_FAIL;
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseSMSMessage : Invalid Message Type\r\n")));
            goto Error;
    }

    if (!fRet) {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseSMSMessage : Failed\r\n")));
        hr = E_FAIL;
    }

Error:
    delete[] pbGSMBytes;
    return hr;
}


//
// Helper for setting RILMSGDCS language properties
//
static void SetDCSLanguageType(RILMSGDCS& rrmdDCS, DWORD dwAlphabet, DWORD dwLanguage)
{
    rrmdDCS.dwType = RIL_DCSTYPE_LANGUAGE;
    rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;

    rrmdDCS.dwAlphabet = dwAlphabet;
    rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;

    rrmdDCS.dwLanguage = dwLanguage;
    rrmdDCS.dwParams |= RIL_PARAM_MDCS_LANGUAGE;
}

//
// Set Data Coding Scheme of Incoming Cell Broadcast Message
// see GSM 03.38
//
static BOOL ParseCellBroadcastDCS(const BYTE bIn, RILMSGDCS& rrmdDCS, UINT& rcbLangInMsgBody)
{
    FUNCTION_TRACE(ParseCellBroadcastDCS);
    
    BOOL fRet = FALSE;

    rcbLangInMsgBody = 0;
    
    (void)memset(&rrmdDCS, 0x00, sizeof(RILMSGDCS));
    rrmdDCS.cbSize = sizeof(RILMSGDCS);

    switch (bIn & 0xf0)
    {
        case 0x00:
            SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, g_rgdwDCSLanguages[bIn & 0x0f]);
            break;

        case 0x10:
            switch (bIn & 0x0f)
            {
                case 0x00:
                    // First 3 characters of message body contain language.
                    rcbLangInMsgBody = 3;

                    SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
                    break;

                case 0x01:
                    // First 2 characters of message body contain language.
                    rcbLangInMsgBody = 2;

                    SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_UCS2, RIL_DCSLANG_UNKNOWN);
                    break;

                default:
                    SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
                    break;
            }
            break;

        case 0x20:
            if (0x00 == (bIn & 0x0f))
            {
                SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_CZECH);
                break;
            }
            // else fall through...

        case 0x30:
            SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
            break;

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

            if (bIn & 0x04)
            {
                rrmdDCS.dwAlphabet = RIL_DCSALPHABET_8BIT;
                rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
            }
            else
            {
                rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
                rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
            }
            
            switch (bIn & 0x03)
            {
                case 0x00:
                    // None
                    break;

                case 0x01:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_1;
                    rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                    break;

                case 0x02:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_2;
                    rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                    break;

                case 0x03:
                    rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_3;
                    rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                    break;
            }
            break;

        default:
            if (bIn & 0x40)
            {
                rrmdDCS.dwType = RIL_DCSTYPE_GENERAL;
                rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;

                if (bIn & 0x20)
                {
                    rrmdDCS.dwFlags |= RIL_DCSFLAG_COMPRESSED;
                    rrmdDCS.dwParams |= RIL_PARAM_MDCS_FLAGS;
                }

                if (bIn & 0x10)
                {
                    switch (bIn & 0x03)
                    {
                        case 0x00:
                            rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_0;
                            rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                            break;

                        case 0x01:
                            rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_1;
                            rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                            break;

                        case 0x02:
                            rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_2;
                            rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                            break;

                        case 0x03:
                            rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_3;
                            rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
                            break;
                    }
                }

                switch ((bIn >> 2) & 0x03)
                {
                    case 0x00:
                        rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
                        rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
                        break;

                    case 0x01:
                        rrmdDCS.dwAlphabet = RIL_DCSALPHABET_8BIT;
                        rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
                        break;

                    case 0x02:
                        rrmdDCS.dwAlphabet = RIL_DCSALPHABET_UCS2;
                        rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
                        break;

                    case 0x03:
                        // Reserved... so use assume alphabet
                        rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
                        rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
                        break;
                }
            }
            else
            {
                // All other cases are reserved and assumed to use default alphabet.
                SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
            }
            break;
    }


    return TRUE;
}


//
// Parses header information for 
//
static BOOL ParseCellBroadcastHeader(const BYTE* const pbIn, const UINT cbIn, RILMESSAGE& rrmMsg, UINT& rcbParsed)
{
    rcbParsed = 0;

    if (cbIn < CELLBROADCAST_HEADER_LENGTH)
    {
        return FALSE;
    }

    // Parse values from the first 2 octets (the serial number)
    WORD wSerialNumber                  = MAKEWORD(*(pbIn+1), *pbIn);
    rrmMsg.msgBcGeneral.dwGeoScope      = GEOSCOPE_FROM_SERIALNUMBER    (wSerialNumber);
    rrmMsg.msgBcGeneral.dwMsgCode       = MESSAGECODE_FROM_SERIALNUMBER (wSerialNumber);
    rrmMsg.msgBcGeneral.dwUpdateNumber  = UPDATENUMBER_FROM_SERIALNUMBER(wSerialNumber);

    // Parse the message ID
    rrmMsg.msgBcGeneral.dwID            = MAKEWORD(*(pbIn+3), *(pbIn+2));

    // Parse DCS info
    UINT cbLanguageInMessageBody = 0;
    if (!ParseCellBroadcastDCS(*(pbIn+4), rrmMsg.msgBcGeneral.rmdDataCoding, cbLanguageInMessageBody))
    {
        return FALSE;
    }

    // Parse page info
    BYTE bPageInfo = *(pbIn+5);
    rrmMsg.msgBcGeneral.dwTotalPages    = TOTALPAGES(bPageInfo);
    rrmMsg.msgBcGeneral.dwPageNumber    = PAGENUMBER(bPageInfo);

    if (rrmMsg.msgBcGeneral.dwTotalPages == 0 ||
        rrmMsg.msgBcGeneral.dwPageNumber == 0)
    {
        rrmMsg.msgBcGeneral.dwTotalPages = 1;
        rrmMsg.msgBcGeneral.dwPageNumber = 1;
    }

    rcbParsed = CELLBROADCAST_HEADER_LENGTH + cbLanguageInMessageBody;

    return TRUE;
}

HRESULT ParseCellBroadcastMessage(const LPCSTR sIn, const UINT cbIn, RILMESSAGE& rrmMsg)
{
    FUNCTION_TRACE(ParseCellBroadcastMessage);
    DEBUGCHK(NULL != sIn);
    DEBUGCHK(0 < cbIn);
    
    HRESULT hr = S_OK;
    BYTE* pbGSMBytes = NULL;
    UINT cbGSMBytes;
    UINT cbParsed = 0;

    // Zero out the message structure
    (void)memset(&rrmMsg, 0x00, sizeof(RILMESSAGE));
    rrmMsg.cbSize = sizeof(RILMESSAGE);

    // Convert the whole message from GSM default HEX represention into GSM default
    pbGSMBytes = new BYTE[cbIn / 2 + 1];
    if (!pbGSMBytes) {
        hr = E_OUTOFMEMORY;
        goto Error;
    }
    if (!GSMHexToGSM(sIn, cbIn, (LPSTR)pbGSMBytes, cbIn / 2 + 1, cbGSMBytes)) {
        hr = E_FAIL;
        goto Error;
    }

    // Parse the header information
    if (!ParseCellBroadcastHeader(pbGSMBytes, cbGSMBytes, rrmMsg, cbParsed))
    {
        hr = E_FAIL;
        goto Error;
    }

    // This is a cell broadcast message.
    rrmMsg.dwType = RIL_MSGTYPE_BC_GENERAL;

    // Copy the message body to the output structure
    rrmMsg.msgBcGeneral.cchMsgLength = min(cbGSMBytes - cbParsed, MAXLENGTH_MSG);
    memcpy(rrmMsg.msgBcGeneral.rgbMsg, pbGSMBytes + cbParsed, rrmMsg.msgBcGeneral.cchMsgLength);
    
    // We always get all the parameters for cell broadcast
    rrmMsg.dwParams = RIL_PARAM_M_ALL_BC_GENERAL;

Error:
    delete[] pbGSMBytes;
    return hr;
}


⌨️ 快捷键说明

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