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

📄 sms.cpp

📁 PDU编码解码DLL
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	// 返回目标字符串长度
	return nDstLength;
}

// 两两颠倒的字符串转换为正常顺序的字符串
// 如:"0891683139831012F7" --> "8613933801217"
// 输入: pSrc - 源字符串指针
//       nSrcLength - 源字符串长度
// 输出: pDst - 目标字符串指针
// 返回: 目标字符串长度
int gsmSerializeNumbers(const char* pSrc, char* pDst, int nSrcLength)
{
	int nDstLength;		// 目标字符串长度
	char ch;			// 用于保存一个字符
	// 复制串长度
	nDstLength = nSrcLength;
	// 两两颠倒
	for(int i=0; i<nSrcLength;i+=2)
	{
		ch = *pSrc++;		// 保存先出现的字符
		*pDst++ = *pSrc++;	// 复制后出现的字符
		*pDst++ = ch;		// 复制先出现的字符
	}
	// 最后的字符是'F'吗
	if(*(pDst-1) == 'F')
	{
		pDst--;
		nDstLength--;		// 目标字符串长度减1
	}
	// 输出字符串加个结束符
	*pDst = '\0';
	
	// 返回目标字符串长度
	return nDstLength;
}

// PDU编码,用于编制、发送短消息
// 输入: pSrc - 源PDU参数指针
// 输出: pDst - 目标PDU串指针
// 返回: 目标PDU串长度
int gsmEncodePdu(const SM_PARAM* pSrc, char* pDst)
{
	int nLength;			// 内部用的串长度
	int nDstLength;			// 目标PDU串长度
	unsigned char buf[512];	// 内部用的缓冲区
	memset(buf,0,sizeof(buf));
	
	// SMSC地址信息段
	// 格式(13800311500)
	nLength = strlen(pSrc->SCA);	// SMSC地址字符串的长度
	if(nLength!=0)
	{
		buf[0] = (char)((nLength & 1) == 0 ? nLength : nLength + 1) / 2 + 2;	// SMSC地址信息长度
		buf[1] = 0x91;		// 固定: 用国际格式号码
		buf[2] = 0x68;
		nDstLength = gsmBytes2String(buf, pDst, 3);		// 转换3个字节到目标PDU串
		nDstLength += gsmInvertNumbers(pSrc->SCA, &pDst[nDstLength], nLength);	// 转换SMSC号码到目标PDU串
	}
	else
	{
		buf[0] = 0;
		nDstLength = gsmBytes2String(buf, pDst, 1);		// 转换1个字节到目标PDU串
	}
	
	// TPDU段基本参数、目标地址等
	nLength = strlen(pSrc->TPA);	// TP-DA地址字符串的长度
	buf[0] = 0x31;					// 发送短信标识类型
	buf[1] = 0;						// TP-MR=0
	buf[2] = (char)nLength;			// 目标地址数字个数(TP-DA地址字符串真实长度)
	buf[3] = 0x81;					// 固定: 用国际格式号码
	nDstLength += gsmBytes2String(buf, &pDst[nDstLength], 4);	// 转换4个字节到目标PDU串
	nDstLength += gsmInvertNumbers(pSrc->TPA, &pDst[nDstLength], nLength);	// 转换TP-DA到目标PDU串
	
	// TPDU段协议标识、编码方式、用户信息等
	nLength = strlen(pSrc->TP_UD);	// 用户信息字符串的长度
	buf[0] = pSrc->TP_PID;			// 协议标识(TP-PID)
	buf[1] = pSrc->TP_DCS;			// 用户信息编码方式(TP-DCS)
	buf[2] = 0xa7;					// 有效期(TP-VP)为24小时
	if(pSrc->TP_DCS == GSM_7BIT)
	{
		// 7-bit编码方式
		buf[3] = nLength;			// 编码前长度
		nLength = gsmEncode7bit(pSrc->TP_UD, &buf[4], nLength+1) + 4;	// 转换TP-DA到目标PDU串
	}
	else if(pSrc->TP_DCS == GSM_UCS2)
	{
		// UCS2编码方式
		buf[3] = gsmEncodeUcs2(pSrc->TP_UD, &buf[4], nLength);	// 转换TP-DA到目标PDU串
		nLength = buf[3] + 4;		// nLength等于该段数据长度
	}
	else
	{
		// 8-bit编码方式
		buf[3] = gsmEncode8bit(pSrc->TP_UD, &buf[4], nLength);	// 转换TP-DA到目标PDU串
		nLength = buf[3] + 4;		// nLength等于该段数据长度
	}
	nDstLength += gsmBytes2String(buf, &pDst[nDstLength], nLength);		// 转换该段数据到目标PDU串
	
	// 返回目标字符串长度
	return nDstLength;
}

// PDU解码,用于接收、阅读短消息
// 输入: pSrc - 源PDU串指针
// 输出: pDst - 目标PDU参数指针
// 返回: 用户信息串长度
int gsmDecodePdu(const char* pSrc, SM_PARAM* pDst)
{
	int nDstLength;					// 目标PDU串长度
	unsigned char tmp,temp_86;		// 内部用的临时字节变量
	unsigned char buf[512];			// 内部用的缓冲区
	memset(buf,0,sizeof(buf));
	
	// SMSC地址信息段
	gsmString2Bytes(pSrc, &tmp, 2);	// 取长度
	tmp = (tmp-1) * 2;	// SMSC号码串长度
	// 0x0891683139831012F7
	pSrc += 4;			// 指针后移,忽略SCA地址长度及SCA地址类型
	// 跳过SMSC号码中的"+86"部分(联通及小灵通情况未知)
	// 0x86两个字节
	tmp -= 2;
	pSrc += 2;
	// 获取短信中心号码
	gsmSerializeNumbers(pSrc, pDst->SCA, tmp);	// 转换SMSC号码到目标PDU串
	pSrc += tmp;	// 指针后移
	
	// TPDU段基本参数
	gsmString2Bytes(pSrc, &tmp, 2);	// 取基本参数
	pSrc += 2;		// 指针后移
	
	// 取短信来源号码
	gsmString2Bytes(pSrc, &tmp, 2);	// 取长度
	if(tmp & 1) tmp += 1;	// 调整奇偶性
	pSrc += 2;			// 指针后移,忽略处理长度字节
	pSrc += 2;			// 指针后移,忽略处理来源端口类型(0x91)
	gsmString2Bytes(pSrc, &temp_86, 2);	// 取TP-RA号码的头两个字节
	if(temp_86==0x68)
	{
		tmp -= 2;		// 原TP-RA号码长度减少两个字节
		pSrc += 2;		// 指针后移,忽略"+86"两个字节部分
	}
	gsmSerializeNumbers(pSrc, pDst->TPA, tmp);	// 取TP-RA号码
	pSrc += tmp;		// 指针后移
	
	// TPDU段协议标识、编码方式、用户信息等
	gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_PID, 2);	// 取协议标识(TP-PID)
	pSrc += 2;		// 指针后移
	gsmString2Bytes(pSrc, (unsigned char*)&pDst->TP_DCS, 2);	// 取编码方式(TP-DCS)
	pSrc += 2;		// 指针后移
	gsmSerializeNumbers(pSrc, pDst->TP_SCTS, 14);		// 服务时间戳字符串(TP_SCTS)
	pSrc += 14;		// 指针后移
	
	// 开始处理时间字符串
	char szTime[32];
	char szTmp1[3];
	char szTmp2[3];
	char szTmp3[3];
	char szTmp4[3];
	char szTmp5[3];
	char szTmp6[3];
	char szTmp7[3];
	memset(szTime,0,sizeof(szTime));
	memset(szTmp1,0,sizeof(szTmp1));
	memset(szTmp2,0,sizeof(szTmp2));
	memset(szTmp3,0,sizeof(szTmp3));
	memset(szTmp4,0,sizeof(szTmp4));
	memset(szTmp5,0,sizeof(szTmp5));
	memset(szTmp6,0,sizeof(szTmp6));
	memset(szTmp7,0,sizeof(szTmp7));
	if(pDst->TP_SCTS[0]>'8')
		sprintf(szTmp1,"19");
	else
		sprintf(szTmp1,"20");
	memcpy(szTmp2,&pDst->TP_SCTS[0],2);
	memcpy(szTmp3,&pDst->TP_SCTS[2],2);
	memcpy(szTmp4,&pDst->TP_SCTS[4],2);
	memcpy(szTmp5,&pDst->TP_SCTS[6],2);
	memcpy(szTmp6,&pDst->TP_SCTS[8],2);
	memcpy(szTmp7,&pDst->TP_SCTS[10],2);
	sprintf(szTime,"%s%s-%s-%s %s:%s:%s",szTmp1,szTmp2,szTmp3,szTmp4,szTmp5,szTmp6,szTmp7);
	// 写入短信接收时间
	memset(pDst->TP_SCTS,0,sizeof(pDst->TP_SCTS));
	sprintf(pDst->TP_SCTS,szTime);
	// 时间字符串处理完成
	
	gsmString2Bytes(pSrc, &tmp, 2);		// 用户信息长度(TP-UDL)
	pSrc += 2;		// 指针后移
	if(pDst->TP_DCS == GSM_7BIT)
	{
		// 7-bit解码
		nDstLength = gsmString2Bytes(pSrc, buf, tmp & 7 ? (int)tmp * 7 / 4 + 2 : (int)tmp * 7 / 4);		// 格式转换
		gsmDecode7bit(buf, pDst->TP_UD, nDstLength);	// 转换到TP-DU
		nDstLength = tmp;
	}
	else if(pDst->TP_DCS == GSM_UCS2)
	{
		// UCS2解码
		nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2);			// 格式转换
		nDstLength = gsmDecodeUcs2(buf, pDst->TP_UD, nDstLength);	// 转换到TP-DU
	}
	else
	{
		// 8-bit解码
		nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2);			// 格式转换
		nDstLength = gsmDecode8bit(buf, pDst->TP_UD, nDstLength);	// 转换到TP-DU
	}
	
	// 返回目标字符串长度
	return nDstLength;
}

int WINAPI EncodePdu(char* pPort,char* pContent,char* pSmsc,char* pPreSend,char* pPdu)
{
	SM_PARAM pSrc;
	char szCmd[32];		// 命令串
	char szPdu[512];	// PDU串
	int nPduLength;		// PDU串长度
	unsigned char nSmscLength;	// SMSC串长度
	
	// 初始化基础数据
	memset(&pSrc,0,sizeof(pSrc));
	sprintf(pSrc.SCA,pSmsc);
	sprintf(pSrc.TPA,pPort);
	sprintf(pSrc.TP_UD,pContent);
	pSrc.TP_DCS = GSM_UCS2;
	pSrc.TP_PID = 0;
	memset(szCmd,0,sizeof(szCmd));
	memset(szPdu,0,sizeof(szPdu));
	
	// 调用gsmEncodePdu进行编码
	nPduLength = gsmEncodePdu(&pSrc, szPdu);	// 根据PDU参数,编码PDU串
	strcat(szPdu, "\x1a");		// 以Ctrl-Z结束
	gsmString2Bytes(szPdu, &nSmscLength, 2);	// 取PDU串中的SMSC信息长度
	nSmscLength++;	// 加上长度字节本身的长度
	// 发送短信的指令中的长度,不包括SMSC信息长度,以数据字节计
	sprintf(szCmd, "AT+CMGS=%d\r", nPduLength / 2 - nSmscLength);	// 生成短信发送长度指令
	
	// 填写返回数据内容
	sprintf(pPreSend,szCmd);
	sprintf(pPdu,szPdu);
	
	return 0;
}

int WINAPI DecodePdu(char* pPort,char* pContent,char* pTime,char* pPdu)
{
	SM_PARAM pMsg;

	// 初始化基础数据
	memset(&pMsg,0,sizeof(pMsg));
	
	// 调用gsmDecodePdu进行解码
	gsmDecodePdu(pPdu, &pMsg);	// 进行PDU串解码

	// 填写返回数据内容
	sprintf(pPort,pMsg.TPA);
	sprintf(pContent,pMsg.TP_UD);
	sprintf(pTime,pMsg.TP_SCTS);
	
	return 0;
}

⌨️ 快捷键说明

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