短信PDU模式解码

 
把GPRS模块从串口发送回来的数据全部放到缓冲区里面,可完成多条短信的解码
代码还在完善当中,贴出来希望与大家一起讨论!
 
 

//PDU模式短信解码文件操作类
//by so_zhou

//标准GSM短信,适合国内使用

CPDUcode::CPDUcode()
{
    m_dwMsgCount = 0;
    Message = NULL;
    m_strSMS = "";
}

CPDUcode::~CPDUcode()
{
    if (Message != NULL)
    {
        delete[] Message;
        Message = NULL;
    }
    m_strSMS = "";
}

BOOL CPDUcode::DecodeOneMsg(PBYTE pSMS, DWORD index)
{
    DWORD i = 0;//信息偏移

    DWORD dwLen = 0;
    DWORD codeType = 0;
    CHAR temp[2] = {0};
    temp[0] = pSMS[0];
    temp[1] = pSMS[1];
    dwLen = hexAtoi(temp, 2);
    dwLen = (dwLen + 1) * 2;
    //读取短信中心号码到短信结构中

    for (i = 0; i < dwLen; i++)
        Message[index].smsc[i] = pSMS[i];
    SavePhoneN(Message[index].smsc, i, Message[index].smscN);

    temp[0] = pSMS[i + 2];
    temp[1] = pSMS[i + 3];
    dwLen = hexAtoi(temp, 2);
    i += 2;
    if (0 == dwLen % 2)
        dwLen += 4;
    else
        dwLen += 5;
    //读取电话号码

    for (DWORD j = 0; j < dwLen; j++)
    {
        Message[index].phoneNumeber[j] = pSMS[i];
        i++;
    }
    SavePhoneN(Message[index].phoneNumeber, dwLen, Message[index].phoneNum);
    //获取编码方式

    temp[0] = pSMS[i + 2];
    temp[1] = pSMS[i + 3];
    codeType = hexAtoi(temp, 2);
    //时间

    i += 4;
    for (INT k = 0; k < 14; k++)
    {
        Message[index].time[k] = pSMS[i];
        i++;
    }
    //长度

    temp[0] = pSMS[i];
    temp[1] = pSMS[i + 1];
    Message[index].smsLen = hexAtoi(temp, 2);
    i += 2;
    //内容

    BYTE content[280] = {0};
    DWORD dwCharLen = 0;
    if (0 == codeType)//7bit编码方式解码

    {
        dwCharLen = (Message[index].smsLen - (Message[index].smsLen / 8));
        DWORD m = 0;
        for (m = 0; m < (dwCharLen * 2); m++)
            content[m] = pSMS[i + m];
        hexStrToStr(content, m, content);
        BitToStr(content, dwCharLen, Message[index].smsContent);
    }
    else if (8 == codeType)//unicode方式解码

    {
        dwCharLen = Message[index].smsLen * 2;
        for (DWORD m = 0; m < dwCharLen; m++)
            content[m] = pSMS[i + m];

        hexStrToA(content, dwCharLen, Message[index].smsContent);
    }
    
    return TRUE;
}

void CPDUcode::SavePhoneN(PBYTE inBuffer, DWORD inLen, PBYTE outBuffer)
{
    DWORD i = 4;
    outBuffer[i - 4] = '+';
    while (i < inLen)
    {
        outBuffer[i - 3] = inBuffer[i + 1];
        outBuffer[i - 2] = inBuffer[i];
        i += 2;
    }
    if ('F' == outBuffer[i - 4])
        outBuffer[i - 4] = 0;
}
//中文解码

void CPDUcode::hexStrToW(PBYTE inBuffer, DWORD inBufLen, PTCHAR outBuffer)
{
    CHAR tTemp[4] = {0};
    DWORD i = 0;
    DWORD j = 0;
    while (i < inBufLen)
    {
        //一个Unicode字符

        for (INT k = 0; k < 4; k++)
        {
            tTemp[k] = (CHAR)inBuffer[i];
            i++;
        }
        outBuffer[j] = (TCHAR)hexAtoi(tTemp, 4);
        j++;
    }
}
void CPDUcode::hexStrToA(PBYTE inBuffer, DWORD inBufLen, PBYTE outBuffer)
{
    TCHAR tcTemp[128] = {0};
    hexStrToW(inBuffer, inBufLen, tcTemp);
    wcstombs((PCHAR)outBuffer, tcTemp, (wcslen(tcTemp) * 2));
}
//中文编码

void CPDUcode::WTohexStr(PTCHAR inBuffer, DWORD inBufLen, PBYTE outBuffer)
{
    DWORD cLen = 0;
    CHAR cTemp[4] = {0};
    for (DWORD i = 0; i < inBufLen; i++)
    {
        memset(cTemp, 0, 4);
        _itoa(inBuffer[i], cTemp, 16);
        cLen = strlen(cTemp);
        switch (cLen)
        {
        case 1:
            strcat((PCHAR)outBuffer, "000");
            break;
        case 2:
            strcat((PCHAR)outBuffer, "00");
            break;
        case 3:
            strcat((PCHAR)outBuffer, "0");
            break;
        }
        strcat((PCHAR)outBuffer, cTemp);
    }
    StrLowerToUpper((PCHAR)outBuffer);
}

void CPDUcode::ATohexStr(PBYTE inBuffer, DWORD inBufLen, PBYTE outBuffer)
{
    TCHAR tcTemp[128] = {0};
    mbstowcs(tcTemp, (PCHAR)inBuffer, inBufLen);
    WTohexStr(tcTemp, inBufLen, outBuffer);
}
//7-bit串解码

void CPDUcode::BitToStr(PBYTE inBuffer, DWORD inBufLen, PBYTE outBuffer)
{
    BYTE bTemp[12] = {0};
    BYTE cTemp[12] = {0};
    DWORD i = 0;
    while (i < inBufLen)
    {
        memset(bTemp, 0, 12);
        memset(cTemp, 0, 12);
        for (INT k = 0; k < 7; k++)
        {
            bTemp[k] = inBuffer[i];
            i++;
            if (i > inBufLen)
                break;
        }
        Decode7bit(bTemp, cTemp);
        strcat((PCHAR)outBuffer, (PCHAR)cTemp);
    }
        
}
//7-bit串编码

void CPDUcode::StrToBit(PBYTE inBuffer, DWORD inBufLen, PBYTE outBuffer)
{
    BYTE bTemp[12] = {0};
    BYTE bcTemp[24] = {0};
    CHAR bccTemp[4] = {0};
    BYTE cTemp[12] = {0};
    DWORD i = 0;
    while (i < inBufLen)
    {
        memset(bTemp, 0, 12);
        memset(cTemp, 0, 12);
        memset(bcTemp, 0, 24);
        memset(bccTemp, 0, 4);

        for (INT k = 0; k < 8; k++)
        {
            cTemp[k] = inBuffer[i];
            i++;
            if (i > inBufLen)
                break;
        }
        Encode7bit(cTemp, bTemp);//编码完成

        //转换成16进制字符串表示

        for (INT m = 0; m < 7; m++)
        {
            _itoa(bTemp[m], bccTemp, 16);
            strcat((PCHAR)bcTemp, bccTemp);
        }
        strcat((PCHAR)outBuffer, (PCHAR)bcTemp);
    }
    StrLowerToUpper((PCHAR)outBuffer);
}
//一组 7-bit解码

void CPDUcode::Decode7bit(PBYTE inBuffer, PBYTE outBuffer)
{
    INT i = 0;
    //i = 0

    outBuffer[0] = (inBuffer[0] << 0) & 0x7f;
    //i = 1 ~ 6

    for (i = 1; i < 7; i++)
    {
        // i i i i - 1 8 - i

        outBuffer[i] = ((inBuffer[i] << i) | (inBuffer[i - 1] >> (8 - i))) & 0x7f;
    }
    
    //i = 7

    outBuffer[7] = (inBuffer[6] >> 1) & 0x7f;
}
//一组 7-bit编码

void CPDUcode::Encode7bit(PBYTE inBuffer, PBYTE outBuffer)
{
    INT i = 0;
    for (i = 0; i < 7; i++)
    {
        // i i i i + 1 7 - i

        outBuffer[i] = (inBuffer[i] >> i) | (inBuffer[i + 1] << (7 - i));
    }
}
void CPDUcode::hexStrToStr(PBYTE inBuffer, DWORD inLen, PBYTE outBuffer)
{
    CHAR tTemp[4] = {0};
    DWORD i = 0;
    DWORD j = 0;
    while (i < inLen)
    {
        //一个Unicode字符

        for (INT k = 0; k < 2; k++)
        {
            tTemp[k] = (CHAR)inBuffer[i];
            i++;
        }
        outBuffer[j] = (BYTE)hexAtoi(tTemp, 2);
        j++;
        outBuffer[j] = 0;
    }
}
//转换成大写

void CPDUcode::StrLowerToUpper(PCHAR inBuffer)
{
    for (DWORD i = 0; i < strlen(inBuffer); i++)
        inBuffer[i] = toupper(inBuffer[i]);
}
//转换成小写

void CPDUcode::StrUpperToLower(PCHAR inBuffer)
{
    for (DWORD i = 0; i < strlen(inBuffer); i++)
        inBuffer[i] = tolower(inBuffer[i]);
}

//字符表示的十六进制转换成整型

DWORD CPDUcode::hexAtoi(PCHAR hexChar, DWORD inLen)
{
    BYTE num[8] = {0};
    DWORD dwRetVal = 0;
    
    INT j = 0;
    INT i = inLen - 1;
    
    for (i, j = 0; i >= 0, j < 8; i--, j++)
    {
        if (isdigit(hexChar[i]))
            num[j] = hexChar[i] - 0x30;
        else if (IsCharUpper(hexChar[i]))            
            num[j] = hexChar[i] - 0x41 + 10;
        else if (IsCharLower(hexChar[i]))
            num[j] = hexChar[i] - 0x61 + 10;
        
        dwRetVal |= (num[j] << (4 * j));
    }

    return dwRetVal;    
}

BOOL CPDUcode::SaveMessage()
{
    INT pos = 0;
    DWORD dwNum = 0;
    DWORD i = 0;
    for (INT l = 0; l < m_strSMS.length(); l++)
    {
        if ('+' == m_strSMS[l])
            dwNum += 1;
    }
    m_dwMsgCount = dwNum;

    Message = new MSG_INFO[dwNum];
    PBYTE msgTemp = new BYTE[512];

    for (i = 0; i < dwNum; i++)
    {
        memset(msgTemp, 0, 512);
        memset(&Message[i], 0, sizeof(MSG_INFO));
        //01234567890123

        //+CMGL: 1,1,,28

        pos = m_strSMS.find("+CMGL:");
        if (pos > 0)
            m_strSMS.erase(0, pos);
        pos = m_strSMS.find("+CMGL:");
        if (pos >= 0)
        {
            //读取消息在卡上的位置

            for (DWORD k = 0; k < 3; k++)
            {
                if (',' == m_strSMS[k + pos + 7])
                    break;
                Message[i].index[k] = m_strSMS[k + pos + 7];
            }
            //读取消息内容

            pos = m_strSMS.find("\r\n") + 2;
            for (DWORD n = 0; n < m_strSMS.length(); n++, pos++)
            {
                if ('\r' == m_strSMS[pos] || '\n' == m_strSMS[pos])
                    break;
                msgTemp[n] = m_strSMS[pos];
            }
            //保存消息到结构体

            DecodeOneMsg(msgTemp, i);
            //删除已经读取的内容

            m_strSMS.erase(0, pos);
        }
    }
    
    if (NULL != msgTemp)
    {
        delete[] msgTemp;
        msgTemp = NULL;
    }

    return TRUE;
}

<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
阅读(1508) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值