Chinaunix首页 | 论坛 | 博客
  • 博客访问: 431726
  • 博文数量: 56
  • 博客积分: 2262
  • 博客等级: 大尉
  • 技术积分: 711
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-08 20:04
文章分类

全部博文(56)

文章存档

2013年(1)

2012年(9)

2011年(10)

2010年(7)

2009年(7)

2008年(22)

我的朋友

分类: C/C++

2008-08-20 19:39:19

 
把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;
}

阅读(3551) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~