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

📄 gprser.cpp

📁 gprs开发使用程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
*/
DWORD CGPRSer::gprsDecode7bit(const UCHAR *pSrc, TCHAR *pDst, INT nSrcLength)
{
	int nSrc;		/* 源字符串的计数值 */
	int nDst;		/* 目标解码串的计数值 */
	int nByte;		/* 当前正在处理的组内字节的序号,范围是0-6 */
	UCHAR 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;
}

/*! 从短消息数据数据包提取PDU数据帧函数
	\param [in] pSrc - 短消息数据数据包
	\param [out] pDst - PDU数据帧
	\return 无
*/
VOID CGPRSer::gprsGetPdu(CHAR *pSrc, CHAR *pDst)
{
	if ((pSrc = strstr(pSrc, "+CMGR:")) != NULL)
	{
		pSrc = strstr(pSrc, "\r\n");	/* 找下一行 */
		if (pSrc != NULL)
		{
			pSrc += 2;		/* 跳过"\r\n", 定位到PDU */
		}
		strcpy(pDst, pSrc);
	}
}

/*! 8bit解码
	\param [in] pSrc - 源编码串指针
	\param [in] nSrcLength -  源编码串长度
	\param [out] pDst -  目标字符串指针
	\return 目标字符串长度 
*/
DWORD CGPRSer::gprsDecode8bit(const UCHAR *pSrc, TCHAR *pDst, DWORD nSrcLength)
{
	/* 简单复制 */
	memcpy(pDst, pSrc, nSrcLength);

	/* 输出字符串加个结束符 */
	*pDst = '\0';

	return nSrcLength;
}

/*! 8bit编码
	\param [in] pSrc - 源字符串指针
	\param [in] nSrcLength - 源字符串长度 
	\param [out] pDst - 目标编码串指针
	\return 目标编码串长度 
*/
DWORD CGPRSer::gprsEncode8bit(const TCHAR *pSrc, UCHAR *pDst, DWORD nSrcLength)
{
	/* 简单复制 */
	memcpy(pDst, pSrc, nSrcLength);

	return nSrcLength;
}

/*! PDU解码,用于接收、阅读短消息
	\param [in] pSrc - 源PDU串指针
	\param [out] pDst - 目标PDU参数指针
	\return 用户信息串长度 
*/
DWORD CGPRSer::gprsDecodePdu(const CHAR *pSrc, SM_PARAM *pDst)
{
	int nDstLength;		/* 目标PDU串长度 */
	UCHAR tmp;			/* 内部用的临时字节变量 */
	UCHAR buf[256];		/* 内部用的缓冲区 */

	/* SMSC地址信息段 */
	gprsString2Bytes(pSrc, &tmp, 2);	/* 取长度 */
	tmp = (tmp - 1) * 2;	/* SMSC号码串长度 */
	pSrc += 4;			/* 指针后移,忽略了SMSC地址格式 */
	gprsSerializeNumbers(pSrc, pDst->SCA, tmp);	/* 转换SMSC号码到目标PDU串 */
	pSrc += tmp;		/* 指针后移 */

	/* TPDU段基本参数 */
	gprsString2Bytes(pSrc, &tmp, 2);	/* 取基本参数 */
	pSrc += 2;		/* 指针后移 */

	/* 取回复号码 */
	gprsString2Bytes(pSrc, &tmp, 2);	/* 取长度 */
	if(tmp & 1) tmp += 1;	/* 调整奇偶性 */
	pSrc += 4;			/* 指针后移,忽略了回复地址(TP-RA)格式 */
	gprsSerializeNumbers(pSrc, pDst->TPA, tmp);	/* 取TP-RA号码 */
	pSrc += tmp;		/* 指针后移 */

	/* TPDU段协议标识、编码方式、用户信息等 */
	gprsString2Bytes(pSrc, (UCHAR*)&pDst->TP_PID, 2);	/* 取协议标识(TP-PID) */
	pSrc += 2;		/* 指针后移 */
	gprsString2Bytes(pSrc, (UCHAR*)&pDst->TP_DCS, 2);	/* 取编码方式(TP-DCS) */
	pSrc += 2;		/* 指针后移 */
	gprsSerializeNumbers(pSrc, pDst->TP_SCTS, 14);		/* 服务时间戳字符串(TP_SCTS)  */
	pSrc += 14;		/* 指针后移 */
	gprsString2Bytes(pSrc, &tmp, 2);	/* 用户信息长度(TP-UDL) */
	pSrc += 2;		/* 指针后移 */
	if(pDst->TP_DCS == GSM_7BIT)	
	{
		/* 7-bit解码 */
		nDstLength = gprsString2Bytes(pSrc, buf, tmp & 7 ? (int)tmp * 7 / 4 + 2 : (int)tmp * 7 / 4);	/* 格式转换 */
		gprsDecode7bit(buf, pDst->TP_UD, nDstLength);	/* 转换到TP-DU */
		nDstLength = tmp;
	}
	else if(pDst->TP_DCS == GSM_UCS2)
	{
		/* UCS2解码 */
		nDstLength = gprsString2Bytes(pSrc, buf, tmp * 2);			/* 格式转换 */
		nDstLength = gprsDecodeUcs2(buf, pDst->TP_UD, nDstLength);	/* 转换到TP-DU */
	}
	else
	{
		/* 8-bit解码 */
		nDstLength = gprsString2Bytes(pSrc, buf, tmp * 2);			/* 格式转换 */
		nDstLength = gprsDecode8bit(buf, pDst->TP_UD, nDstLength);	/* 转换到TP-DU */
	}

	/* 返回目标字符串长度 */
	return nDstLength;
}

/*! 字节数据转换为可打印字符串
 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
	\param [in] pSrc - 源数据指针 
	\param [in] nSrcLength - 源数据长度
	\param [out] pDst - 目标字符串指针 
	\return 目标字符串长度 
*/
DWORD CGPRSer::gprsBytes2String(const UCHAR *pSrc, CHAR *pDst, DWORD nSrcLength)
{
	const char tab[]="0123456789ABCDEF";	/* 0x0-0xf的字符查找表 */

	for (INT i = 0; i < (INT)nSrcLength; i++)
	{
		
		*pDst++ = tab[pSrc[i] >> 4];		/* 输出高4位 */
		*pDst++ = tab[pSrc[i] & 0x0f];	/* 输出低4位 */
	}

	/* 输出字符串加个结束符 */
	*pDst = '\0';

	/* 返回目标字符串长度 */
	return (nSrcLength * 2);
}

/*! 两两颠倒的字符串转换为正常顺序的字符串
	如:"683158812764F8" --> "8613851872468"
	\param [in] pSrc - 源字符串指针
	\param [in] nSrcLength - 源字符串长度 
	\param [out] pDst - 目标字符串指针
	\return 目标字符串长度 
*/
DWORD CGPRSer::gprsSerializeNumbers(const CHAR *pSrc, CHAR *pDst, DWORD nSrcLength)
{
	DWORD nDstLength;		/* 目标字符串长度 */
	char ch;			/* 用于保存一个字符 */

	/* 复制串长度 */
	nDstLength = nSrcLength;

	/* 两两颠倒 */
	for(INT i=0; i < (INT)nSrcLength; i+=2)
	{
		ch = *pSrc++;		/* 保存先出现的字符 */
		*pDst++ = *pSrc++;	/* 复制后出现的字符 */
		*pDst++ = ch;		/* 复制先出现的字符 */
	}

	/* 最后的字符是'F'吗?*/
	if(*(pDst-1) == 'F')
	{
		pDst--;
		nDstLength--;		/* 目标字符串长度减1 */
	}

	/* 输出字符串加个结束符 */
	*pDst = '\0';

	/* 返回目标字符串长度 */
	return nDstLength;
}

/*! 可打印字符串转换为字节数据
	如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
	\param [in] pSrc - 源字符串指针
	\param [in] nSrcLength - 源字符串长度
	\param [out] pDst - 目标数据指针
	\return 目标数据长度 
*/
DWORD CGPRSer::gprsString2Bytes(const CHAR *pSrc, UCHAR *pDst, DWORD nSrcLength)
{
	for (int i = 0; i < (INT)nSrcLength; i += 2)
	{
		/* 输出高4位 */
		if ((*pSrc >= '0') && (*pSrc <= '9'))
		{
			*pDst = (*pSrc - '0') << 4;
		}
		else
		{
			*pDst = (*pSrc - 'A' + 10) << 4;
		}

		pSrc++;

		/* 输出低4位 */
		if ((*pSrc>='0') && (*pSrc<='9'))
		{
			*pDst |= *pSrc - '0';
		}
		else
		{
			*pDst |= *pSrc - 'A' + 10;
		}

		pSrc++;
		pDst++;
	}

	/* 返回目标数据长度 */
	return (nSrcLength / 2);
}

/*! 正常顺序的字符串转换为两两颠倒的字符串,若长度为奇数,补'F'凑成偶数
	如:"8613851872468" --> "683158812764F8"
	\param [in] pSrc - 源字符串指针
	\param [in] nSrcLength - 源字符串长度
	\param [out] pDst - 目标字符串指针
	\return 目标字符串长度 
*/
DWORD CGPRSer::gprsInvertNumbers(const CHAR *pSrc, CHAR *pDst, DWORD nSrcLength)
{
	int nDstLength;		/* 目标字符串长度 */
	char ch;			/* 用于保存一个字符 */

	/* 复制串长度 */
	nDstLength = nSrcLength;

	/* 两两颠倒 */
	for(int i=0; i < (INT)nSrcLength;i+=2)
	{
		ch = *pSrc++;		/* 保存先出现的字符 */
		*pDst++ = *pSrc++;	/* 复制后出现的字符 */
		*pDst++ = ch;		/* 复制先出现的字符 */
	}

	/* 源串长度是奇数吗?*/
	if(nSrcLength & 1)
	{
		*(pDst-2) = 'F';	/* 补'F' */
		nDstLength++;		/* 目标串长度加1 */
	}

	/* 输出字符串加个结束符 */
	*pDst = '\0';

	/* 返回目标字符串长度 */
	return nDstLength;
}


⌨️ 快捷键说明

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