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

📄 ysatmodem.cpp

📁 VisualC++通信编程工程实例精解 Chapter 2 Example 1 MSCOMM控件编程实例 Example 2 基于Windows API的虚拟终端实现 Example 3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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("设置自动应答模式失败"));
		//SetLastError(_TEXT("Set autoreply mode fail"));
		return FALSE;
	}
#endif

	//clear comm buffer
	if(!Purge(PURGE_ALL))
	{
		return FALSE;
	}

	TRACE("Com%d 初始化Modem成功 \n",m_nPort);
	//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("发送测试信号,但是未收到返回值"));
		//SetLastError(_TEXT("send +++ but cann't recept OK"));xa
		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("发送测试信号,但是未收到返回值"));
		//SetLastError(_TEXT("send ATH0 but cann't recept OK"));
		TRACE("2  %s\n",buffer);
		return HangUp2();
	}

	TRACE("成功挂断!!!\n");
	//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("未知状态!");
	}
}
//如果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 + -