📄 gprser.cpp
字号:
*/
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 + -