📄 sms.cpp
字号:
#include "stdafx.h"
#include "MoblieX.h"
#include "sms.h"
CSMS::CSMS()
{
memcpy( m_scaClass, "91", 3 );//短信中心号码类型 一般为91
memcpy( m_pduHeader, "11", 3 );//文件头字节
memcpy( m_tppid, "00", 3 );//协议标识 00 = 短消息
memcpy( m_callNoClass, "91", 3 );//被叫号码类型
memcpy( m_tpdcs, "08", 3 );//编码类型 00 = 英文 08 = 中文
// memcpy( m_tpdcs, "19", 3 );//编码类型 00 = 英文 08 = 中文
SetSCST();//设置时间标记
memcpy( m_hexBuf, "00", 3 );//供临时使用
}
BOOL CSMS::Encode(CString &reStr)
{
CString oSCA;
CString oCallNo;
CString oSMS;
EncodeStr( m_sms, oSMS );
if( oSMS.GetLength() > 280 )
{//信息太长
return FALSE;
}
EncodeNo( m_sca, oSCA );
EncodeNo( m_callNo, oCallNo );
m_pduLen = 0;
reStr.Empty();
if( oSCA.GetLength() > 0 )
{
reStr = ByteToHex( oSCA.GetLength()/2 + 1 );//短信中心长度(字节), 包括号码类别
reStr += m_scaClass;//号码类别
reStr += oSCA;//短信中心号码
}
else
{
reStr = "00";
}
reStr += m_pduHeader;//PDU文件头字节
reStr += "00";//一定要加上, 表示这是短信
reStr += ByteToHex( m_callNo.GetLength() );//被叫号码长度(数位), 不包括号码类别
m_pduLen += 3;
if( m_callNo.GetLength() > 0 )
{
reStr += m_callNoClass;//被叫号码类别
reStr += oCallNo;//被叫号码
m_pduLen += oCallNo.GetLength() / 2 + 1;
}
reStr += m_tppid;//协议标识
reStr += m_tpdcs;//编码方式
// reStr += m_tpscst;//时间标识, 只在接收信息中使用
reStr += "AA";//有效期
m_pduLen += 3;
reStr += ByteToHex( oSMS.GetLength()/2 );//短信长度(字节), 这个设置最后一个字乱码
reStr += oSMS;
m_pduLen += oSMS.GetLength() / 2 + 1;
return TRUE;
}
BOOL CSMS::Decode(const char *orgSMS)
{
char * pV;
char sHex[3];
int scaLen, callNoLen, udLen;
CString sBuf;
sHex[2] = '\0';
//取短信中心号长度
pV = (char*)orgSMS;
sHex[0] = pV[0];
sHex[1] = pV[1];
pV += 2;
scaLen = HexToByte( sHex );
if( scaLen > 0 )
{//取短信中心号码及类型
m_scaClass[0] = pV[0];
m_scaClass[1] = pV[1];
pV += 2;
scaLen = (scaLen-1)*2;//字节数转为数字位数, 去掉类型字节
memcpy( sBuf.GetBufferSetLength( scaLen ), pV, scaLen );
sBuf.ReleaseBuffer( scaLen );
DecodeNo( sBuf, m_sca );
pV += scaLen;
}
//pdu文件头字节
m_pduHeader[0] = pV[0];
m_pduHeader[1] = pV[1];
pV += 2;
switch( HexToByte( m_pduHeader ) )
{
case 0x11:
pV += 2;//跳过一个不需要处理的字节, 可能是FF
break;
case 0x00:
case 0x04:
case 0x24:
break;
default://暂不能解
m_sms = "Unknow pduHeader: ";
m_sms += m_pduHeader;
return FALSE;
}
//取被叫号码长度
sHex[0] = pV[0];
sHex[1] = pV[1];
pV += 2;
callNoLen = HexToByte( sHex );
if( callNoLen > 0 )
{//取被叫号码及类型
m_callNoClass[0] = pV[0];
m_callNoClass[1] = pV[1];
pV += 2;
if( callNoLen & 0x01 )
{//数字位数如果为奇数, 要补一位
callNoLen++;
}
memcpy( sBuf.GetBufferSetLength( callNoLen ), pV, callNoLen );
sBuf.ReleaseBuffer( callNoLen );
DecodeNo( sBuf, m_callNo );
pV += callNoLen;
}
//取tppid
m_tppid[0] = pV[0];
m_tppid[1] = pV[1];
pV += 2;
//取tpdcs
m_tpdcs[0] = pV[0];
m_tpdcs[1] = pV[1];
pV += 2;
if( strcmp( m_tpdcs, "08" ) != 0
&& strcmp( m_tpdcs, "19" ) != 0 )
{//未知的格式
m_sms = "Unknow dcs: ";
m_sms += m_tpdcs;
return FALSE;
}
//取时间
if( pV[0] == 'A' && pV[1] == 'A' )
{
memset( m_tpscst, 0, 14 );
pV += 2;
}
else if( *pV > '9' )
{//不是有效的时间
m_sms = "Unknow scst: ";
m_sms += pV;
return FALSE;
}
else
{
memcpy( m_tpscst, pV, 14 );
ExchangHighLow( m_tpscst, 14 );
pV += 14;
}
//取UDL
sHex[0] = pV[0];
sHex[1] = pV[1];
pV += 2;
udLen = HexToByte( sHex );
if( udLen < 1 )
{//没有正文
m_sms.Empty();
return TRUE;
}
//取UD
udLen *= 2;//计算字数
memcpy( sBuf.GetBufferSetLength( udLen ), pV, udLen );
sBuf.ReleaseBuffer( udLen );
DecodeStr( sBuf, m_sms );
pV += udLen;
return TRUE;
}
unsigned char CSMS::HexToByte(const char *sHex)
{
char * p;
return (unsigned char)strtoul( sHex, &p, 16 );
}
const char * CSMS::ByteToHex(unsigned char val)
{
unsigned char v;
v = (val & 0xF0) >> 4;
if( v < 10 )
{
m_hexBuf[0] = '0' + v;
}
else
{
m_hexBuf[0] = 'A' + (v - 10);
}
v = val & 0x0F;
if( v < 10 )
{
m_hexBuf[1] = '0' + v;
}
else
{
m_hexBuf[1] = 'A' + (v - 10);
}
return m_hexBuf;
}
BOOL CSMS::EncodeNo(const char *pS1, CString &s2)
{
//将pS1的奇偶位交换后放到s2中, 如果pS1长度为奇数, 则最后一位补 'F' 后再交换
int size;
char * pS2;
BOOL AddF = FALSE;
size = strlen( pS1 );
if( size <= 0 )
{
s2.Empty();
return TRUE;
}
if( size & 0x01 )
{//奇数号码, 要加1
size++;
AddF = TRUE;
}
pS2 = s2.GetBufferSetLength( size );
memcpy( pS2, pS1, size );
if( AddF )
{
pS2[size-1] = 'F';
}
ExchangHighLow( pS2, size );
s2.ReleaseBuffer( size );
return TRUE;
}
BOOL CSMS::DecodeNo(const char *pS1, CString &s2)
{
//将pS1的奇偶位交换后放到s2中, 如果s2最后一位为 'F' 则删除
int size;
char * pS2;
size = strlen( pS1 );
if( size <= 0 )
{
s2.Empty();
return FALSE;
}
pS2 = s2.GetBufferSetLength( size );
memcpy( pS2, pS1, size );
ExchangHighLow( pS2, size );
s2.ReleaseBuffer( size );
s2.MakeUpper();
s2.Remove( 'F' );
return TRUE;
}
BOOL CSMS::DecodeStr(const char *pS1, CString &s2)
{
int i, s1Size, wSize, mSize;
CString s;
char *pS;
char sHex[3];
s1Size = strlen( pS1 );
wSize = s1Size / 2;//w字串所需的字节数, 不是W字数
pS = s.GetBufferSetLength( wSize );
sHex[2] = '\0';
for( i = 0; i < wSize; i++ )
{
sHex[0] = pS1[i*2];
sHex[1] = pS1[i*2+1];
pS[i] = HexToByte( sHex );
}
ExchangHighLow( pS, wSize );
mSize = WideCharToMultiByte(
936, WC_COMPOSITECHECK,
(wchar_t*)pS, wSize/2,
s2.GetBufferSetLength(wSize), wSize,
NULL, NULL );
s2.ReleaseBuffer( mSize );
s.ReleaseBuffer( 0 );
return TRUE;
}
BOOL CSMS::EncodeStr(const char *pS1, CString &s2)
{
int i, s1Size, wSize;
CString s;
char *pS;
s1Size = strlen( pS1 );
pS = s.GetBufferSetLength( s1Size*2 );
wSize = MultiByteToWideChar( 936, MB_COMPOSITE, pS1, s1Size, (wchar_t*)pS, s1Size*2 );
s2.Empty();
for( i = 0; i < wSize*2; i+=2 )
{
s2 += ByteToHex( pS[i+1] );
s2 += ByteToHex( pS[i] );
}
s.ReleaseBuffer( 0 );
return TRUE;
}
void CSMS::SetSCST()
{
COleDateTime ct;
CString buf;
ct = COleDateTime::GetCurrentTime();
buf = ct.Format( "%y%m%d%H%M%S08" );// YYMMDDhhmmss08
memcpy( m_tpscst, buf, 15 );
ExchangHighLow( m_tpscst, 14 );
}
void CSMS::ExchangHighLow(char *pData, int dataLen)
{
int i;
char b;
dataLen = dataLen & 0xFFFFFFFE;//去掉最低位, 保证为偶数
for( i = 0; i < dataLen; i+=2 )
{
b = pData[i];
pData[i] = pData[i+1];
pData[i+1] = b;
}
}
BOOL CSMS::GetFormatedSCST( CString & scst )
{
int i, j;
scst = "00-00-00 00:00:00";
for( i = 0, j = 0; i < 12; i++, j++ )
{
scst.SetAt( j, m_tpscst[i] );
if( i & 0x01 )
{
j++;
}
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -