863
社区成员
发帖
与我相关
我的任务
分享
//**************************************************************************
//** 函 数 名:PDUDecode
//** 功能描述:对读取到的 SMS 短信进行 PDU 解码。
//** 参数输入:strPDUString - 必要参数。要解码的 PDU 字符串。
//** :retPhone - 必要参数。解码后返回来电号码的字符串缓冲区。
//** :retDateTime - 必要参数;解码后返回短信时间的字符串缓冲区。
//** 返 回:成功返回短信正文信息,失败返回空字符串
//** 创建日期:2010-09-10
//** 修改日期:
//** 版 本 号:(VC版本) Version 1.0.0
//**************************************************************************
char * PDUDecode(char * strPDUString, char ** retPhone, char ** retDateTime)
{
//收到短信的基本段落模式
//SCA + PDU Type + OA + PID + DCS + SCTS + UDL + UD
VBString PDUString;
VBString tmpString;
VBString tmpStr1;
VBString SCAText;
VBString OAText;
VBString SCTSTime;
VBString UDText;
VBString UDASCII;
WORD UDUnicode = 0;
WORD UDGB2312 = 0;
//BSTR retBSTR;
BYTE MoveBitCount = 0;
BYTE YSBYTE = 0;
BYTE BJBYTE = 0;
BYTE TMPBYTE = 0;
DWORD ExecByteCount = 0;
DWORD SCACount = 0;
DWORD OACount = 0;
DWORD SCAMode = 0;
DWORD OAMode = 0;
DWORD tmpLong1 = 0;
DWORD DCSZip = 0;
DWORD DCSCode = 0;
DWORD UDCount = 0;
DWORD Y = 0;
PDUString = strPDUString;
//====== 分析 SCA 段信息 ======
ExecByteCount = 2;
tmpString = PDUString.get_Mid(0,2);
//=== 分析 SCA 的 Len 段 ===
SCAText = "";
if(tmpString!="00"){
//如果不是 00 表示存在短信中心号码信息
sscanf(*tmpString,"%x",&SCACount);
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&SCAMode);
//=== 分析 SCA 的 Type 段 ===
//分析 Type 段的 数据类型段 Bit 6-4
tmpLong1 = SCAMode << 1;
tmpLong1 = tmpLong1 & 0xFF;
tmpLong1 = tmpLong1 >> 5;
switch(tmpLong1){
case 0: //未知的类型,这里不做处理
break;
case 1: //国际类型,表示 + 开头
SCAText = "+";
break;
case 2: //国内号码类型
break;
case 7: //留作扩展
break;
}
//分析 Type 段的 号码鉴别段 Bit 3-0
tmpLong1 = SCAMode & 15;
switch(tmpLong1){
case 0: //未知
break;
case 1: //ISDN/电话号码(E.164/E.163)
break;
case 15://留作扩展
break;
}
//=== 分析 SCA 的 Add 段 ===
for(Y = ExecByteCount;Y<=(ExecByteCount+((SCACount - 2) * 2));Y=Y+2){
tmpString = PDUString.get_Mid(Y, 2);
SCAText &= tmpString.get_Right(1);
SCAText &= tmpString.get_Left(1);
}
tmpString = SCAText.get_Right(1);
if(tmpString=="F"){
SCAText.set_Left(SCAText.lengthB-1);
}
ExecByteCount = ExecByteCount + ((SCACount - 1) * 2);
}
//====== 分析 PDU Type 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
//====== 分析 OA 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
OAText = "";
if(tmpString!="00"){
// 如果不是 00 表示存在发送用户的号码信息
sscanf(*tmpString,"%x",&OACount);
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&OAMode);
//=== 分析 OA 的 Type 段 ===
//分析 Type 段的 数据类型段 Bit 6-4
tmpLong1 = OAMode << 1;
tmpLong1 = tmpLong1 & 0xFF;
tmpLong1 = tmpLong1 >> 5;
switch(tmpLong1){
case 0: //未知的类型,这里不做处理
break;
case 1: //国际类型,表示 + 开头
OAText = "+";
break;
case 2: //国内号码类型
break;
case 7: //留作扩展
break;
}
//分析 Type 段的 号码鉴别段 Bit 3-0
tmpLong1 = OAMode & 15;
switch(tmpLong1){
case 0: //未知
break;
case 1: //ISDN/电话号码(E.164/E.163)
break;
case 15://留作扩展
break;
}
//=== 分析 OA 的 Add 段 ===
if(OACount%2==1){
tmpLong1 = OACount + 1;
}else{
tmpLong1 = OACount;
}
tmpString = PDUString.get_Mid(ExecByteCount,tmpLong1);
for(Y = 0;Y<tmpLong1;Y=Y+2){
tmpStr1 = tmpString.get_Mid(Y, 2);
OAText &= tmpStr1.get_Right(1);
OAText &= tmpStr1.get_Left(1);
}
if(OACount%2==1){
OAText.set_Left(OAText.lengthB-1);
}
ExecByteCount = ExecByteCount + tmpLong1;
}
//====== 分析 PID 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
//====== 分析 DCS 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&tmpLong1);
// 分析 DCS 的是否压缩标志 Bit 5
tmpLong1 = tmpLong1 >> 4;
DCSZip = tmpLong1 & 1; // 0 - 表示未压缩 1 - 表示用 GSM 标准压缩算法压缩
// 分析 DCS 的编码防止标志 Bit 3-2
sscanf(*tmpString,"%x",&tmpLong1);
tmpLong1 = tmpLong1 >> 2;
DCSCode = tmpLong1 & 3; // 0 - 表示用 7 Bit 位编码(英文) 1 - 表示用 8 Bit 位编码(数据) 2 - 表示用 16 Bit 位的 UCS2 编码(中文) 3 - 预留
//====== 分析 SCTS 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,12);
ExecByteCount = ExecByteCount + 14;
SCTSTime = "";
for(Y=0;Y<12;Y=Y+2){
tmpStr1 = tmpString.get_Mid(Y,2);
SCTSTime &= tmpStr1.get_Right(1);
SCTSTime &= tmpStr1.get_Left(1);
}
tmpString = *SCTSTime;
SCTSTime = tmpString.get_Mid(0,2);
SCTSTime &= "-";
SCTSTime &= tmpString.get_Mid(2,2);
SCTSTime &= "-";
SCTSTime &= tmpString.get_Mid(4,2);
SCTSTime &= " ";
SCTSTime &= tmpString.get_Mid(6,2);
SCTSTime &= ":";
SCTSTime &= tmpString.get_Mid(8,2);
SCTSTime &= ":";
SCTSTime &= tmpString.get_Right(2);
//====== 分析 UDL 段信息 ======
tmpString = PDUString.get_Mid(ExecByteCount,2);
ExecByteCount = ExecByteCount + 2;
sscanf(*tmpString,"%x",&UDCount);
//====== 分析 UD 段信息 ======
UDASCII = "";
switch(DCSCode){
case 0: //表示用 7 Bit 位编码(英文)
UDCount = UDCount - (UDCount / 8);
UDCount = UDCount * 2;
UDText = PDUString.get_Mid(ExecByteCount,UDCount);
tmpStr1 = "A";
for(Y=0;Y<UDCount;Y=Y+2){
tmpString = UDText.get_Mid(Y,2);
sscanf(*tmpString,"%x",&tmpLong1);
MoveBitCount++;
if(MoveBitCount==1){
YSBYTE = (BYTE)(tmpLong1 & 255);
BJBYTE = YSBYTE;
YSBYTE = YSBYTE << MoveBitCount;
YSBYTE = YSBYTE >> MoveBitCount;
BJBYTE = BJBYTE >> (8-MoveBitCount);
}else if(MoveBitCount>=7){
YSBYTE = (BYTE)(tmpLong1 & 255);
TMPBYTE = YSBYTE;
YSBYTE = YSBYTE << MoveBitCount;
YSBYTE = YSBYTE >> 1;
YSBYTE = YSBYTE | BJBYTE;
BJBYTE = TMPBYTE >> (8 - MoveBitCount);
tmpStr1.value[0] = (char)YSBYTE;
UDASCII &= *tmpStr1;
YSBYTE = BJBYTE;
MoveBitCount = 0;
}else{
YSBYTE = (BYTE)(tmpLong1 & 255);
TMPBYTE = YSBYTE;
YSBYTE = YSBYTE << MoveBitCount;
YSBYTE = YSBYTE >> 1;
YSBYTE = YSBYTE | BJBYTE;
BJBYTE = TMPBYTE >> (8 - MoveBitCount);
}
tmpStr1.value[0] = (char)YSBYTE;
UDASCII &= *tmpStr1;
}
break;
case 1: //表示用 8 Bit 位编码(数据)
UDText = PDUString.get_Mid(ExecByteCount,UDCount*2);
for(Y=0;Y<UDCount;Y++){
tmpString = UDText.get_Mid(Y*2,2);
sscanf(*tmpString,"%x",&tmpLong1);
UDASCII &= (char *)(BYTE)tmpLong1;
}
break;
case 2: //表示用 16 Bit 位的 UCS2 编码(中文)
UDCount = UDCount / 2;
UDText = PDUString.get_Mid(ExecByteCount,(UDCount * 4));
tmpStr1 = "AA";
UDCount = UDCount * 4;
for(Y=0;Y<UDCount;Y=Y+4){
tmpString = UDText.get_Mid(Y,4);
sscanf(*tmpString,"%x",&UDUnicode);
UDGB2312 = GB2312[UDUnicode];
if(HIBYTE(UDGB2312)==0){
tmpStr1.value[0]=LOBYTE(UDGB2312);
tmpStr1.value[1]=HIBYTE(UDGB2312);
}else{
tmpStr1.value[0]=HIBYTE(UDGB2312);
tmpStr1.value[1]=LOBYTE(UDGB2312);
}
UDASCII &= *tmpStr1;
}
break;
}
*retPhone = *OAText;
*retDateTime = *SCTSTime;
return *UDASCII;
}
MSComm1.Output = "AT+CMGF=0" & vbCr '使用PDU模式