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

📄 mobliexdoc.cpp

📁 通过手机数据线连接手机
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// MoblieXDoc.cpp : implementation of the CMoblieXDoc class
//

#include "stdafx.h"
#include "MoblieX.h"

#include "MoblieXDoc.h"

#include "sms.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMoblieXDoc

IMPLEMENT_DYNCREATE(CMoblieXDoc, CDocument)

BEGIN_MESSAGE_MAP(CMoblieXDoc, CDocument)
	//{{AFX_MSG_MAP(CMoblieXDoc)
	ON_COMMAND(ID_TEST, OnTest)
	ON_COMMAND(ID_COMM_INIT, OnCommInit)
	ON_COMMAND(ID_COMM_CLOSE, OnCommClose)
	ON_UPDATE_COMMAND_UI(ID_COMM_INIT, OnUpdateCommInit)
	ON_UPDATE_COMMAND_UI(ID_COMM_CLOSE, OnUpdateCommClose)
	ON_COMMAND(ID_COMM_PORT_SETUP, OnCommPortSetup)
	ON_COMMAND(ID_LOG_READ_TO_WND, OnLogReadToWnd)
	ON_UPDATE_COMMAND_UI(ID_LOG_READ_TO_WND, OnUpdateLogReadToWnd)
	ON_COMMAND(ID_LOG_WRITE_TO_WND, OnLogWriteToWnd)
	ON_UPDATE_COMMAND_UI(ID_LOG_WRITE_TO_WND, OnUpdateLogWriteToWnd)
	ON_COMMAND(ID_COMM_READ_OK, OnCommReadOk)
	ON_COMMAND(ID_LOG_RES_TO_WND, OnLogResToWnd)
	ON_UPDATE_COMMAND_UI(ID_LOG_RES_TO_WND, OnUpdateLogResToWnd)
	ON_UPDATE_COMMAND_UI(ID_COMM_PORT_SETUP, OnUpdateCommPortSetup)
	ON_COMMAND(ID_PB_PATH_SET, OnPbPathSet)
	ON_COMMAND(ID_SMS_SAVE_ALL, OnSmsSaveAll)
	ON_UPDATE_COMMAND_UI(ID_SMS_SAVE_ALL, OnUpdateSmsSaveAll)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMoblieXDoc construction/destruction

CMoblieXDoc::CMoblieXDoc()
{
	m_curWorkID = CW_TM;//终端方式

	m_hComm = INVALID_HANDLE_VALUE;
	m_pComThr = NULL;

	m_logRead2Wnd = FALSE;
	m_logWrite2Wnd = FALSE;
	m_logRes2Wnd = TRUE;

	GetPhoneBook( PBM_ME ).SetPBM( PBM_ME );
	GetPhoneBook( PBM_SM ).SetPBM( PBM_SM );

	//串口通讯超时设置
	memset(&m_commTimeout,0,sizeof(m_commTimeout));
	m_commTimeout.ReadIntervalTimeout = 100;
	m_commTimeout.ReadTotalTimeoutMultiplier = 0;
	m_commTimeout.ReadTotalTimeoutConstant = 300;//读超时, 0.3秒
	m_commTimeout.WriteTotalTimeoutConstant = 4000;//写超时, 4秒
	m_commTimeout.WriteTotalTimeoutMultiplier = 0;

	m_commNoDataReadCounter = 0;//连续未读到数据计数器
}

CMoblieXDoc::~CMoblieXDoc()
{
	if( m_pComThr )
	{
		m_pComThr->Quit();
		m_pComThr = NULL;
	}

	CloseCOMM();
}

BOOL CMoblieXDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	SetTitle( "手机小精灵" );

	//取得缺省的端口设置
	m_dlgCommPort.LoadDefault();
	//取电话本路径
	m_dlgPBPath.LoadDefault();

	//载入电话本
	m_phoneBookME.Load( m_dlgPBPath.m_me );
	m_phoneBookSM.Load( m_dlgPBPath.m_sm );
	UpdateDlgPBSData();
	//载入短信中心地址
	m_dlgSCASelect.m_pb.Load( m_dlgPBPath.m_sca );

	if( !m_pComThr )
	{//创建线程
		m_pComThr = (CComThread*)AfxBeginThread( RUNTIME_CLASS(CComThread), THREAD_PRIORITY_ABOVE_NORMAL );
		m_pComThr->m_pDoc = this;
	}

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMoblieXDoc serialization

void CMoblieXDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CMoblieXDoc diagnostics

#ifdef _DEBUG
void CMoblieXDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CMoblieXDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMoblieXDoc commands
void CMoblieXDoc::RemoveAllCommandArray()
{
	m_sendStrArray.RemoveAll();
	m_sendCWIDArray.RemoveAll();
	m_sendStrDesArray.RemoveAll();
}

DWORD CMoblieXDoc::SendCommandStr( const char * str, int cwID/*=CW_TM*/, const char * des /*=NULL*/ )
{
	if( !m_pComThr->IsRuning() )
	{
		m_hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
		m_pComThr->SetNotifyWnd( m_hMainWnd );
		m_pComThr->StartProcess();
	}

	m_sendStrArray.Add( str );
	m_sendCWIDArray.Add( cwID );
	m_sendStrDesArray.Add( des );

	return strlen( str );
}

BOOL CMoblieXDoc::IsAnsTimeout()
{
DWORD sto;
	
	if( !IsCurWorkWantEcho() || m_atState != ATS_WAITING )
	{
		return FALSE;
	}

	sto = (m_curWorkID == CW_SEND_SMS_BODY) ? 18000 : 4000;
	return (m_commNoDataReadCounter*m_commTimeout.ReadTotalTimeoutConstant > sto);
}

BOOL CMoblieXDoc::ProcessRecievedStr()
{
	if( m_commNoDataReadCounter > 0 )
	{//没有读到数据
		if( m_commNoDataReadCounter*m_commTimeout.ReadTotalTimeoutConstant > 360000 )
		{//已经360秒没有读到数据了
			if( m_pComThr )
			{//停止查询式数据读取过程
				m_pComThr->StopProcess();
			}
		}
		if( IsAnsTimeout() )
		{//回应超时
			m_atState = ATS_ER;
			if( IsLogRes2Wnd() )
			{
				AddLog( "手机没有回应" );
			}
		}

		return FALSE;
	}

	if( !m_curReadStr.SeparateAll( "\r\n", m_readStrArray ) )
	{
		return FALSE;
	}

	if( !m_curReadStr.IsEmpty() )
	{//最后一行未完成
		if( m_curWorkID == CW_SEND_SMS_HEAD && m_curReadStr.Find('>') == 0 )
		{
			m_atState = ATS_WANTMORE;
		}
		m_readStrArray.RemoveAt( m_readStrArray.GetUpperBound() );
	}
	else if( m_readStrArray.GetSize() > 0 )
	{//最后一行已完成
	CString & res = m_readStrArray[ m_readStrArray.GetUpperBound() ];
		if( res.Find("OK") == 0 )
		{
			m_atState = ATS_OK;
		}
		else if( res.Find("ERROR") == 0 )
		{
			m_atState = ATS_ER;
		}
		else
		{
			m_atState = ATS_WAITING;
		}
	}

	if( IsCurWorkWantProcessResult() )
	{
		m_waitingProcessArray.Append( m_readStrArray );
	}

	if( m_atState == ATS_OK || m_atState == ATS_ER )
	{
		ProcessResult();
	}

	return TRUE;
}

BOOL CMoblieXDoc::CrackSMS(const char *orgSMS)
{
	return TRUE;
}

BOOL CMoblieXDoc::InitCOMM()
{
CString sMsg;

	if( m_hComm != INVALID_HANDLE_VALUE )
	{//怎么回事, 已经打开了
		return TRUE;
	}

	//初始化串口
	m_hComm = CreateFile( 
		m_dlgCommPort.m_commPortName, // pointer to name of the file
		GENERIC_READ | GENERIC_WRITE, // access (read-write) mode 
		FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode 
		NULL, // pointer to security attributes
		OPEN_EXISTING, // how to create
		0, // file attributes
		NULL // handle to file with attributes to copy 
		);

	if( m_hComm == INVALID_HANDLE_VALUE )
	{
		return FALSE;
	}

	sMsg.Format( "COMM Init handle: %d", m_hComm );
	TRACE( sMsg + '\n' );
/*	if( IsLogRes2Wnd() )
	{
		AddLog( sMsg );
	}
*/
	if( !SetCommState( m_hComm, &(m_dlgCommPort.m_dcb) ) )
	{
		sMsg.Format( "COMM Set State ER: %d", GetLastError() );
		TRACE( sMsg + '\n'  );
		if( IsLogRes2Wnd() )
		{
			AddLog( sMsg );
		}
		return FALSE;
	}
 
	SetupComm( 
		m_hComm, // handle of communications device 
		2048, // size of input buffer 
		2048 // size of output buffer 
		);

	//清空缓冲
	PurgeComm( m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR );
	//超时设置
	SetCommTimeouts( m_hComm, &m_commTimeout );

	return TRUE;
}

BOOL CMoblieXDoc::CloseCOMM()
{
	if( m_hComm == INVALID_HANDLE_VALUE )
	{
		return TRUE;
	}

	if( m_pComThr )
	{
		m_pComThr->StopProcess();
	}

	//清空缓冲
	PurgeComm( m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR );

	CloseHandle( m_hComm );
	m_hComm = INVALID_HANDLE_VALUE;
	return TRUE;
}


void CMoblieXDoc::OnCommInit() 
{
	if( !InitCOMM() )
	{
		AfxMessageBox( "无法初始化串口, 请检查串口设置是否正确。" );
		return;
	}
	InitMobile();
}

void CMoblieXDoc::OnCommClose() 
{
	RemoveAllCommandArray();//清空待发送队列
	CloseCOMM();//关闭通讯口
}

void CMoblieXDoc::OnUpdateCommInit(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( !IsCommPortOpen() );
}

void CMoblieXDoc::OnUpdateCommClose(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( IsCommPortOpen() );
}

void CMoblieXDoc::OnCommPortSetup() 
{
	m_dlgCommPort.DoModal();
}

void CMoblieXDoc::OnUpdateCommPortSetup(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( !IsCommPortOpen() );
}

BOOL CMoblieXDoc::InitMobile()
{//初始化手机并测试指令是否可用
	SendCommandStr( "AT\r", CW_TEST_COMMAND );//不回显命令
	SendCommandStr( "AT\r", CW_TEST_COMMAND );//不回显命令
	SendCommandStr( "ATE0\r", CW_TEST_COMMAND );//不回显命令
	SendCommandStr( "AT+CMGS=?\r", CW_CMGS_QUERY );//是否可发短信
	SendCommandStr( "AT+CMGF=0\r", CW_TEST_COMMAND );//设为PDU格式
	SendCommandStr( "AT+CSCS=\"UCS2\"\r", CW_TEST_COMMAND );//设置编码方式

	SendCommandStr( "AT+CPBS=?\r", CW_CPBS_QUERY );//查询电话本情况一定要放在最后一行

	return TRUE;
}

BOOL CMoblieXDoc::IsCurWorkWantProcessResult()
{
BOOL re;
	switch( m_curWorkID )
	{
	case CW_CMGS_QUERY:

	case CW_GET_SMS:
	case CW_SEND_SMS_HEAD:
	case CW_SEND_SMS_BODY:
	case CW_SEND_STRNOWAIT:

	case CW_CPBS_QUERY:
	case CW_CPBS_SET:
	case CW_CPBR_QUERY:
	case CW_CPBR_GET:
	case CW_CPBW_SET:
	case CW_CPBW_QUERY:

		re = TRUE;
		break;

	case CW_TEST_COMMAND:
	case CW_DEL_SMS:
	case CW_TM:
	default:
		re = FALSE;
	}
	return re;
}

BOOL CMoblieXDoc::IsCurWorkWantEcho()
{
BOOL re;
	switch( m_curWorkID )
	{
	case CW_TEST_COMMAND:
	case CW_CMGS_QUERY:

	case CW_GET_SMS:
	case CW_DEL_SMS:
	case CW_SEND_SMS_HEAD:
	case CW_SEND_SMS_BODY:

	case CW_CPBS_QUERY:
	case CW_CPBS_SET:
	case CW_CPBR_QUERY:
	case CW_CPBR_GET:
	case CW_CPBW_SET:
	case CW_CPBW_QUERY:
		
		re = TRUE;
		break;
	case CW_TM:
	case CW_SEND_STRNOWAIT:
	default:
		re = FALSE;
	}
	return re;
}

BOOL CMoblieXDoc::MakeCurSendStr()
{
	if( m_sendStrArray.GetSize() <= 0 )
	{//没有字串要发送
		return FALSE;
	}

	if( m_atState == ATS_WAITING
	 && IsCurWorkWantEcho() )
	{//上次命令没有结果, 并且那个命令需要等结果
		return FALSE;
	}

	if( m_sendStrArray[0].GetLength() <= 0 )
	{//空字串, 忽略
		m_sendStrArray.RemoveAt( 0 );
		m_sendCWIDArray.RemoveAt( 0 );
		m_sendStrDesArray.RemoveAt( 0 );
		return FALSE;
	}

	if( !(m_sendStrDesArray[0].IsEmpty()) && IsLogRes2Wnd() )
	{
		AddLog( m_sendStrDesArray[0] );
	}

	m_curSendStr = m_sendStrArray[0];
	m_curWorkID = m_sendCWIDArray[0];
	m_sendStrArray.RemoveAt( 0 );
	m_sendCWIDArray.RemoveAt( 0 );
	m_sendStrDesArray.RemoveAt( 0 );

	return TRUE;
}

//注意: 本函数在子线程中运行
BOOL CMoblieXDoc::CommSendCurStr()
{
DWORD nBytes = m_curSendStr.GetLength();
DWORD nSendBytes;

	if( nBytes <= 0 )
	{//没有数据要发送
		return FALSE;
	}
	if( !WriteFile( m_hComm, m_curSendStr, nBytes, &nSendBytes, NULL ) )
	{//输出数据不成功
	CString sMsg;
		sMsg.Format( "通讯错误(输出): %d", GetLastError() );
		TRACE( sMsg + '\n' );
		if( IsLogWrite2Wnd() )
		{
			AddLog( sMsg );
		}
	}
	else if( nBytes != nSendBytes )
	{
		TRACE( "通讯错误(输出丢失)\n" );
		if( IsLogRes2Wnd() )
		{
			AddLog( "通讯错误(输出丢失)" );
		}
	}
	else
	{
		m_commNoDataReadCounter = 0;//连续未读到数据计数器清零
		m_atState = ATS_WAITING;//重设AT命令结果状态

		if( IsLogWrite2Wnd() )
		{
			AddLog( "CM>>" + m_curSendStr );
		}
	}
	return TRUE;
}

BOOL CMoblieXDoc::CommReadStr()
{
DWORD nBytes;

	if(!ReadFile(m_hComm, m_commBuf, COMM_REC_BUF_SIZE, &nBytes, NULL))
	{
		TRACE( "通讯错误(输入): %d\n", GetLastError() );
		return FALSE;
	}
	else
	{
		if(nBytes)
		{//已读到数据
			m_commBuf[nBytes] = 0;
			m_curReadStr += m_commBuf;
			m_commNoDataReadCounter = 0;//连续未读到数据计数器清零
		}
		else
		{//没有读到数据
			m_commNoDataReadCounter++;
		}
		return TRUE;
	}
}

BOOL CMoblieXDoc::ProcessResult()
{
BOOL re;

	switch( m_curWorkID )
	{
	case CW_CMGS_QUERY:
		re = ProcessResCMGSQuery();	break;
	case CW_GET_SMS:
		re = ProcessResGetSMS();	break;
	case CW_ADD_SMS:

⌨️ 快捷键说明

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