// SMS.cpp: implementation of the CSMS class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "SerialPort.h"
#include "SMS.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSMS::CSMS(CSerialPort* port)
{
HANDLE hThread;
DWORD dwThreadID;
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);
hThread = CreateThread(NULL, 0, MonitorThread, this, 0, &dwThreadID);
CloseHandle(hThread);
Sleep(500);
}
CSMS::~CSMS()
{
CloseHandle(m_hStopMonitor);
CloseHandle(m_hReMonitor);
CloseHandle(m_hStoppedEvent);
CloseHandle(m_hRestartEvent);
m_bMonitor = false;
}
//use 'F'
int CSMS::encode_address(char* telephone_number, char* address_value)
{
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';
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)
{
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)
{
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;
}
BYTE CSMS::hex_str2int(char a1, char a2)
{
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)
{
char command[256], resp[512];
int ret, command_len;
if(strncmp(szSMSC, "+8613", 5) == 0 || strncmp(szSMSC, "008613", 6) == 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);
Sleep(10);
ret = m_pComm->WriteBytes((PBYTE) command, command_len);
if(ret != command_len)
{
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return -1;
}
ret = m_pComm->ReadLine((PBYTE) resp, 512);
while(ret > 0 && strncmp((char*) resp, (char*) command, command_len) != 0)
ret = m_pComm->ReadLine((PBYTE) resp, 1024); // 命令回显
if(ret <= 0)
{
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return -1;
}
ret = m_pComm->ReadLine((PBYTE) resp, 512); //\r\n
if(strcmp(resp, "ERROR\r\n") == 0)
{
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return -1;
}
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return 1;
}
int CSMS::send(char* szDestTel, char* szMsg)
{
char pdu[256], temp[32], command[256], resp[256];
int i = 0, j, length, ret, command_len;
WCHAR *pWidechar;
sprintf(pdu + i, "00");
i += 2;
sprintf(pdu + i, "11"); //first octet
i += 2;
sprintf(pdu + i, "00"); //first octet
i += 2;
//destination address
length = strlen(szDestTel);
if(strncmp(szDestTel, "13", 2) == 0)
{
encode_address(szDestTel, temp);
sprintf(pdu + i, "%02X9168%s", length + 2, temp);
}
else
{
encode_address(szDestTel, temp);
sprintf(pdu + i, "%02X00%s", length, temp);
}
i = strlen(pdu);
sprintf(pdu + i, "00"); //pid
i += 2;
//encoding user data
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);
i = strlen(pdu);
SetEvent(m_hStopMonitor);
WaitForSingleObject(m_hStoppedEvent, INFINITE);
Sleep(10);
//send pdu to comm, i is the length of pdu.
sprintf(command, "AT+CMGF=0\n", 10);
command_len = strlen(command);
ret = m_pComm->WriteBytes((PBYTE) command, command_len);
ret = m_pComm->ReadLine((PBYTE) resp, 256);
while(ret > 0 && strncmp((char*) resp, (char*) command, command_len) != 0)
ret = m_pComm->ReadLine((PBYTE) resp, 1024); // 命令回显
ret = m_pComm->ReadLine((PBYTE) resp, 256);
if(strncmp(resp, "ERROR\r\n", strlen("ERROR\r\n")) == 0)
{
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return -1;
}
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);
while(ret > 0 && strncmp((char*) resp, (char*) command, command_len) != 0)
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
TRACE1("%s\n", resp);
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return 1;
}
//0: un read. 1: read, 2: un sent, 3: sent, 4: all
int CSMS::read_by_type(int type, char** szTel, char** szTime, char** szMessage, int* location)
{
BYTE command[256], resp[1024];
int command_len, ret, i;
SetEvent(m_hStopMonitor);
WaitForSingleObject(m_hStoppedEvent, INFINITE);
//1. get
sprintf((char*) command, "at+cmgl=%d\n", type);
command_len = strlen((char*) command);
ret = m_pComm->WriteBytes(command, command_len);
if(ret != command_len)
{
TRACE1("error, %d\n", GetLastError());
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return -1;
}
Sleep(25);
ret = m_pComm->ReadLine((PBYTE) resp, 1024); // 命令回显
while(ret > 0 && strncmp((char*) resp, (char*) command, command_len) != 0 &&
strncmp((char*) resp, (char*) "+CMGL: ", strlen("+CMGL: ")) != 0)
ret = m_pComm->ReadLine((PBYTE) resp, 1024); // 命令回显
if(ret <= 0)
{
//ResetEvent(m_hRestartEvent);
SetEvent(m_hReMonitor);
WaitForSingleObject(m_hRestartEvent, INFINITE);
return -1;
}
for(i = 0; ; i++)
{
Sleep(1