📄 sms.cpp
字号:
// SMS.cpp: implementation of the CSMS class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SerialPort.h"
#include "SMS.h"
CSMS::CSMS(CSerialPort* port)
{
m_pComm = port;
m_bMonitor = true;
// 用于暂停监视
m_hStopMonitor = CreateEvent(NULL, false, false, NULL);
// 用于恢复监视
m_hReMonitor = CreateEvent(NULL, false, false, NULL);
// 报告监视已停止
m_hStoppedEvent = CreateEvent(NULL, false, false, NULL);
// 报告监视已恢复
m_hRestartEvent = CreateEvent(NULL, false, false, NULL);
}
CSMS::~CSMS()
{
CloseHandle(m_hStopMonitor);
CloseHandle(m_hReMonitor);
CloseHandle(m_hStoppedEvent);
CloseHandle(m_hRestartEvent);
m_bMonitor = false;
}
int CSMS::encode_address(char* address_value, char* telephone_number)
/*
telephone_number -> address_value
8613051267975 -> 683150217679F5
*/
{
int i = 0, j = 0, len;
len = strlen(telephone_number);
for(i = 0; i < len; i += 2, j += 2)
{
if(i + 1 >= len)
address_value[j] = 'F'; //use 'F'
else
address_value[j] = telephone_number[i + 1];
address_value[j + 1] = telephone_number[i];
}
address_value[j] = 0;
return j;
}
int CSMS::decode_address(char* telephone_number, char* address_value)
/*
address_value -> telephone_number
683150217679F5 -> 8613051267975
*/
{
int i, j, len;
char temp[32];
len = strlen((char*) address_value);
for(i = 0, j = 0; i < len; i += 2, j += 2)
{
telephone_number[j] = address_value[i + 1];
if(address_value[i] != 'F' && address_value[i] != 'f')
telephone_number[j + 1] = address_value[i];
else
{
telephone_number[j + 1] = 0;
j += 1;
if(strncmp(telephone_number, "86", 2) == 0)
{
strcpy(temp, telephone_number + 2);
j -= 2;
strcpy(telephone_number, temp);
}
break;
}
}
return j;
}
int CSMS::decode_timestamp(char* time, char* time_stamp)
/*
time_stamp -> time
99309251619580 -> 99-03-29-15-16-59
time_stamp最后的80表示时区。
*/
{
int i, j, len;
len = strlen((char*) time_stamp);
for(i = 0, j = 0; i < len - 2; i += 2, j += 3)
{
time[j] = time_stamp[i + 1];
time[j + 1] = time_stamp[i];
time[j + 2] = '-';
}
time[j - 1] = 0;
return j;
}
int CSMS::decode_rpdu(char* pdu, char* szTel, char* szTime, char* szMessage)
{
char smsc_address[32], smsc_tel[32], sender_address[32], time_stamp[16];
int len, i, j, message_type;
WCHAR t1, t2, wcharName[32];
i = 0;
//1. get smsc
len = hex_str2int(pdu[i], pdu[i + 1]);
i += 2;
i += 2; //skip address_type
memcpy(smsc_address, pdu + i, (len - 1) * 2);
smsc_address[(len - 1) * 2] = 0;
decode_address(smsc_tel, smsc_address);
i += (len - 1) * 2;
//2. get message
i += 2; //skip "first octet"
len = hex_str2int(pdu[i], pdu[i + 1]);
i += 2;
i += 2; //skip address_type
len = len % 2 == 0 ? (len / 2) : (len / 2 + 1);
memcpy(sender_address, pdu + i, len * 2);
sender_address[len * 2] = 0;
decode_address(szTel, sender_address);
i += len * 2;
i += 2; //skip indicator
message_type = hex_str2int(pdu[i], pdu[i + 1]);
i += 2;
memcpy(time_stamp, pdu + i, 14);
time_stamp[14] = 0;
decode_timestamp(szTime, time_stamp);
i += 14; //skip time stamp
len = hex_str2int(pdu[i], pdu[i + 1]); //message length
i += 2;
switch(message_type)
{
case 0: // 7 bit
memcpy(szMessage, pdu + i, len);
break;
case 8: // 16 bit
len = len * 2;
for(j = 0; j < len; j += 4) //skip '80'
{
t1 = ((USHORT) hex_str2int(pdu[i + j], pdu[i + j + 1])) & 0x00FF;
t2 = ((USHORT) hex_str2int(pdu[i + j + 2], pdu[i + j + 3])) & 0x00FF;
wcharName[j / 4] = ((t1 << 8) | t2);
}
wcharName[len / 4] = 0;
WideCharToMultiByte(CP_ACP, 0, wcharName, -1, szMessage, 64, NULL, NULL);
break;
}
return 1;
}
BYTE CSMS::hex_str2int(char a1, char a2)
/*
a1a2: "43" -> 0x43
*/
{
int high, low;
//assert(a1 >= '0' && a1 <= '9' || a1 >= 'a' && a1 <= 'z' || a1 >= 'A' && a1 <= 'Z');
//assert(a2 >= '0' && a2 <= '9' || a2 >= 'a' && a2 <= 'z' || a2 >= 'A' && a2 <= 'Z');
if(a1 >= 'a' && a1 <= 'z')
a1 = a1 - 'a' + 'A';
if(a2 >= 'a' && a2 <= 'z')
a2 = a2 - 'a' + 'A';
if(a1 >= 'A' && a1 <= 'Z')
high = a1 - 'A' + 10;
else
high = a1 - '0';
if(a2 >= 'A' && a2 <= 'Z')
low = a2 - 'A' + 10;
else
low = a2 - '0';
return (BYTE) (high * 16 + low);
}
int CSMS::config(char* szSMSC)
{
int retval = -1;
char command[256], resp[512];
int ret, command_len;
if(strncmp(szSMSC, "+86", 3) == 0 || strncmp(szSMSC, "0086", 4) == 0)
sprintf(command, "at+csca=%s\n", szSMSC);
else
sprintf(command, "at+csca=+86%s\n", szSMSC);
command_len = strlen(command);
SetEvent(m_hStopMonitor);
WaitForSingleObject(m_hStoppedEvent, INFINITE);
ret = m_pComm->WriteBytes((PBYTE) command, command_len);
if(ret != command_len)
{
goto _out;
}
ret = m_pComm->ReadLine((PBYTE) resp, 512);
if(!ret || strncmp((char*) resp, (char*) command, command_len) != 0)
{
goto _out;
}
ret = m_pComm->ReadLine((PBYTE) resp, 512); //\r\n
if(strcmp(resp, "ERROR\r\n") == 0)
{
goto _out;
}
retval = 1;
_out:
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return retval;
}
bool CSMS::initialize()
{
char resp[1024], command[256];
int command_len, ret;
// set pdu mode: AT+CMGF=0\n
sprintf(command, "AT+CMGF=0\n");
command_len = strlen(command);
ret = m_pComm->WriteBytes((PBYTE) command, command_len);
ret = m_pComm->ReadLine((PBYTE) resp, 256);
if(!ret || strncmp((char*) resp, (char*) command, command_len) != 0)
{
MessageBox(NULL, "访问设备出错:AT+CMGF\n请重新启动程序。", "SMSpirit", MB_OK);
return 0;
}
ret = m_pComm->ReadLine((PBYTE) resp, 256);
if(strncmp(resp, "ERROR\r\n", strlen("ERROR\r\n")) == 0)
{
MessageBox(NULL, "访问设备出错:AT+CMGF\n请重新启动程序。", "SMSpirit", MB_OK);
return 0;
}
DWORD dwThreadId;
HANDLE hThread = CreateThread(NULL, 0, MonitorThread, this, 0, &dwThreadId);
CloseHandle(hThread);
return 1;
}
int CSMS::send(char* szDestTel, char* szMsg, int msg_type)
{
char pdu[256], temp[32], command[256], resp[256];
int i = 0, j, length, ret, command_len;
WCHAR *pWidechar;
sprintf(pdu + i, "00"); //根据设备说明文档,必须添加00,与PDU文档不符。
i += 2;
sprintf(pdu + i, "11"); //Type
i += 2;
sprintf(pdu + i, "00"); //MR
i += 2;
//destination address
if(strncmp(szDestTel, "86", 2) == 0)
szDestTel += 2;
else if(strncmp(szDestTel, "+86", 3) == 0)
szDestTel += 3;
else if(strncmp(szDestTel, "0086", 4) == 0)
szDestTel += 4;
length = strlen(szDestTel);
encode_address(temp, szDestTel);
sprintf(pdu + i, "%02X9168%s", length + 2, temp);
i = strlen(pdu);
sprintf(pdu + i, "00"); //pid
i += 2;
//encoding user data
switch(msg_type)
{
case MSG_CHINESE:
length = strlen(szMsg);
pWidechar = (WCHAR*) malloc(length * 2 + 4);
length = MultiByteToWideChar(CP_ACP, 0, szMsg, length, pWidechar, length);
length = length > 70 ? 70 : length;
sprintf(pdu + i, "0801%02X", length * 2);
i = strlen(pdu);
for(j = 0; j < length; j++)
{
sprintf(pdu + i, "%02X%02X", (BYTE) ((pWidechar[j] & 0xFF00) >> 8), (BYTE) (pWidechar[j] & 0x00FF));
i += 4;
}
free(pWidechar);
break;
case MSG_ENGLISH:
length = strlen(szMsg);
sprintf(pdu + i, "0001%02X%s", length, szMsg);
break;
}
i = strlen(pdu);
SetEvent(m_hStopMonitor);
WaitForSingleObject(m_hStoppedEvent, INFINITE);
sprintf(command, "AT+CMGS=%d\n", (i - 2) / 2);
command_len = strlen(command);
ret = m_pComm->WriteBytes((PBYTE) command, command_len);
ret = m_pComm->ReadLine((PBYTE) resp, 128);
if(!ret || strncmp((char*) resp, (char*) command, command_len) != 0)
return -1;//ret = m_pComm->ReadLine((PBYTE) resp, 1024); // 命令回显
//send pdu
ret = m_pComm->WriteBytes((PBYTE) pdu, i);
pdu[0] = 0x1a;
ret = m_pComm->WriteBytes((PBYTE) pdu, 1);
ret = m_pComm->ReadLine((PBYTE) resp, 128);
ret = m_pComm->ReadLine((PBYTE) resp, 128);
ret = m_pComm->ReadLine((PBYTE) resp, 128); //\r\n
ret = m_pComm->ReadLine((PBYTE) resp, 128); //OK\r\n
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return 1;
}
int CSMS::read_message(int nLocation, char* szTel, char* szTime, char* szMessage)
{
BYTE command[256], resp[1024];
int ret, command_len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -