短信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;
}

原文链接:http://blog.chinaunix.net/u1/56388/showart_1136362.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java PDU(Protocol Data Unit)解码是指将PDU数据转换成人类可读的文本信息。PDU是在计算机网络中传输的数据单元,它可以是报文、数据或控制信息。在Java开发中,PDU解码通常用于解析和处理短信、邮件、电话等通信信息。 在Java中,实现PDU解码的一种常见方式是使用第三方库或工具,如SMPP(Short Message Peer to Peer)协议库或jsmpp库。这些库提供了一组API(Application Programming Interface),可以使用Java代码解码PDU数据。通过读取和解析PDU的各个字段,可以从二进制数据中提取出发送者、接收者、时间戳、正文等信息,并将其转换为可读的文本。 解码PDU的过程一般包括以下步骤: 1. 读取PDU的二进制数据,并将其转换为可操作的字节数组。 2. 根据PDU的协议规范,确定各个字段的起始位置和长度。 3. 通过字节数组的索引和长度信息,逐个字段地读取PDU数据,并将其转换为可读的文本。 4. 解析PDU的各个字段,如发送者的号码、接收者的号码、时间戳等。 5. 将解析后的字段拼接成人类可读的文本信息,如短信正文。 PDU解码在移动通信、网络通信等领域有广泛的应用。在Java开发中,通过使用第三方库可以简化PDU解码的过程,快速获取PDU中的各个字段信息,并进行相应的处理和分析。这些库提供了丰富的功能和API,可以帮助我们更高效地解码和处理PDU数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值