⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms.cpp

📁 用VC6++对串口编程的实现,主要对SMS的实现,可以模拟发短信,收短信,不过要相应的MODON
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -