📄 sms.cpp
字号:
#include "sms.h"
#include <Dialogs.hpp>
/*
AT命令:每个指令以AT开头,以回车结尾。每个命令执行成功与否都有相应的返回。其
他一些非预期的信息(如有人拨号进来、线路无信号等),模块将有对应的一些信息提
示,接收端可做相应的处理。其控制符有如下两个:
结束符(<CR>)十六进制的0x0D, 十进制值:13,char表示值为:'\n'
发送符(<Ctrl/Z>)十六进制的0x1A,十进制值:26;
*/
//---------------------------------------------------------------------------
phone_type __stdcall get_phone_type(char *p)
{
if (p[0] == '0')
return _wi; //如果电话首位是0,说明是小灵通。
else
return _mp; //否则统一认为是手机号码。
}
//---------------------------------------------------------------------------
void __stdcall encode_unicode(char *_dest, char *_src
, unsigned short *_len, unsigned short *_code_len)
{
unsigned short len = 0;
len = MultiByteToWideChar(CP_ACP, 0, _src, -1, NULL, 0);
wchar_t *cur = new wchar_t[len];
try
{
MultiByteToWideChar(CP_ACP, 0, _src, -1, cur, len);
for (unsigned int i = 0; i < wcslen(cur); i++)
{
strcat(_dest, IntToHex(*(cur + i), 4).c_str());
}
*_len = strlen(_dest) / 2;
*_code_len = *_len;
}
__finally
{
delete[] cur;
}
}
void __stdcall decode_unicode(char *_dest, char *_src)
{
unsigned short os = 0, len = 0;
wchar_t *src = new wchar_t[(strlen(_src) / 4) + 1];
wchar_t src_bit[5] = {'\0'};
try
{
for (size_t i = 0; i < strlen(_src); i = i + 4)
{
*src_bit = *(_src + i);
*(src_bit + 1) = *(_src + (i + 1));
*(src_bit + 2) = *(_src + (i + 2));
*(src_bit + 3) = *(_src + (i + 3));
*(src + os) = wcstol(src_bit, NULL, 16);
os++;
}
*(src + os) = '\0';
len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, src, -1, _dest, len, NULL, NULL);
}
__finally
{
delete[] src;
}
}
void __stdcall encode_bit7(char *_dest, char *_src
, unsigned short *_len, unsigned short *_code_len)
{
unsigned short n = 0, os = 0, cur = 0; //n:位数;os:目标下标位。cur:临时变量
*_len = strlen(_src); //字节个数
for(int i = 0; i < *_len; i++)
{
if (i < (*_len - 1))
cur = (((unsigned char)(*(_src + i))) >> n)
| ((((unsigned char)(*(_src + (i + 1)))) << (7 - n)) & 0XFF);
else
cur = (((unsigned char)(*(_src + i))) >> n) & 0X7F;
strcpy(_dest + os, IntToHex(cur, 2).c_str());
os += 2;
n = (n + 1) % 7;
if (n == 0) //第八个字节要跳过,8个字节压缩到7个字节中存储。
i++;
}
*_code_len = strlen(_dest) / 2; //编码长度。
}
void __stdcall decode_bit7(char *_dest, char *_src)
{
unsigned short n = 0, rud = 0, os = 0; //n:位数;rud:遗留字节值;os:指针下移位数。\
unsigned char *src = new unsigned char[(strlen(_src) / 2) + 1];
char src_bit[3] = {'\0'};
try
{
for (size_t i = 0; i < strlen(_src); i = i + 2)
{
*src_bit = *(_src + i);
*(src_bit + 1) = *(_src + (i + 1));
*(src + os) = strtol(src_bit, NULL, 16);
os++;
}
*(src + os) = '\0';
os = 0;
for (size_t i = 0; i < strlen(src); i++)
{
*(_dest + os) = (((*(src + i)) << n) | rud) & 0X7F;
rud = (*(src + i)) >> (7 - n);
n++;
os++;
if (n == 7)
{
*(_dest + os) = rud;
rud = 0;
n = 0;
os++;
}
}
}
__finally
{
delete[] src;
}
}
void __stdcall encode_bit8(char *_dest, char *_src
, unsigned short *_len, unsigned short *_code_len)
{
*_len = strlen(_src);
unsigned char cur = 0;
for (unsigned short i = 0; i < *_len; i++)
{
cur = *(_src + i);
strcat(_dest, IntToHex(cur, 2).c_str());
}
*_code_len = strlen(_dest) / 2; //编码长度。
}
void __stdcall decode_bit8(char *_dest, char *_src)
{
char src_bit[3] = {'\0'};
unsigned short os = 0;
for (size_t i = 0; i < strlen(_src); i = i + 2)
{
*src_bit = *(_src + i);
*(src_bit + 1) = *(_src + (i + 1));
*(_dest + os) = strtol(src_bit, NULL, 16);
os++;
}
}
//---------------------------------------------------------------------------
void __stdcall encode_phone(char *_dest, char *_src, unsigned char *_len)
{
char _tmp = 0;
if (get_phone_type(_src) == _wi) //说明是小灵通。
strcpy(_dest, "106");
else
strcpy(_dest, "86");
strcat(_dest, _src);
*_len = strlen(_dest);
if ( (*_len % 2) != 0 ) //如果位数为奇数位,则在最后加F补成偶数位。
strcat(_dest, "F");
for (unsigned int i = 0; i < strlen(_dest); i+=2)
{
_tmp = _dest[i];
_dest[i] = _dest[i + 1];
_dest[i + 1] = _tmp;
} //进奇偶位校验,奇偶位互换。
}
void __stdcall encode_head(char *_head, char *_phone, char *_code, unsigned short *_len)
{
//头文件格式如下:
//00 SMSC长度:此处省略SMSC。
//11:FO
//00:TP-MR
//00: 电话号码长度,这里先置为0,后面的代码会进行修改。
//91,81:地址类型,91是手机,81是小灵通。
//106,86:国际区号:86中国国际区号,指手机,106是中国人自己搞的小灵通。
//<手机号码编码> 接下来就是手机的编码号。
//00: PID
//08: 编码类型:08为Unicode编码,00为Bit 7编码,15为Bit 8编码。
//A7: 有效期。
char _tmp = 0;
if (get_phone_type(_phone) == _wi) //说明是小灵通。
strcpy(_head, "0011000081106");
else
strcpy(_head, "001100009186");
strcat(_head, _phone);
*_len = strlen(_head + 10);
*(_head + 6) = IntToHex(*_len, 2).c_str()[0];
*(_head + 7) = IntToHex(*_len, 2).c_str()[1];
if ( (*_len % 2) != 0 ) //如果位数为奇数位,则在最后加F补成偶数位。
strcat(_head + 10, "F");
for (unsigned int i = 0; i < strlen(_head + 10); i+=2)
{
_tmp = *(_head + (10 + i));
*(_head + (10 + i)) = *(_head + (10 + i + 1));
*(_head + (10 + i + 1)) = _tmp;
} //进奇偶位校验,奇偶位互换。
strcat(_head, "00"); //PID;
strcat(_head, _code); //编码类型。
strcat(_head, "01"); //有效期。
*_len = strlen(_head) / 2;
}
//---------------------------------------------------------------------------
AnsiString __stdcall SendEncode(char *_phone, char *_code, char *_message)
{
char head[50] = {'\0'};
char info[512] = {'\0'};
unsigned short head_len = 0, info_len = 0, code_len = 0;
//编码PDU头。
encode_head(head, _phone, _code, &head_len);
//编码PDU内容。
if (strcmp(_code, _ud.c_str()) == 0) //Unicode编码模式。
{
//这里可以处理相应的代码:
encode_unicode(info, _message, &info_len, &code_len);
}
else if (strcmp(_code, _b7.c_str()) == 0) //Bit 7编码模式。
{
encode_bit7(info, _message, &info_len, &code_len);
}
else //Bit 8编码模式。
{
encode_bit8(info, _message, &info_len, &code_len);
}
ShowMessage("AT+CMGS="
+ FormatFloat("000", (head_len + code_len)) + "\r"
+ head
+ IntToHex(info_len, 2)
+ info + char(26) + "\r\n");
//十进制编码。
return "AT+CMGS="
+ FormatFloat("000", (head_len + code_len)) //+ "\r"
+ head
+ IntToHex(info_len, 2)
+ info + char(26) + "\r\n";
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -