?? mobliexdoc.cpp
字號(hào):
// 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 );
//串口通訊超時(shí)設(shè)置
memset(&m_commTimeout,0,sizeof(m_commTimeout));
m_commTimeout.ReadIntervalTimeout = 100;
m_commTimeout.ReadTotalTimeoutMultiplier = 0;
m_commTimeout.ReadTotalTimeoutConstant = 300;//讀超時(shí), 0.3秒
m_commTimeout.WriteTotalTimeoutConstant = 4000;//寫(xiě)超時(shí), 4秒
m_commTimeout.WriteTotalTimeoutMultiplier = 0;
m_commNoDataReadCounter = 0;//連續(xù)未讀到數(shù)據(jù)計(jì)數(shù)器
}
CMoblieXDoc::~CMoblieXDoc()
{
if( m_pComThr )
{
m_pComThr->Quit();
m_pComThr = NULL;
}
CloseCOMM();
}
BOOL CMoblieXDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
SetTitle( "手機(jī)小精靈" );
//取得缺省的端口設(shè)置
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 )
{//創(chuàng)建線程
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 )
{//沒(méi)有讀到數(shù)據(jù)
if( m_commNoDataReadCounter*m_commTimeout.ReadTotalTimeoutConstant > 360000 )
{//已經(jīng)360秒沒(méi)有讀到數(shù)據(jù)了
if( m_pComThr )
{//停止查詢式數(shù)據(jù)讀取過(guò)程
m_pComThr->StopProcess();
}
}
if( IsAnsTimeout() )
{//回應(yīng)超時(shí)
m_atState = ATS_ER;
if( IsLogRes2Wnd() )
{
AddLog( "手機(jī)沒(méi)有回應(yīng)" );
}
}
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 )
{//怎么回事, 已經(jīng)打開(kāi)了
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 );
//超時(shí)設(shè)置
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( "無(wú)法初始化串口, 請(qǐng)檢查串口設(shè)置是否正確。" );
return;
}
InitMobile();
}
void CMoblieXDoc::OnCommClose()
{
RemoveAllCommandArray();//清空待發(fā)送隊(duì)列
CloseCOMM();//關(guān)閉通訊口
}
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()
{//初始化手機(jī)并測(cè)試指令是否可用
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 );//是否可發(fā)短信
SendCommandStr( "AT+CMGF=0\r", CW_TEST_COMMAND );//設(shè)為PDU格式
SendCommandStr( "AT+CSCS=\"UCS2\"\r", CW_TEST_COMMAND );//設(shè)置編碼方式
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 )
{//沒(méi)有字串要發(fā)送
return FALSE;
}
if( m_atState == ATS_WAITING
&& IsCurWorkWantEcho() )
{//上次命令沒(méi)有結(jié)果, 并且那個(gè)命令需要等結(jié)果
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;
}
//注意: 本函數(shù)在子線程中運(yùn)行
BOOL CMoblieXDoc::CommSendCurStr()
{
DWORD nBytes = m_curSendStr.GetLength();
DWORD nSendBytes;
if( nBytes <= 0 )
{//沒(méi)有數(shù)據(jù)要發(fā)送
return FALSE;
}
if( !WriteFile( m_hComm, m_curSendStr, nBytes, &nSendBytes, NULL ) )
{//輸出數(shù)據(jù)不成功
CString sMsg;
sMsg.Format( "通訊錯(cuò)誤(輸出): %d", GetLastError() );
TRACE( sMsg + '\n' );
if( IsLogWrite2Wnd() )
{
AddLog( sMsg );
}
}
else if( nBytes != nSendBytes )
{
TRACE( "通訊錯(cuò)誤(輸出丟失)\n" );
if( IsLogRes2Wnd() )
{
AddLog( "通訊錯(cuò)誤(輸出丟失)" );
}
}
else
{
m_commNoDataReadCounter = 0;//連續(xù)未讀到數(shù)據(jù)計(jì)數(shù)器清零
m_atState = ATS_WAITING;//重設(shè)AT命令結(jié)果狀態(tài)
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( "通訊錯(cuò)誤(輸入): %d\n", GetLastError() );
return FALSE;
}
else
{
if(nBytes)
{//已讀到數(shù)據(jù)
m_commBuf[nBytes] = 0;
m_curReadStr += m_commBuf;
m_commNoDataReadCounter = 0;//連續(xù)未讀到數(shù)據(jù)計(jì)數(shù)器清零
}
else
{//沒(méi)有讀到數(shù)據(jù)
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:
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -