📄 comtraview.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 + -