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

📄 csms.cpp

📁 PDU短信的编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "class.h"
#include "globlclass.h"

INT16U CSmsPdu:: GsmDecode8bit(const INT8U *pSrc, INT8U *pDst, INT16U nSrcLength)
{
	// 简单复制
	for(INT16U m=0;m<nSrcLength;m++)
	   *pDst++=*pSrc++;
	// 输出字符串加个结束符
	*pDst = '\0';
	return nSrcLength;
}

INT16U CSmsPdu::GsmEncode8bit(const INT8U *pSrc, INT8U *pDst, INT16U nSrcLength)
{
	// 简单复制
	for(INT16U m=0;m<nSrcLength;m++)
	   *pDst++=*pSrc++;

	return nSrcLength;
}

INT16U CSmsPdu::GsmDecodeUcs2(const INT8U* pSrc, INT8U* pDst, INT16U nSrcLength)
{
	INT16U nDstLength=nSrcLength;        // UNICODE宽字符数目
   // INT16U wchar[128];      // UNICODE串缓冲区
    
    // 高低字节对调,拼成UNICODE
    for(INT16U i=0; i<nSrcLength; i+=2)
    {
        // 先高位字节,因为是数据。高字节为0
         pSrc++;
        // 后低位字节
        *pDst++= *pSrc++;
       
   
    }
        // UNICODE串-.字符串
    //nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
        // 输出字符串加个结束符    
    //pDst[nDstLength] = '\0';    
        // 返回目标字符串长度
    return (nDstLength>>1);
}

INT16U CSmsPdu::GsmEncodeUcs2(const INT8U* pSrc, INT8U* pDst, INT16U nSrcLength)
{
	INT16U nDstLength=nSrcLength;        // UNICODE宽字符数目
    //INT16U wchar[128];      // UNICODE串缓冲区
    
    // 字符串-.UNICODE串
   // nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
 
    // 高低字节对调,输出
    for(INT16U i=0; i<nDstLength; i++)
    {
         // 先输出高位字节
        *pDst++ = 0x00;
        // 后输出低位字节
        *pDst++ = * pSrc++;
       
    }
    
    // 返回目标编码串长度
    return (nDstLength <<1);
}

  INT16U  CSmsPdu::GsmDecode7bit(const INT8U* pSrc, INT8U* pDst, INT16U nSrcLength)
{
	INT16U nSrc;        // 源字符串的计数值
    INT16U nDst;        // 目标解码串的计数值
    INT16U nByte;       // 当前正在处理的组内字节的序号,范围是0-6
    INT8U nLeft;    // 上一字节残余的数据
    
    // 计数值初始化
    nSrc = 0;
    nDst = 0;
    
    // 组内字节序号和残余数据初始化
    nByte = 0;
    nLeft = 0;
    
    // 将源数据每7个字节分为一组,解压缩成8个字节
  // 循环该处理过程,直至源数据被处理完
    // 如果分组不到7字节,也能正确处理
    while(nSrc<nSrcLength)
    {
        // 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节
        *pDst = ((*pSrc << nByte) | nLeft) & 0x7f;
        // 将该字节剩下的左边部分,作为残余数据保存起来
        nLeft = *pSrc >> (7-nByte);
    
        // 修改目标串的指针和计数值
        pDst++;
        nDst++;
   // 修改字节计数值
        nByte++;
    
        // 到了一组的最后一个字节
        if(nByte == 7)
        {
            // 额外得到一个目标解码字节
            *pDst = nLeft;
    
            // 修改目标串的指针和计数值
            pDst++;
            nDst++;
    
            // 组内字节序号和残余数据初始化
            nByte = 0;
            nLeft = 0;
        }
    
        // 修改源串的指针和计数值
        pSrc++;
        nSrc++;
	}
    
    *pDst = 0;
    
    // 返回目标串长度
    return nDst;

	
}
//将每个ascii8位编码的Bit8去掉,依次将下7位编码的后几位逐次移到前面,形成新的8位编码。 
 INT16U  CSmsPdu::GsmEncode7bit(const INT8U* pSrc, INT8U* pDst, INT16U nSrcLength)
{
	 INT16U nSrc;        // 源字符串的计数值
    INT16U nDst;        // 目标编码串的计数值
    INT16U nChar;       // 当前正在处理的组内字符字节的序号,范围是0-7
    INT8U nLeft;    // 上一字节残余的数据
    
    // 计数值初始化
    nSrc = 0;
    nDst = 0;
    
    // 将源串每8个字节分为一组,压缩成7个字节
    // 循环该处理过程,直至源串被处理完
    // 如果分组不到8字节,也能正确处理
    while(nSrc<nSrcLength+1)
    {
        // 取源字符串的计数值的最低3位
        nChar = nSrc & 7;
		  // 处理源串的每个字节
        if(nChar == 0)
        {
            // 组内第一个字节,只是保存起来,待处理下一个字节时使用
            nLeft = *pSrc;
        }
        else
        {
            // 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
            *pDst = (*pSrc << (8-nChar)) | nLeft;
      // 将该字节剩下的左边部分,作为残余数据保存起来
            nLeft = *pSrc >> nChar;
            // 修改目标串的指针和计数值 pDst++;
            pDst++;
            nDst++; 
        } 
        
        // 修改源串的指针和计数值
        pSrc++; nSrc++;
    }
    
    // 返回目标串长度
    return nDst; 
	
}

 INT16U  CSmsPdu::Ascii_To_Hex(const INT8U* pSrc, INT8U* pDst, INT16U nSrcLength)
{
	
	for(INT16U i=0; i<nSrcLength; i+=2)
    {
        // 输出高4位
        if(*pSrc>='0' && *pSrc<='9')
        {
            *pDst = (*pSrc - '0') << 4;
		}
        else if(*pSrc>='A' && *pSrc<='F')
        {
            *pDst = (*pSrc - 'A' + 10) << 4;
        }
        else  if(*pSrc>='a' && *pSrc<='f')
        {
             *pDst = (*pSrc - 'a' + 10) << 4;
        
        }
        else
           return FALSE;
        pSrc++;
      // 输出低4位
        if(*pSrc>='0' && *pSrc<='9')
        {
            *pDst |= *pSrc - '0';
        }
        else if(*pSrc>='A' && *pSrc<='F')
		{
            *pDst |= *pSrc - 'A' + 10;
        }
         else  if(*pSrc>='a' && *pSrc<='f')
        {
             *pDst |= (*pSrc - 'a' + 10);
        
        }
        else
           return FALSE;
        pSrc++;
        pDst++;
    }
    
    // 返回目标数据长度
    return (nSrcLength >> 1);
	
}

 INT16U CSmsPdu:: Hex_To_Ascii(const INT8U* pSrc, INT8U* pDst, INT16U nSrcLength)
{
	
	const INT8U tab[]="0123456789ABCDEF";    // 0x0-0xf的字符查找表
    
    for(INT16U i=0; i<nSrcLength; i++)
    {
		// 输出低4位
        *pDst++ = tab[*pSrc >> 4];
                                        
        // 输出高4位
        *pDst++ = tab[*pSrc & 0x0f];
    
        pSrc++;
	}
    
    // 输出字符串加个结束符
    *pDst = '\0';
    
    // 返回目标字符串长度
    return (nSrcLength << 1);
}
 


//解码程序
  INT16U  CSmsPdu::GsmDecodePdu(const INT8U* pSrc,INT16U pSrcLength,SmsType *pSmstype,INT8U *DataDst)
{
	
	INT8U nDstLength=0;          // 目标PDU串长度
	INT8U tmp;       // 内部用的临时字节变量
    INT8U buf[256];  // 内部用的缓冲区
	INT16U templen=0;
	INT16U tmp16;
   
   //---SCA
    // SMSC地址信息段
    Ascii_To_Hex(pSrc, &tmp, 2);    // 取长度
    if(tmp>0&&tmp<=12)
    {
    
    tmp = (tmp - 1) * 2;    // SMSC号码串长度,去掉了91;
    pSrc += 4;              // 指针后移,长度两个字节,91两个字节。共4个字节
    templen+=4;
    Ascii_To_Hex(pSrc, buf, tmp);    // 转换SMSC号码到目标PDU串
    Hex_Num_Decode(buf,(*pSmstype).SCA,tmp);//取短信中心号码,保存,回复时用,是HEX码保存的  
    pSrc += tmp;        // 指针后移,此时到了PDUType
    templen+=tmp;
  
    
    // TPDU段基本参数、回复地址等
     //--PDUType
    Ascii_To_Hex(pSrc, &tmp, 2);    // 取基本参数
    pSrc += 2;        // 指针后移
    templen+=2;
    //--OA----star
        // 包含回复地址,取回复地址信息
    Ascii_To_Hex(pSrc, &tmp, 2);    // 取长度,OA的长度是指具体的号码长度,
    if(tmp & 1) tmp += 1;    // 调整奇偶性
    pSrc += 4;          // 指针后移,除去长度,和91,共4个字节
    templen+=4;
    if(tmp>0&&tmp<=12*2)
    {
    Ascii_To_Hex(pSrc, buf, tmp); 
    Hex_Num_Decode(buf,(*pSmstype).TPA,tmp) ;  // 取TP-RA号码,保存回复地址
    pSrc += tmp;        // 指针后移
    templen+=tmp;
    //--OA---End-------

    
    // TPDU段协议标识、编码方式、用户信息等
    Ascii_To_Hex(pSrc, (INT8U*)&(*pSmstype).TP_PID, 2);    // 取协议标识(TP-PID)
    pSrc += 2;
    templen+=2;       // 指针后移
    Ascii_To_Hex(pSrc, (INT8U*)&(*pSmstype).TP_DCS, 2);    // 取编码方式(TP-DCS),这个解码时和回复时用
    pSrc += 2;        // 指针后移
    templen+=2;
    //GsmSerializeNumbers(pSrc, m_SmsType.TP_SCTS, 14);        // 服务时间戳字符串(TP_SCTS) 
    pSrc += 14;       // 指针后移
    templen+=14;
    Ascii_To_Hex(pSrc, &tmp, 2);    // 用户信息长度(TP-UDL)
    pSrc += 2;        // 指针后移
    templen+=2;
   // pDst.TP_DCS=8;
    if(((*pSmstype).TP_DCS&0x0c) == GSM_7BIT)    
    {
        // 7-bit解码
        tmp16=tmp%8 ? ((INT16U)tmp * 7 / 8 + 1) : ((INT16U)tmp * 7 / 8);
        tmp16*=2;
       if((templen+tmp16<=pSrcLength)&&(tmp16<400))
       { 
        nDstLength = Ascii_To_Hex(pSrc, buf,tmp16);  // 格式转换
        GsmDecode7bit(buf, DataDst, nDstLength);    // 转换到TP-DU
        nDstLength = tmp;
       }
    }
    else if(((*pSmstype).TP_DCS&0x0c) == GSM_UCS2)
    {
        // UCS2解码
       tmp16=tmp * 2;
        if((templen+tmp16<=pSrcLength)&&(tmp16<400))
        {
        nDstLength = Ascii_To_Hex(pSrc, buf,tmp16);        // 格式转换
        nDstLength = GsmDecodeUcs2(buf, DataDst, nDstLength);    // 转换到TP-DU
        }
    }
    else
    {
        // 8-bit解码
        tmp16=tmp * 2;
       if((templen+tmp16<=pSrcLength)&&(tmp16<512))
        {
        nDstLength = Ascii_To_Hex(pSrc, buf,tmp16);        // 格式转换
        nDstLength = GsmDecode8bit(buf, DataDst, nDstLength);    // 转换到TP-DU
		}

⌨️ 快捷键说明

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