📄 sms.c
字号:
#include <w77e58.h>
#include "global.h"
#include "io.h"
#include "timer.h"
#include "serial.h"
#include "gsm.h"
//用户信息编码方式
#define GSM_7BIT 0
#define GSM_8BIT 4
#define GSM_UCS2 8
// 短消息参数结构,编码/解码共用
// 其中,字符串以0结尾
#if 1
typedef struct
{
char SCA[16]; // 短消息服务中心号码(SMSC地址)
char TPA[16]; // 目标号码或回复号码(TP-DA或TP-RA)
char TP_PID; // 用户信息协议标识(TP-PID)
char TP_DCS; // 用户信息编码方式(TP-DCS)
char TP_SCTS[16]; // 服务时间戳字符串(TP_SCTS), 接收时用到
char TP_UD[161]; // 原始用户信息(编码前或解码后的TP-UD)
char index; // 短消息序号,在读取时用到
} SM_PARAM;
#else
typedef struct
{
char xdata SCA[16]; //_at_ 0x000; // 短消息服务中心号码(SMSC地址)
char xdata TPA[16]; //_at_ 0x016; // 目标号码或回复号码(TP-DA或TP-RA)
char xdata TP_PID; //_at_ 0x032; // 用户信息协议标识(TP-PID)
char xdata TP_DCS; // _at_ 0x033; // 用户信息编码方式(TP-DCS)
char xdata TP_SCTS[16]; // _at_ 0x049; // 服务时间戳字符串(TP_SCTS), 接收时用到
char xdata TP_UD[161]; // _at_ 0x064; // 原始用户信息(编码前或解码后的TP-UD)
char xdata index; // _at_ 0x065; // 短消息序号,在读取时用到
} SM_PARAM;
#endif
char xdata SCA1[16]; //_at_ 0x000; // 短消息服务中心号码(SMSC地址)
char xdata TPA1[16]; //_at_ 0x016; // 目标号码或回复号码(TP-DA或TP-RA)
char xdata TP_PID1; //_at_ 0x032; // 用户信息协议标识(TP-PID)
char xdata TP_DCS1; // _at_ 0x033; // 用户信息编码方式(TP-DCS)
char xdata TP_SCTS1[16]; // _at_ 0x049; // 服务时间戳字符串(TP_SCTS), 接收时用到
char xdata TP_UD1[161]; // _at_ 0x064; // 原始用户信息(编码前或解码后的TP-UD)
char xdata index1; // _at_ 0x065; // 短消息序号,在读取时用到
//char xdata cmd[16]
//char xdata pdu[512];
//char xdata ans[256]; //Read GSM answer buff;
int gsmDecode7bit(uchar xdata * pSrc, char xdata * pDst, int xdata nSrcLength);
/**************************************************************************************************************
GSM_IO10: L->H-L,H=40-50 ms,wake up MCU,and gsm set IO11 to low.
GSM_ROW4: ,Wake up GSM.
Host to GSM: check GSM sleep? if yes,Host pull low GSM_ROW4 to low 50 ms,at once send AT command.
**************************************************************************************************************/
void gsmModule_init(void)
{
GSM_PWON=HIGH;
delay_ms(5);
GSM_PWON=LOW;
delay_ms(200); //Over 120 ms,M32 power on.
GSM_PWON=HIGH;
}
/************************************************************************************************
* int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
* 7-bit编码
* pSrc: 源字符串指针
* pDst: 目标编码串指针
* nSrcLength: 源字符串长度
* 返回: 目标编码串长度
***************************************************************************************/
int gsmEncode7bit(char xdata* pSrc, unsigned char xdata* pDst, int xdata nSrcLength)
{
int xdata nSrc; // 源字符串的计数值
int xdata nDst; // 目标编码串的计数值
int xdata nChar; // 当前正在处理的组内字符字节的序号,范围是0-7
unsigned char xdata nLeft; // 上一字节残余的数据
// 计数值初始化
nSrc = 0;
nDst = 0;
// 将源串每8个字节分为一组,压缩成7个字节
// 循环该处理过程,直至源串被处理完
// 如果分组不到8字节,也能正确处理
while(nSrc<nSrcLength)
{
// 取源字符串的计数值的最低3位
nChar = nSrc & 7;
// 处理源串的每个字节
if(nChar == 0)
{
// 组内第一个字节,只是保存起来,待处理下一个字节时使用
nLeft = *pSrc;
}
else
{
// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
*pDst = (*pSrc << (8-nChar))| nLeft;
// 将该字节剩下的左边部分,作为残余数据保存起来
nLeft = *pSrc >> nChar;
// 修改目标串的指针和计数值
pDst++;
nDst++;
}
// 修改源串的指针和计数值
pSrc++;
nSrc++;
}
// 返回目标串长度
return nDst;
}
int gsmEncode8bit(char xdata * pSrc, unsigned char xdata* pDst, int xdata nSrcLength)
{
}
/*****************************************************************************************************
* int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
*
* 7-bit解码
* pSrc: 源编码串指针
* pDst: 目标字符串指针
* nSrcLength: 源编码串长度
* 返回: 目标字符串长度
*******************************************************************************************************/
//int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
int gsmDecode7bit(uchar xdata * pSrc, char xdata * pDst, int xdata nSrcLength)
{
int xdata nSrc; // 源字符串的计数值
int xdata nDst; // 目标解码串的计数值
int xdata nByte; // 当前正在处理的组内字节的序号,范围是0-6
unsigned char xdata 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;
}
//int gsmDecode8bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
int gsmDecode8bit(uchar xdata * pSrc, char xdata * pDst, int xdata nSrcLength)
{
}
/***********************************************************************************************
需要指出的是,7-bit的字符集与ANSI标准字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、
阿拉伯数字和常用符号的位置 两者是一样的。用上面介绍的算法收发纯英文短消息,一般情况应该是够用了。
如果是法语、德语、西班牙语等,含有 “?”、 “é”这一类字 符,则要按上面编码的输出去查表,请参阅GSM 03.38
的规定。
***********************************************************************************************/
#if 0
/************************************************************************************************
UCS2编码是将每个字符(1-2个字节)按照ISO/IEC10646的规定,转变为16位的Unicode宽字符。在Windows系统中,特
别是在2000/XP中,可以简单地调用API 函数实现编码和解码。如果没有系统的支持,比如用单片机控制手机模块收
发短消息,只好用查表法解决了。
Windows 用C实现UCS2编码和解码的算法如下:
*************************************************************************************************/
/*************************************************************************************************
// UCS2编码
// pSrc: 源字符串指针
// pDst: 目标编码串指针
// nSrcLength: 源字符串长度
// 返回: 目标编码串长度
**************************************************************************************************/
int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
int nDstLength; // UNICODE宽字符数目
WCHAR wchar[128]; // UNICODE串缓冲区
// 字符串-->UNICODE串
nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
// 高低字节对调,输出
for(int i=0; i<nDstLength; i++)
{
// 先输出高位字节
*pDst++ = wchar[i] >> 8;
// 后输出低位字节
*pDst++ = wchar[i] & 0xff;
}
// 返回目标编码串长度
return nDstLength * 2;
}
/**************************************************************************************************
// UCS2解码
// pSrc: 源编码串指针
// pDst: 目标字符串指针
// nSrcLength: 源编码串长度
// 返回: 目标字符串长度
**************************************************************************************************/
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
int nDstLength; // UNICODE宽字符数目
WCHAR wchar[128]; // UNICODE串缓冲区
// 高低字节对调,拼成UNICODE
for(int i=0; i<nSrcLength/2; i++)
{
// 先高位字节
wchar[i] = *pSrc++ << 8;
// 后低位字节
wchar[i] = *pSrc++;
}
// UNICODE串-->字符串
nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
// 输出字符串加个结束符
pDst[nDstLength] = '\0';
// 返回目标字符串长度
return nDstLength;
}
#endif
/*************************************************************************************************
用以上编码和解码模块,还不能将短消息字符串编码为PDU串需要的格式,也不能直接将PDU串中的用户信息解码为
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -