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

📄 comtraview.cpp

📁 sms短信模拟程序
💻 CPP
字号:
// comtraView.cpp : implementation of the CComtraView class
//

#include "stdafx.h"
#include "comtra.h"

#include "comtraDoc.h"
#include "comtraView.h"

#include "Setupdialog.h"
#include "Comm.h"
#include <assert.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CComtraView

IMPLEMENT_DYNCREATE(CComtraView, CEditView)

BEGIN_MESSAGE_MAP(CComtraView, CEditView)
	//{{AFX_MSG_MAP(CComtraView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////////////////////m_iLen//////////////////////////////////////////
// CComtraView construction/destruction

CComtraView::CComtraView()
{
	// TODO: add construction code here
	m_iLen = 0;
}

CComtraView::~CComtraView()
{
	
}

BOOL CComtraView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CEditView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CComtraView drawing

void CComtraView::OnDraw(CDC* pDC)
{
	CComtraDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CComtraView diagnostics

#ifdef _DEBUG
void CComtraView::AssertValid() const
{
	CEditView::AssertValid();
}

void CComtraView::Dump(CDumpContext& dc) const
{
	CEditView::Dump(dc);
}

CComtraDoc* CComtraView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CComtraDoc)));
	return (CComtraDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CComtraView message handlers

void CComtraView::OnInitialUpdate() 
{
	CEditView::OnInitialUpdate();

	initsysinfo();
	// TODO: Add your specialized code here and/or call the base class
	assert(this);
	if(m_SockServer != NULL)
	{
//		delete m_SockServer;
		m_SockServer = NULL;
	}
	m_SockServer = new SockServer();
	if(m_SockServer->Create(sysinfo.SockPort,SOCK_STREAM,FD_READ|FD_WRITE|FD_ACCEPT|FD_CLOSE)){
		m_SockServer->Listen();
		Message("SYS: Server listen........");
	}else{
		Message("SYS: Socket port can't open.");
	}

	CString strPort;
	strPort.Format("COM%d",sysinfo.ComPort);
	if(!::OpenComm(strPort,sysinfo.Combaud))
	{
		Message("SYS:" + strPort + " Open Failure.");
	}else{
		Message("SYS:" + strPort + " is Open success.");
	}

}

void CComtraView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CView::CalcWindowRect(lpClientRect, nAdjustType);
}

void CComtraView::Message(LPCTSTR lpszMessage)
{

	CString strTemp = lpszMessage;
	strTemp += _T("\r\n");

	int len = GetWindowTextLength();
	if(GetEditCtrl().GetLineCount() > 100)
	{
		GetEditCtrl().SetSel(0,len);
		GetEditCtrl().Clear();
		GetEditCtrl().SetSel(0,0);
	}else{
		GetEditCtrl().SetSel(len,len);
	}
	GetEditCtrl().ReplaceSel(strTemp);

}

void CComtraView::initsysinfo()
{
	int iReturn;
	CString strReturn;

	CString strSection = "Service";
	iReturn = (AfxGetApp()->GetProfileInt(strSection,"SockPort",3000));
	sysinfo.SockPort = iReturn;

	iReturn = (AfxGetApp()->GetProfileInt(strSection,"ComPort",1));
	sysinfo.ComPort = iReturn;

	iReturn = (AfxGetApp()->GetProfileInt(strSection,"Combaud",9600));
	sysinfo.Combaud = iReturn;

	iReturn = (AfxGetApp()->GetProfileInt(strSection,"Databit",8));
	sysinfo.databits = iReturn;

	iReturn = (AfxGetApp()->GetProfileInt(strSection,"Stopsbits",1));
	sysinfo.stopsbits = iReturn;
	sysinfo.parity = 'N';

	CSetupdialog Setupdialog;
	Setupdialog.m_SockPort = sysinfo.SockPort;
	Setupdialog.m_ComPort = sysinfo.ComPort;
	Setupdialog.m_baud = sysinfo.Combaud;
	Setupdialog.m_databit = sysinfo.databits;
	Setupdialog.m_stopbit = sysinfo.stopsbits;

	if(Setupdialog.DoModal() == IDOK)
	{
		sysinfo.SockPort = Setupdialog.m_SockPort;
		sysinfo.ComPort = Setupdialog.m_ComPort;
		sysinfo.Combaud = Setupdialog.m_baud;
		sysinfo.databits = Setupdialog.m_databit;
		sysinfo.stopsbits = Setupdialog.m_stopbit;

		AfxGetApp()->WriteProfileInt(strSection, "SockPort", sysinfo.SockPort);
		AfxGetApp()->WriteProfileInt(strSection, "ComPort", sysinfo.ComPort);
		AfxGetApp()->WriteProfileInt(strSection, "Stopsbits", sysinfo.stopsbits);
		AfxGetApp()->WriteProfileInt(strSection, "Databit", sysinfo.databits);
		AfxGetApp()->WriteProfileInt(strSection, "Combaud", sysinfo.Combaud);
	}

}


DWORD CComtraView::OnSocketAccept(int nError)
{
	SOCKADDR *lpSockAddr;
	if(m_ConnSock != NULL)m_ConnSock.Close();
	m_SockServer->Accept(m_ConnSock,lpSockAddr,NULL);
	
	Message("SYS:Accept IP");
	return 0;
}

DWORD CComtraView::OnSocketClose(int nError)
{
	if(m_ConnSock != NULL)
	{
		m_ConnSock.Close();
		Message("SYS:网络连接断开。");
	}
	return 0;
}

DWORD CComtraView::OnSocketReceive(int nError)
{
	int nLen;
	char lpbuf[200];
	char Msg[250];
	
	
	
	nLen = m_ConnSock.Receive(lpbuf,200,0);
	if (nLen > 0 && nLen < 200){
		lpbuf[nLen] = '\0';
		strcpy(Msg,lpbuf);
		Message("SR:接受网络数据。");

		Message(Msg);
		ParseCallID(Msg);
	}
	return nLen;
}

CComtraView * CComtraView::GetView()
{
	CFrameWnd *pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
	CView *pView = pFrame->GetActiveView();
	if (!pView)
		return NULL;
	if (!pView->IsKindOf(RUNTIME_CLASS(CComtraView)))
		return NULL;
	return (CComtraView *)pView;
}

int CComtraView::SendCallInfo(char *CallID)
{

	//RING +CLIP "CallID",129 
	//return ATH
	//ATH OK

	CString CallerID;
	int iLen;
	iLen = strlen(CallID);


	CallerID.Format("+CLIP \"%s\",129\r\n",CallID);
	iLen =+12;
//	m_Comm.WriteToPort("RING\r\n",4);
	Sleep(10);
//	m_Comm.WriteToPort(CallerID.GetBuffer(iLen),iLen);

	Sleep(10);

	return 0;
}

void CComtraView::ParseCallID(char *string)
{
	//<becall:1222><callid:1112>
	CString strSmsc;
	CString strNumber;
	CString strContent;
	CString strBecall;
	CString strCallID;

	SM_PARAM SmParam;

	int iLen,j=0;
	iLen = strlen(string);
	for(int i = 0;i<iLen;i++)
	{
		if(isdigit(string[i]))
		{
			if(j == 0){
				strBecall += string[i];
			}else{
				strCallID += string[i];
			}
		}else if(string[i] == '>'){
			if(j == 0){
				j++;
			}else{

			}
		}

	}
	memset(&SmParam, 0, sizeof(SM_PARAM));

	// 去掉号码前的"+"
//	if(strSmsc[0] == '+')  strSmsc = strSmsc.Mid(1);
//	if(strNumber[0] == '+')  strNumber = strNumber.Mid(1);
	strSmsc = "13800755500";
	strNumber = strCallID;
	// 在号码前加"86"
	if(strSmsc.Left(2) != "86")  strSmsc = "86" + strSmsc;
	if(strNumber.Left(2) != "86")  strNumber = "86" + strNumber;

	strContent = "HJ*0" + strBecall;
	// 填充短消息结构
	strcpy(SmParam.SCA, strSmsc);
	strcpy(SmParam.TPA, strNumber);
	strcpy(SmParam.TP_UD, strContent);
	SmParam.TP_PID = 0x00;
//	SmParam.TP_DCS = GSM_UCS2;
	strcpy(SmParam.TP_SCTS ,"08121709434932"); 
	SmParam.TP_DCS = GSM_7BIT;
//	SmParam.TP_DCS = GSM_8BIT;

	gsmSendMessage(&SmParam);
}


int CComtraView::gsmSendMessage(SM_PARAM* pSrc)
{
	int nPduLength;		// PDU串长度
	unsigned char nSmscLength;	// SMSC串长度
	int nLength;		// 串口收到的数据长度
	char cmd[16];		// 命令串
	char pdu[512];		// PDU串
	char ans[512];		// 应答串

	nPduLength = gsmEncodePdu(pSrc, pdu) ;	// 根据PDU参数,编码PDU串
	strcat(pdu, "\r\n");		// 以回车换行结束

//	TRACE("%s", pdu);  //zhao
	gsmString2Bytes(pdu, &nSmscLength, 2);	// 取PDU串中的SMSC信息长度
	nSmscLength++;		// 加上长度字节本身

	// 命令中的长度,不包括SMSC信息长度,以数据字节计
	sprintf(cmd, "+CMT: ,%d\r\n", nPduLength/2 - nSmscLength );	// 生成命令

	int i;

	Message("呼叫开始。");
	nLength = strlen(cmd);
	i = WriteComm(cmd,nLength);
	
	if (i==0){
		sprintf(ans,"SEND ERROR:%s.",cmd);
		Message(ans);
	}else{
		Message(cmd);
	}
	Sleep(100);
	nLength = strlen(pdu);

	WriteComm(pdu,nLength);
	if (i==0){
		sprintf(ans,"SEND ERROR:%s.",pdu);
		Message(ans);
	}else{
		Message(pdu);
	}
	
//	TRACE("%s", cmd);  
//	TRACE("%s\n", pdu);
/*
	WriteComm(cmd, strlen(cmd));	// 先输出命令串

	nLength = ReadComm(ans, 128);	// 读应答数据

	// 根据能否找到"\r\n> "决定成功与否
	if(nLength == 4 && strncmp(ans, "\r\n> ", 4) == 0)
	{
		return WriteComm(pdu, strlen(pdu));		// 得到肯定回答,继续输出PDU串
	}
*/
	return 0;
}

int CComtraView::gsmEncodePdu(const SM_PARAM* pSrc, char* pDst)
{
	int nLength;			// 内部用的串长度
	int nDstLength;			// 目标PDU串长度
	unsigned char buf[256];	// 内部用的缓冲区

	// SMSC地址信息段
	nLength = strlen(pSrc->SCA);	// SMSC地址字符串的长度	
	buf[0] = (char)((nLength & 1) == 0 ? nLength : nLength + 1) / 2 + 1;	// SMSC地址信息长度
//	TRACE("%c",buf[0]);
	buf[1] = 0x91;		// 固定: 用国际格式号码
	nDstLength = gsmBytes2String(buf, pDst, 2);		// 转换2个字节到目标PDU串
//	TRACE("%s",pDst);
	nDstLength += gsmInvertNumbers(pSrc->SCA, &pDst[nDstLength], nLength);	// 转换SMSC号码到目标PDU串
//	TRACE("%s",pDst);

	// TPDU段基本参数、目标地址等
	nLength = strlen(pSrc->TPA);	// TP-DA地址字符串的长度
	buf[0] = 0x04;					// 是发送短信(TP-MTI=01),TP-VP用相对格式(TP-VPF=10)
//	buf[1] = 0;						// TP-MR=0
	buf[1] = (char)nLength;			// 目标地址数字个数(TP-DA地址字符串真实长度)
	buf[2] = 0x91;					// 固定: 用国际格式号码
	nDstLength += gsmBytes2String(buf, &pDst[nDstLength], 3);		// 转换4个字节到目标PDU串
	nDstLength += gsmInvertNumbers(pSrc->TPA, &pDst[nDstLength], nLength);	// 转换TP-DA到目标PDU串

	// TPDU段协议标识、编码方式、用户信息等
	nLength = strlen(pSrc->TP_UD);	// 用户信息字符串的长度
	buf[0] = pSrc->TP_PID;
	buf[1] = pSrc->TP_DCS;			// 用户信息编码方式(TP-DCS)

	nDstLength += gsmBytes2String(buf, &pDst[nDstLength], 2);
	nDstLength += gsmInvertNumbers(pSrc->TP_SCTS, &pDst[nDstLength], 14);

	if(pSrc->TP_DCS == GSM_7BIT)	
	{
		// 7-bit编码方式
		buf[0] = nLength;			// 编码前长度
		nLength = gsmEncode7bit(pSrc->TP_UD, &buf[1], nLength+1) + 1;	// 转换TP-DA到目标PDU串
	}
	else if(pSrc->TP_DCS == GSM_UCS2)
	{
		// UCS2编码方式

		buf[0] = gsmEncodeUcs2(pSrc->TP_UD, &buf[1], nLength);	// 转换TP-DA到目标PDU串		
		buf[0] = nLength;		// nLength等于该段数据长度
	}
	else
	{
		// 8-bit编码方式
		buf[3] = gsmEncode8bit(pSrc->TP_UD, &buf[4], nLength);	// 转换TP-DA到目标PDU串
		nLength = buf[3] + 4;		// nLength等于该段数据长度
	}
	nDstLength += gsmBytes2String(buf, &pDst[nDstLength], nLength );		// 转换该段数据到目标PDU串

	// 返回目标字符串长度
	return nDstLength;
}

// 7bit编码
// 输入: pSrc - 源字符串指针
//       nSrcLength - 源字符串长度
// 输出: pDst - 目标编码串指针
// 返回: 目标编码串长度
int CComtraView::gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
	int nSrc;		// 源字符串的计数值
	int nDst;		// 目标编码串的计数值
	int nChar;		// 当前正在处理的组内字符字节的序号,范围是0-7
	unsigned char nLeft;	// 上一字节残余的数据

	// 计数值初始化
	nSrc = 0;
	nDst = 0;

	// 将源串每8个字节分为一组,压缩成7个字节
	// 循环该处理过程,直至源串被处理完
	// 如果分组不到8字节,也能正确处理
	while (nSrc < nSrcLength)
	{
		// 取源字符串的计数值的最低3位
		nChar = nSrc & 7;

		// 处理源串的每个字节
		if(nChar == 0)
		{
			// 组内第一个字节,只是保存起来,待处理下一个字节时使用
			nLeft = *pSrc;
		}
		else
		{
			// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
			*pDst = (*pSrc << (8-nChar)) | nLeft;

			// 将该字节剩下的左边部分,作为残余数据保存起来
			nLeft = *pSrc >> nChar;

			// 修改目标串的指针和计数值
			pDst++;
			nDst++;
		}

		// 修改源串的指针和计数值
		pSrc++;
		nSrc++;
	}

	// 返回目标串长度
	return nDst;
}
int CComtraView::gsmEncode8bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
	// 简单复制
	memcpy(pDst, pSrc, nSrcLength);

	return nSrcLength;
}

int CComtraView::gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
	int nDstLength;		// UNICODE宽字符数目
	WCHAR wchar[128];	// UNICODE串缓冲区

	// 字符串-->UNICODE串
	nDstLength = MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);

	// 高低字节对调,输出
	for(int i=0; i<nDstLength; i++)
	{
		*pDst++ = wchar[i] >> 8;		// 先输出高位字节
		*pDst++ = wchar[i] & 0xff;		// 后输出低位字节
	}
//	TRACE("%s",wchar);
	// 返回目标编码串长度
	return nDstLength * 2;
}

int CComtraView::gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
	for (int i = 0; i < nSrcLength; i += 2)
	{
		// 输出高4位
		if ((*pSrc >= '0') && (*pSrc <= '9'))
		{
			*pDst = (*pSrc - '0') << 4;
		}
		else
		{
			*pDst = (*pSrc - 'A' + 10) << 4;
		}

		pSrc++;

		// 输出低4位
		if ((*pSrc>='0') && (*pSrc<='9'))
		{
			*pDst |= *pSrc - '0';
		}
		else
		{
			*pDst |= *pSrc - 'A' + 10;
		}

		pSrc++;
		TRACE("%s",pSrc);
		pDst++;
		TRACE("%s",pDst);
	}

	// 返回目标数据长度
	return (nSrcLength / 2);
}

int CComtraView::gsmInvertNumbers(const char* pSrc, char* pDst, int nSrcLength)
{
	int nDstLength;		// 目标字符串长度
	char ch;			// 用于保存一个字符

	// 复制串长度
	nDstLength = nSrcLength;

	// 两两颠倒
	for(int i=0; i<nSrcLength;i+=2)
	{
		ch = *pSrc++;		// 保存先出现的字符
		*pDst++ = *pSrc++;	// 复制后出现的字符
		*pDst++ = ch;		// 复制先出现的字符
	}

	// 源串长度是奇数吗?
	if(nSrcLength & 1)
	{
		*(pDst-2) = 'F';	// 补'F'
		nDstLength++;		// 目标串长度加1
	}

	// 输出字符串加个结束符
	*pDst = '\0';

	// 返回目标字符串长度
	return nDstLength;
}
int CComtraView::gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
	const char tab[]="0123456789ABCDEF";	// 0x0-0xf的字符查找表

	for (int i = 0; i < nSrcLength; i++)
	{
		*pDst++ = tab[*pSrc >> 4];		// 输出高4位
		*pDst++ = tab[*pSrc & 0x0f];	// 输出低4位
		pSrc++;
	}

	// 输出字符串加个结束符
	*pDst = '\0';   

	// 返回目标字符串长度
	return (nSrcLength * 2);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -