?? ysatmodem.cpp
字號:
TCHAR temp[10];
lstrcpy(buffer,"ATS0=");
sprintf(temp,"%d",iRingCount);
lstrcat(buffer,temp);
//send 設置自動應答
SendAT(buffer);
ReadComm((PBYTE)buffer,6,&length,WAITTIME);
buffer[length]='\0';
i=CheckString(buffer);
if(i!=CODE_OK)
{
SetLastError(_TEXT("Set autoreply mode fail"));
return FALSE;
}
#endif
//clear comm buffer
if(!Purge(PURGE_ALL))
{
return FALSE;
}
TRACE("Com%d InitModem Success \n",m_nPort);
ChangeMode(MODE_COMMAND);
if(!SetEvent(EV_DSR|EV_RING|EV_RLSD))//設備就續狀態改變性號,現在已經就續,如果收到這個信號表示modem出問題了
{
SetLastError(_TEXT("Set comm event error"));
return FALSE;
}
AfxBeginThread(DetectModemThread,this);
ResetError();
m_bInit=TRUE;
return TRUE;
}
/*************************2001.10.30 ycat *********************************************
BOOL CYsATModem::SendAT(LPCSTR strCmd,BOOL AddReturn)
PURPOSE: 發送AT命令
PARAMETERS:
strCmd:要發送的AT命令
AddReturn:指明是否要在AT命令后面加上回車
RETURN VALUE:
如果操作成功,返回TRUE,如果失敗返回FALSE
COMMENTS:
1)大多數AT命令要加上回車符,才能運行,但+++卻不同,不要加回車
所以不支持+++命令
**********************************************************************/
BOOL CYsATModem::SendAT(LPCSTR strCmd,BOOL AddReturn)
{
//在傳送data模式
if(m_nMode==MODE_DATA)
{
SetLastError(_TEXT("Send AT Command error"));
return FALSE;
}
TCHAR buffer[50];
lstrcpy(buffer,strCmd);
lstrcat(buffer,"\r\n");//只有+++,可以省\n
TRACE("send AT command %s\n",buffer);
// DWORD dw;
// WaitEvent(&dw,0);
//如果strCmd中間含有值為0的字符,將會產生不良后果
if(WriteComm((PBYTE)buffer,strlen(buffer))==1)
return TRUE;
SetLastError(_TEXT("Send AT Command error"));
return FALSE;
}
/*
掛斷連接,進入MODE_COMMAND狀態
后面被取消的程序掛斷連接,有時不能很好運行
*/
BOOL CYsATModem::HangUp()
{
if(m_bTestMode)return TRUE;
if(m_nMode==MODE_UNINITIALIZE) return TRUE;
//如果正在連接,發送任意字符,則會中斷
if(m_nMode==MODE_CONNECTING)
{
SendAT(CMD_AT);
Sleep(500);
}
if(!Purge(PURGE_ALL)) return FALSE;
if(!Clear(PURGE_ALL)) return FALSE;
if(m_nMode==MODE_COMMAND) return TRUE;
if(m_nMode==MODE_UNMODEM) return TRUE;
TCHAR buffer[50];
DWORD length=0;
if(m_Thread)
{
if(WAIT_OBJECT_0!=WaitForSingleObject(m_Thread->m_hThread,10000))
{
TerminateThread(m_Thread->m_hThread,-11);
}
delete m_Thread;
m_Thread=NULL;
}
if(m_nMode!=MODE_DATA) return TRUE;
ResetEvent(m_hConnected);
ChangeMode(MODE_COMMAND);
if(!Purge(PURGE_ALL))
return FALSE;//comm error
Sleep(1000);
//change mode to MODE_COMMAND
//+++ 不用換行
TCHAR strSend[]=_TEXT("+++");
if(1!=WriteComm((PBYTE)strSend,3)) return FALSE;//comm error
TRACE(_TEXT("Send +++ \n"));
int i;
DWORD dwReaded;
if(-1==ReadComm((PBYTE)buffer,6,&dwReaded,WAITADDADDADDTIME))
return FALSE;//comm error
buffer[dwReaded]='\0';
i=CheckString(buffer);
if(i!=CODE_OK)
{
SetLastError(_TEXT("send +++ but cann't recept OK"));
TRACE("1 %s\n",buffer);
return HangUp2();
}
//hangup command
SendAT(CMD_ATH0);
if(-1==ReadComm((PBYTE)buffer,6,&dwReaded,WAITATHTIME)) return FALSE;
buffer[dwReaded]='\0';
i=CheckString(buffer);
//wait for OK
if(i!=CODE_OK)
{
SetLastError(_TEXT("send ATH0 but cann't recept OK"));
TRACE("2 %s\n",buffer);
return HangUp2();
}
TRACE("hang up OK!!!\n");
ChangeMode(MODE_COMMAND);
return TRUE;
}
/*************************2001.10.30 ycat *********************************************
FUNCTION: BOOL CYsATModem::Clear(DWORD dwType)
PURPOSE: 清除串口
PARAMETERS:
nType的值及說明,可組合起來用
nType=PURGE_TXABORT Terminates all outstanding
overlapped write operations and returns
immediately, even if the write operations
have not been completed.
nType=PURGE_RXABORT Terminates all outstanding
overlapped read operations and returns
immediately, even if the read operations
have not been completed.
nType=PURGE_TXCLEAR Clears the output buffer
(if the device driver has one).
nType=PURGE_RXCLEAR Clears the input buffer
(if the device driver has one).
RETURN VALUE:
如果操作成功,返回TRUE,如果失敗返回FALSE
COMMENTS:
1)讀緩沖區實際上是m_pQueue里的緩沖區
2)PURGE_RXABORT不起作用
**********************************************************************/
BOOL CYsATModem::Clear(DWORD dwType)
{
if(m_bTestMode)return Purge(dwType);
if(dwType&PURGE_RXCLEAR)
{
if(!m_pQueue->Clear())
{
SetLastError(_T("In clear() clear queue error"));
return FALSE;
}
}
if(dwType&PURGE_TXCLEAR)
if(!Purge(PURGE_TXCLEAR))
{
SetLastError(_T("In clear() clear tx buffer error"));
return FALSE;
}
if(dwType&PURGE_TXABORT)
if(!Purge(PURGE_TXABORT))
{
SetLastError(_T("In clear() clear tx abort error"));
return FALSE;
}
return TRUE;
}
/*************************2001.10.30 ycat *********************************************
FUNCTION: int CYsATModem::Write(LPCSTR lpstrWrite,DWORD dwCount)
PURPOSE: 寫數據
PARAMETERS:
lpstrWrite:要寫的字符串
dwCount: 字符串的長度
RETURN VALUE:
返回1為正常
返回-1為失敗
返回-4為斷線
COMMENTS:
**********************************************************************/
int CYsATModem::Write(LPCSTR lpstrWrite,DWORD dwCount)
{
if(!m_bTestMode)
{
if(m_nMode==MODE_COMMAND) return -4;
if(m_nMode!=MODE_DATA) return -1;
}
int nRet=CYsComm::WriteComm((PBYTE)lpstrWrite,dwCount);
if(nRet==1) return 1;
return -1;
}
/*************************2001.10.30 ycat *********************************************
FUNCTION: int CYsATModem::Read(LPTSTR lpstrRead,DWORD dwCount,
DWORD* dwHaveReaded,DWORD nTimeOut)
PURPOSE: 讀數據
PARAMETERS:
lpstrRead: 放讀出字符串的緩沖區
dwCount: 緩沖區的長度
dwHaveReaded: 實際讀到的字符數
nTimeOut: 超時
RETURN VALUE:
返回1為正常
返回-1為失敗
返回-2為超時
返回-4為斷線
COMMENTS:
**********************************************************************/
int CYsATModem::Read(LPTSTR lpstrRead,DWORD dwCount,
DWORD* dwHaveReaded,DWORD nTimeOut)
{
if(m_bTestMode)
{
return CYsComm::ReadComm((PBYTE)lpstrRead,dwCount,dwHaveReaded,nTimeOut);
}
if(m_nMode==MODE_COMMAND) return -4;
if(m_nMode!=MODE_DATA) return -1;
int nRet;
DWORD dwTimeAfter;
DWORD dwTimeUsed;
DWORD dwTimeBefore;
for(DWORD i=0;i<dwCount;i++)
{
dwTimeBefore=GetTickCount();
if(!m_pQueue->Get((PBYTE)(lpstrRead+i),nTimeOut))
{
//TRACE("Read2 Timeout %ld \n",nTimeOut);
nRet=-2;//超時
goto Exit;
}
dwTimeAfter=GetTickCount();
dwTimeUsed=dwTimeAfter-dwTimeBefore;
//斷線
if(m_nMode==MODE_COMMAND)
{
nRet=-3;
goto Exit;
}
if(dwTimeUsed>nTimeOut)
{
if(i<dwCount)
{
nRet=-2;//TimeOut
goto Exit;
}
else
{
nRet=1;
goto Exit;
}
}
//計算剩下的時間
nTimeOut-=dwTimeUsed;
}
nRet=1;
Exit:
*dwHaveReaded=i;
return nRet;
}
/*************************2001.10.30 ycat *********************************************
FUNCTION: int CYsATModem::CheckString(LPCTSTR strIn,BOOL bSendMessage)
PURPOSE: 查找strIn中是否含有AT命令返回的字符串
PARAMETERS:
strIn:要查找的字符串
bSendMessage:指明是否要發送消息給窗口
RETURN VALUE:
返回AT命令返回字符串的序號,(CODE_CANNTFIND)-1表示沒找到
COMMENTS: 不支持中間含有'\0'的字符串,要改進
**********************************************************************/
int CYsATModem::CheckString(LPCTSTR strIn,BOOL bSendMessage)
{
CString strTemp;
strTemp.Format("%s",strIn);
for(int i=0;i<ECHO_COUNT;i++)
{
if(-1!=strTemp.Find(pstrCmdString[i]))
{
if(!bSendMessage&&i==1) return i;
return i;
}
}
return -1;
}
/*
#define MODE_UNINITIALIZE 1//未初始化狀態
#define MODE_UNMODEM 5
#define MODE_COMMAND 10
#define MODE_DIALING 15
#define MODE_WAITRING 20
#define MODE_CONNECTING 25
#define MODE_DATA 30*/
//返回當前狀態
int CYsATModem::GetState()
{
if(m_bTestMode)return MODE_DATA;
return m_nMode;
}
//返回寫緩沖區內有多少個字符
DWORD CYsATModem::GetReadBufferCount()
{
if(m_bTestMode)
{
DWORD dwLength;
CYsComm::GetBufferCount(TYPE_WRITE,&dwLength);
return dwLength;
}
return m_pQueue->GetCount();
}
//return state describe string
CString CYsATModem::GetStateDesc()
{
if(m_bTestMode) return "測試狀態";
switch(m_nMode)
{
case MODE_UNINITIALIZE:
return _TEXT("串口有問題");
case MODE_UNMODEM:
return _TEXT("Modem有問題");
case MODE_COMMAND:
return _TEXT("可以撥號");
case MODE_CONNECTING:
return _TEXT("正在建立連接");
case MODE_DATA:
return _TEXT("遠程Modem連接");//(如不成功,返回2狀態)
default:
return _TEXT("Unknow state!");
}
}
//如果HangUp()不成功,只好調用HangUp2()了
BOOL CYsATModem::HangUp2()
{
if(m_bTestMode)return TRUE;
TRACE("\n\n In Hangup 2\n\n");
ChangeMode(MODE_UNINITIALIZE);
Sleep(1000);
return InitModem(m_nPort,m_iBaud,m_nRingCount,m_hWnd);
}
void CYsATModem::ChangeMode(int newMode)
{
if(m_nMode!=newMode)
{
if(m_hWnd)
PostMessage(m_hWnd,WM_MODEM_CHANGE,newMode,m_nPort);
m_nMode=newMode;
TRACE("Mode Change =%d \n",m_nMode);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -