?? sms.c
字號(hào):
#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
// 短消息參數(shù)結(jié)構(gòu),編碼/解碼共用
// 其中,字符串以0結(jié)尾
#if 1
typedef struct
{
char SCA[16]; // 短消息服務(wù)中心號(hào)碼(SMSC地址)
char TP_PID; // 用戶信息協(xié)議標(biāo)識(shí)(TP-PID)
char TP_DCS; // 用戶信息編碼方式(TP-DCS)
char TP_SCTS[16]; // 服務(wù)時(shí)間戳字符串(TP_SCTS), 接收時(shí)用到
char TP_UD[161]; // 原始用戶信息(編碼前或解碼后的TP-UD)
char index; // 短消息序號(hào),在讀取時(shí)用到
} SM_PARAM;
#else
typedef struct
{
char xdata SCA[16]; //_at_ 0x000; // 短消息服務(wù)中心號(hào)碼(SMSC地址)
char xdata TPA[16]; //_at_ 0x016; // 目標(biāo)號(hào)碼或回復(fù)號(hào)碼(TP-DA或TP-RA)
char xdata TP_PID; //_at_ 0x032; // 用戶信息協(xié)議標(biāo)識(shí)(TP-PID)
char xdata TP_DCS; // _at_ 0x033; // 用戶信息編碼方式(TP-DCS)
char xdata TP_SCTS[16]; // _at_ 0x049; // 服務(wù)時(shí)間戳字符串(TP_SCTS), 接收時(shí)用到
char xdata TP_UD[161]; // _at_ 0x064; // 原始用戶信息(編碼前或解碼后的TP-UD)
char xdata index; // _at_ 0x065; // 短消息序號(hào),在讀取時(shí)用到
} SM_PARAM;
#endif
char xdata SCA1[16]; //_at_ 0x000; // 短消息服務(wù)中心號(hào)碼(SMSC地址)
char xdata TPA1[16]; //_at_ 0x016; // 目標(biāo)號(hào)碼或回復(fù)號(hào)碼(TP-DA或TP-RA)
char xdata TP_PID1; //_at_ 0x032; // 用戶信息協(xié)議標(biāo)識(shí)(TP-PID)
char xdata TP_DCS1; // _at_ 0x033; // 用戶信息編碼方式(TP-DCS)
char xdata TP_SCTS1[16]; // _at_ 0x049; // 服務(wù)時(shí)間戳字符串(TP_SCTS), 接收時(shí)用到
char xdata TP_UD1[161]; // _at_ 0x064; // 原始用戶信息(編碼前或解碼后的TP-UD)
char xdata index1; // _at_ 0x065; // 短消息序號(hào),在讀取時(shí)用到
//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: 目標(biāo)編碼串指針
* nSrcLength: 源字符串長(zhǎng)度
* 返回: 目標(biāo)編碼串長(zhǎng)度
***************************************************************************************/
int gsmEncode7bit(char xdata* pSrc, unsigned char xdata* pDst, int xdata nSrcLength)
{
int xdata nSrc; // 源字符串的計(jì)數(shù)值
int xdata nDst; // 目標(biāo)編碼串的計(jì)數(shù)值
int xdata nChar; // 當(dāng)前正在處理的組內(nèi)字符字節(jié)的序號(hào),范圍是0-7
unsigned char xdata nLeft; // 上一字節(jié)殘余的數(shù)據(jù)
// 計(jì)數(shù)值初始化
nSrc = 0;
nDst = 0;
// 將源串每8個(gè)字節(jié)分為一組,壓縮成7個(gè)字節(jié)
// 循環(huán)該處理過(guò)程,直至源串被處理完
// 如果分組不到8字節(jié),也能正確處理
while(nSrc<nSrcLength)
{
// 取源字符串的計(jì)數(shù)值的最低3位
nChar = nSrc & 7;
// 處理源串的每個(gè)字節(jié)
if(nChar == 0)
{
// 組內(nèi)第一個(gè)字節(jié),只是保存起來(lái),待處理下一個(gè)字節(jié)時(shí)使用
nLeft = *pSrc;
}
else
{
// 組內(nèi)其它字節(jié),將其右邊部分與殘余數(shù)據(jù)相加,得到一個(gè)目標(biāo)編碼字節(jié)
*pDst = (*pSrc << (8-nChar))| nLeft;
// 將該字節(jié)剩下的左邊部分,作為殘余數(shù)據(jù)保存起來(lái)
nLeft = *pSrc >> nChar;
// 修改目標(biāo)串的指針和計(jì)數(shù)值
pDst++;
nDst++;
}
// 修改源串的指針和計(jì)數(shù)值
pSrc++;
nSrc++;
}
// 返回目標(biāo)串長(zhǎng)度
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: 目標(biāo)字符串指針
* nSrcLength: 源編碼串長(zhǎng)度
* 返回: 目標(biāo)字符串長(zhǎng)度
*******************************************************************************************************/
//int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
int gsmDecode7bit(uchar xdata * pSrc, char xdata * pDst, int xdata nSrcLength)
{
int xdata nSrc; // 源字符串的計(jì)數(shù)值
int xdata nDst; // 目標(biāo)解碼串的計(jì)數(shù)值
int xdata nByte; // 當(dāng)前正在處理的組內(nèi)字節(jié)的序號(hào),范圍是0-6
unsigned char xdata nLeft; // 上一字節(jié)殘余的數(shù)據(jù)
// 計(jì)數(shù)值初始化
nSrc = 0;
nDst = 0;
// 組內(nèi)字節(jié)序號(hào)和殘余數(shù)據(jù)初始化
nByte = 0;
nLeft = 0;
// 將源數(shù)據(jù)每7個(gè)字節(jié)分為一組,解壓縮成8個(gè)字節(jié)
// 循環(huán)該處理過(guò)程,直至源數(shù)據(jù)被處理完
// 如果分組不到7字節(jié),也能正確處理
while(nSrc<nSrcLength)
{
// 將源字節(jié)右邊部分與殘余數(shù)據(jù)相加,去掉最高位,得到一個(gè)目標(biāo)解碼字節(jié)
*pDst = ((*pSrc << nByte) | nLeft) & 0x7f;
// 將該字節(jié)剩下的左邊部分,作為殘余數(shù)據(jù)保存起來(lái)
nLeft = *pSrc >> (7-nByte);
// 修改目標(biāo)串的指針和計(jì)數(shù)值
pDst++;
nDst++;
// 修改字節(jié)計(jì)數(shù)值
nByte++;
// 到了一組的最后一個(gè)字節(jié)
if(nByte == 7)
{
// 額外得到一個(gè)目標(biāo)解碼字節(jié)
*pDst = nLeft;
// 修改目標(biāo)串的指針和計(jì)數(shù)值
pDst++;
nDst++;
// 組內(nèi)字節(jié)序號(hào)和殘余數(shù)據(jù)初始化
nByte = 0;
nLeft = 0;
}
// 修改源串的指針和計(jì)數(shù)值
pSrc++;
nSrc++;
}
*pDst = 0;
// 返回目標(biāo)串長(zhǎng)度
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標(biāo)準(zhǔn)字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、
阿拉伯?dāng)?shù)字和常用符號(hào)的位置 兩者是一樣的。用上面介紹的算法收發(fā)純英文短消息,一般情況應(yīng)該是夠用了。
如果是法語(yǔ)、德語(yǔ)、西班牙語(yǔ)等,含有 “?”、 “é”這一類字 符,則要按上面編碼的輸出去查表,請(qǐng)參閱GSM 03.38
的規(guī)定。
***********************************************************************************************/
#if 0
/************************************************************************************************
UCS2編碼是將每個(gè)字符(1-2個(gè)字節(jié))按照ISO/IEC10646的規(guī)定,轉(zhuǎn)變?yōu)?6位的Unicode寬字符。在Windows系統(tǒng)中,特
別是在2000/XP中,可以簡(jiǎn)單地調(diào)用API 函數(shù)實(shí)現(xiàn)編碼和解碼。如果沒(méi)有系統(tǒng)的支持,比如用單片機(jī)控制手機(jī)模塊收
發(fā)短消息,只好用查表法解決了。
Windows 用C實(shí)現(xiàn)UCS2編碼和解碼的算法如下:
*************************************************************************************************/
/*************************************************************************************************
// UCS2編碼
// pSrc: 源字符串指針
// pDst: 目標(biāo)編碼串指針
// nSrcLength: 源字符串長(zhǎng)度
// 返回: 目標(biāo)編碼串長(zhǎng)度
**************************************************************************************************/
int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
int nDstLength; // UNICODE寬字符數(shù)目
WCHAR wchar[128]; // UNICODE串緩沖區(qū)
// 字符串-->UNICODE串
nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
// 高低字節(jié)對(duì)調(diào),輸出
for(int i=0; i<nDstLength; i++)
{
// 先輸出高位字節(jié)
*pDst++ = wchar[i] >> 8;
// 后輸出低位字節(jié)
*pDst++ = wchar[i] & 0xff;
}
// 返回目標(biāo)編碼串長(zhǎng)度
return nDstLength * 2;
}
/**************************************************************************************************
// UCS2解碼
// pSrc: 源編碼串指針
// pDst: 目標(biāo)字符串指針
// nSrcLength: 源編碼串長(zhǎng)度
// 返回: 目標(biāo)字符串長(zhǎng)度
**************************************************************************************************/
{
int nDstLength; // UNICODE寬字符數(shù)目
WCHAR wchar[128]; // UNICODE串緩沖區(qū)
// 高低字節(jié)對(duì)調(diào),拼成UNICODE
for(int i=0; i<nSrcLength/2; i++)
{
// 先高位字節(jié)
wchar[i] = *pSrc++ << 8;
// 后低位字節(jié)
wchar[i] = *pSrc++;
}
// UNICODE串-->字符串
nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
// 輸出字符串加個(gè)結(jié)束符
pDst[nDstLength] = '\0';
// 返回目標(biāo)字符串長(zhǎng)度
return nDstLength;
}
#endif
/*************************************************************************************************
用以上編碼和解碼模塊,還不能將短消息字符串編碼為PDU串需要的格式,也不能直接將PDU串中的用戶信息解碼為
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -