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

📄 sms.cpp

📁 通过手机数据线连接手机
💻 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 + -