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

📄 serial.cpp

📁 GSM Mobile收发短信
💻 CPP
📖 第 1 页 / 共 2 页
字号:
CSerial::EDataBits CSerial::GetDataBits (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetDataBits - Device is not opened\n");
		return EDataUnknown;
	}
	// Obtain the DCB structure for the device
	CDCB dcb;
	if (!::GetCommState(m_hFile,&dcb))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetDataBits - Unable to obtain DCB information\n");
		return EDataUnknown;
	}
	// Return the appropriate bytesize
	return EDataBits(dcb.ByteSize);

}

CSerial::EParity CSerial::GetParity (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetParity - Device is not opened\n");
		return EParUnknown;
	}
	// Obtain the DCB structure for the device
	CDCB dcb;
	if (!::GetCommState(m_hFile,&dcb))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetParity - Unable to obtain DCB information\n");
		return EParUnknown;
	}
	// Check if parity is used
	if (!dcb.fParity)
	{
		// No parity
		return EParNone;
	}
	// Return the appropriate parity setting
	return EParity(dcb.Parity);

}

CSerial::EStopBits CSerial::GetStopBits (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;

		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetStopBits - Device is not opened\n");
		return EStopUnknown;
	}
	// Obtain the DCB structure for the device
	CDCB dcb;
	if (!::GetCommState(m_hFile,&dcb))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetStopBits - Unable to obtain DCB information\n");
		return EStopUnknown;
	}
	// Return the appropriate stopbits
	return EStopBits(dcb.StopBits);

}

DWORD CSerial::GetEventMask (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetEventMask - Device is not opened\n");
		return 0;
	}
	// Obtain the COM mask
	DWORD dwMask = 0;
	if (!::GetCommMask(m_hFile, &dwMask))
	{
		// Set the internal error code
		m_lLastError = ::GetLastError();
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetEventMask - Unable to get the event mask\n");
		return 0;
	}
	// Return the event mask
	return dwMask;

}

BYTE CSerial::GetEventChar (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetEventChar - Device is not opened\n");
		return 0;
	}
	// Obtain the DCB structure for the device
	CDCB dcb;
	if (!::GetCommState(m_hFile,&dcb))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetEventChar - Unable to obtain DCB information\n");
		return 0;
	}
	// Set the new event character
	return BYTE(dcb.EvtChar);

}
//===========================================================================================
CSerial::EHandshake CSerial::GetHandshaking (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetHandshaking - Device is not opened\n");
		return EHandshakeUnknown;
	}
	// Obtain the DCB structure for the device
	CDCB dcb;
	if (!::GetCommState(m_hFile,&dcb))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetHandshaking - Unable to obtain DCB information\n");
		return EHandshakeUnknown;
	}
	// Check if hardware handshaking is being used
	if ((dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) && (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE))
		return EHandshakeHardware;
	// Check if software handshaking is being used
	if (dcb.fOutX && dcb.fInX)
		return EHandshakeSoftware;
	// No handshaking is being used
	return EHandshakeOff;

}
//=========================================================================================
LONG CSerial::Write (	const void* pData, 
						size_t iLen, 
						DWORD* pdwWritten,
						LPOVERLAPPED lpOverlapped, 
						DWORD dwTimeout
					)
{
	// Overlapped operation should specify the pdwWritten variable
	_ASSERTE(!lpOverlapped || pdwWritten);
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Use our own variable for read count
	DWORD dwWritten;
	if (pdwWritten == 0)
	{
		pdwWritten = &dwWritten;
	}
	// Reset the number of bytes written
	*pdwWritten = 0;
	// Check if the device is open
	if (m_hFile == NULL)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::Write - Device is not opened\n");
		return m_lLastError;
	}
	// Wait for the event to happen
	OVERLAPPED ovInternal;
	if (lpOverlapped == 0)
	{
		// Setup our own overlapped structure
		memset(&ovInternal,0,sizeof(ovInternal));
		ovInternal.hEvent = m_hevtOverlapped;
		// Use our internal overlapped structure
		lpOverlapped = &ovInternal;
	}
	// Make sure the overlapped structure isn't busy
	_ASSERTE(HasOverlappedIoCompleted(lpOverlapped));
	// Write the data
	if (!::WriteFile(m_hFile,pData,iLen,pdwWritten,lpOverlapped))
	{
		// Set the internal error code
		long lLastError = ::GetLastError();
		// Overlapped operation in progress is not an actual error
		if (lLastError != ERROR_IO_PENDING)
		{
			// Save the error
			m_lLastError = lLastError;
			// Issue an error and quit
			_RPTF0(_CRT_WARN,"CSerial::Write - Unable to write the data\n");
			return m_lLastError;
		}
		// We need to block if the client didn't specify an overlapped structure
		if (lpOverlapped == &ovInternal)
		{
			// Wait for the overlapped operation to complete
			switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
			{
				case WAIT_OBJECT_0:
					// The overlapped operation has completed
					if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwWritten,FALSE))
					{
						// Set the internal error code
						m_lLastError = ::GetLastError();
						_RPTF0(_CRT_WARN,"CSerial::Write - Overlapped completed without result\n");
						return m_lLastError;
					}
					break;
				case WAIT_TIMEOUT:
					// Cancel the I/O operation
					::CancelIo(m_hFile);
					// The operation timed out. Set the internal error code and quit
					m_lLastError = ERROR_TIMEOUT;
					return m_lLastError;
				default:
					// Set the internal error code
					m_lLastError = ::GetLastError();
					// Issue an error and quit
					_RPTF0(_CRT_WARN,"CSerial::Write - Unable to wait until data has been sent\n");
					return m_lLastError;
			}
		}
	}
	else
	{
		// The operation completed immediatly. Just to be sure
		// we'll set the overlapped structure's event handle.
		::SetEvent(lpOverlapped->hEvent);
	}
	// Return successfully
	return m_lLastError;
}
//=======================================================================================
LONG CSerial::Write	(	LPCSTR pString, 
						DWORD* pdwWritten, 
						LPOVERLAPPED lpOverlapped, 
						DWORD dwTimeout
					)
{
	// Determine the length of the string
	return Write(pString,strlen(pString),pdwWritten,lpOverlapped,dwTimeout);
}
//=======================================================================================
LONG CSerial::Read(	void* pData, 
					size_t iLen, 
					DWORD* pdwRead, 
					LPOVERLAPPED lpOverlapped, 
					DWORD dwTimeout
				  )
{
	// Overlapped operation should specify the pdwRead variable
	_ASSERTE(!lpOverlapped || pdwRead);
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Use our own variable for read count
	DWORD dwRead;
	if (pdwRead == 0)
	{
		pdwRead = &dwRead;
	}
	// Reset the number of bytes read
	*pdwRead = 0;
	// Check if the device is open
	if (m_hFile == NULL)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::Read - Device is not opened\n");
		return m_lLastError;
	}
	// Wait for the event to happen
	OVERLAPPED ovInternal;
	if (lpOverlapped == 0)
	{
		// Setup our own overlapped structure
		memset(&ovInternal,0,sizeof(ovInternal));
		ovInternal.hEvent = m_hevtOverlapped;
		// Use our internal overlapped structure
		lpOverlapped = &ovInternal;
	}
	// Make sure the overlapped structure isn't busy
	_ASSERTE(HasOverlappedIoCompleted(lpOverlapped));

#ifdef _DEBUG
	// The debug version fills the entire data structure with
	// 0xDC bytes, to catch buffer errors as soon as possible.
	memset(pData,0xDC,iLen);
#endif
	
	// Read the data
	if (!::ReadFile(m_hFile,pData,iLen,pdwRead,lpOverlapped))
	{
		// Set the internal error code
		long lLastError = ::GetLastError();
		// Overlapped operation in progress is not an actual error
		if (lLastError != ERROR_IO_PENDING)
		{
			// Save the error
			m_lLastError = lLastError;
			// Issue an error and quit
			_RPTF0(_CRT_WARN,"CSerial::Read - Unable to read the data\n");
			return m_lLastError;
		}
		// We need to block if the client didn't specify an overlapped structure
		if (lpOverlapped == &ovInternal)
		{
			// Wait for the overlapped operation to complete
			switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
			{
				case WAIT_OBJECT_0:
					// The overlapped operation has completed
					if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwRead,FALSE))
					{
						// Set the internal error code
						m_lLastError = ::GetLastError();
						_RPTF0(_CRT_WARN,"CSerial::Read - Overlapped completed without result\n");
						return m_lLastError;
					}
					break;
				case WAIT_TIMEOUT:
					// Cancel the I/O operation
					::CancelIo(m_hFile);
					// The operation timed out. Set the internal error code and quit
					m_lLastError = ERROR_TIMEOUT;
					return m_lLastError;
				default:
					// Set the internal error code
					m_lLastError = ::GetLastError();
					// Issue an error and quit
					_RPTF0(_CRT_WARN,"CSerial::Read - Unable to wait until data has been read\n");
					return m_lLastError;
			}
		}
	}
	else
	{
		// The operation completed immediatly. Just to be sure
		// we'll set the overlapped structure's event handle.
		::SetEvent(lpOverlapped->hEvent);
	}
	// Return successfully
	return m_lLastError;

}
//=======================================================================================
LONG CSerial::Flush()
{
	// Check if the device is open
	if (m_hFile == NULL)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::Read - Device is not opened\n");
		return m_lLastError;
	}
	if (!::PurgeComm(m_hFile, PURGE_TXCLEAR | PURGE_RXCLEAR))
	{
		// Set the internal error code
		m_lLastError = ::GetLastError();
		_RPTF0(_CRT_WARN,"CSerial::Read - Overlapped completed without result\n");
	}
	// Return successfully
	return m_lLastError;

}
//=======================================================================================
CSerial::EEvent CSerial::GetEventType (void)
{
	// Obtain the event
	EEvent eEvent = m_eEvent;
	// Reset internal event type
	m_eEvent = EEventNone;
	// Return the current cause
	return eEvent;

}
//======================================================================================
CSerial::EError CSerial::GetError (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Check if the device is open
	if (m_hFile == 0)
	{
		// Set the internal error code
		m_lLastError = ERROR_INVALID_HANDLE;
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetError - Device is not opened\n");
		return EErrorUnknown;
	}
	// Obtain COM status
	DWORD dwErrors = 0;
	if (!::ClearCommError(m_hFile,&dwErrors,0))
	{
		// Set the internal error code
		m_lLastError = ::GetLastError();
		// Issue an error and quit
		_RPTF0(_CRT_WARN,"CSerial::GetError - Unable to obtain COM status\n");
		return EErrorUnknown;
	}
	// Return the error
	return EError(dwErrors);

}
//======================================================================================
bool CSerial::GetCTS (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Obtain the modem status
	DWORD dwModemStat = 0;
	if (!::GetCommModemStatus(m_hFile,&dwModemStat))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetCTS - Unable to obtain the modem status\n");
		return false;
	}
	// Determine if CTS is on
	return (dwModemStat & MS_CTS_ON) != 0;
}

bool CSerial::GetDSR (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Obtain the modem status
	DWORD dwModemStat = 0;
	if (!::GetCommModemStatus(m_hFile,&dwModemStat))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetDSR - Unable to obtain the modem status\n");
		return false;
	}
	// Determine if DSR is on
	return (dwModemStat & MS_DSR_ON) != 0;

}

bool CSerial::GetRing (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Obtain the modem status
	DWORD dwModemStat = 0;
	if (!::GetCommModemStatus(m_hFile,&dwModemStat))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetRing - Unable to obtain the modem status");
		return false;
	}
	// Determine if Ring is on
	return (dwModemStat & MS_RING_ON) != 0;
}
//==================================================================================
bool CSerial::GetRLSD (void)
{
	// Reset error state
	m_lLastError = ERROR_SUCCESS;
	// Obtain the modem status
	DWORD dwModemStat = 0;
	if (!::GetCommModemStatus(m_hFile,&dwModemStat))
	{
		// Obtain the error code
		m_lLastError = ::GetLastError();
		// Display a warning
		_RPTF0(_CRT_WARN,"CSerial::GetRLSD - Unable to obtain the modem status");
		return false;
	}
	// Determine if RLSD is on
	return (dwModemStat & MS_RLSD_ON) != 0;
}


⌨️ 快捷键说明

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