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

📄 irdaport.cpp

📁 irda communication on PPC. 和IrdaMobilePCSrc.zip一起使用。
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////
//
// IRDA Port class, a class for IRDA support.
//
// Copyright (c) 2003, Strigl Daniel.
//
// License:
// --------
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this source code; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307 USA.
//
// Author: Strigl Daniel, http://www.hh-system.com/danielstrigl
//
//////////////////////////////////////////////////////////////////////
//
// IrdaPort.cpp: implementation of the CIrdaPort class
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "IrdaPort.h"

#include <atlconv.h>

//////////////////////////////////////////////////////////////////////
// CIrdaPort construction/destruction
//////////////////////////////////////////////////////////////////////

CIrdaPort::CIrdaPort()
{
    m_hPort = INVALID_HANDLE_VALUE;
}

CIrdaPort::~CIrdaPort()
{
    Close();
}

IMPLEMENT_DYNAMIC(CIrdaPort, CObject);

//////////////////////////////////////////////////////////////////////
// CIrdaPort diagnostics
//////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
void CIrdaPort::AssertValid() const
{
	CObject::AssertValid();
}

void CIrdaPort::Dump(CDumpContext& dc) const
{
    CObject::Dump(dc);

    dc << "m_hPort = " << m_hPort;
}
#endif // _DEBUG

//////////////////////////////////////////////////////////////////////
// CIrdaPort functions
//////////////////////////////////////////////////////////////////////

#if defined(UNDER_CE) // for Pocket PC application
UINT CIrdaPort::FindPortIndex()
{
	// Look into the registry for the infrared port number

    UINT uiPort = 0;
	HKEY hKey = NULL;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Drivers\\BuiltIn\\IrDA"), 0, 0, &hKey) == ERROR_SUCCESS && hKey != NULL)
    {
        DWORD dwSize = 0;

		if (RegQueryValueEx(hKey, _T("Index"), NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
		{
			if ((dwSize > 0) && (dwSize <= sizeof(DWORD)))
			{
				DWORD dwData = 0;

        		if (RegQueryValueEx(hKey, _T("Index"), NULL, NULL, (LPBYTE) &dwData, &dwSize) == ERROR_SUCCESS)
				{
					uiPort = (UINT) dwData;
				}
			}
		}

        RegCloseKey(hKey);
    }

	if (uiPort != 0)
		return uiPort;

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Comm\\IrDA"), 0, 0, &hKey) == ERROR_SUCCESS && hKey != NULL)
	{
		DWORD dwSize = 0;

        if (RegQueryValueEx(hKey, _T("Port"), NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
		{
			if ((dwSize > 0) && (dwSize <= sizeof(DWORD)))
			{
    			DWORD dwData = 0;

	    		if (RegQueryValueEx(hKey, _T("Port"), NULL, NULL, (LPBYTE) &dwData, &dwSize) == ERROR_SUCCESS)
				{
				    uiPort = (UINT) dwData;
				}
			}
		}

		RegCloseKey(hKey);
    }

	if (uiPort != 0)
		return uiPort;

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Comm\\IrDA\\Linkage"), 0, 0, &hKey) == ERROR_SUCCESS && hKey != NULL)
	{
		DWORD dwSize = 0;

		if (RegQueryValueEx(hKey, _T("Bind"), NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
		{
			if ((dwSize >= sizeof(TCHAR)) && (dwSize % sizeof(TCHAR) == 0))
			{
				LPTSTR pszSubKey = new TCHAR[dwSize / sizeof(TCHAR) + 1];

				if (RegQueryValueEx(hKey, _T("Bind"), NULL, NULL, (LPBYTE) pszSubKey, &dwSize) == ERROR_SUCCESS)
				{
					pszSubKey[dwSize / sizeof(TCHAR)] = _T('\0');

					CString strSubKey;
					strSubKey.Format(_T("Comm\\%s\\Parms"), pszSubKey);

					// AfxMessageBox(strSubKey);

					HKEY hNewKey = NULL;

					if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strSubKey, 0, 0, &hNewKey) == ERROR_SUCCESS && hNewKey != NULL)
					{
						dwSize = 0;

						if (RegQueryValueEx(hNewKey, _T("Port"), NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
						{
			                if ((dwSize > 0) && (dwSize <= sizeof(DWORD)))
							{
    			                DWORD dwData = 0;

	    		                if (RegQueryValueEx(hNewKey, _T("Port"), NULL, NULL, (LPBYTE) &dwData, &dwSize) == ERROR_SUCCESS)
								{
				                    uiPort = (UINT) dwData;
								}
							}
						}

						RegCloseKey(hNewKey);
					}
				}

				delete [] pszSubKey;
			}
		}

		RegCloseKey(hKey);
	}

	if (uiPort != 0)
		return uiPort;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Drivers\\BuiltIn\\IrCOMM"), 0, 0, &hKey) == ERROR_SUCCESS && hKey != NULL)
    {
        DWORD dwSize = 0;

		if (RegQueryValueEx(hKey, _T("Index"), NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
		{
			if ((dwSize > 0) && (dwSize <= sizeof(DWORD)))
			{
				DWORD dwData = 0;

        		if (RegQueryValueEx(hKey, _T("Index"), NULL, NULL, (LPBYTE) &dwData, &dwSize) == ERROR_SUCCESS)
				{
					uiPort = (UINT) dwData;
				}
			}
		}

        RegCloseKey(hKey);
    }

	return uiPort;
}
#endif // #if defined(UNDER_CE)

BOOL CIrdaPort::Open(UINT uiPort)
{
    ASSERT(uiPort > 0 && uiPort <= 255);

    Close();

    // Open the IRDA port

    CString strPort;
    strPort.Format(_T("COM%d:"), uiPort);

    m_hPort = CreateFile((LPCTSTR) strPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

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

    // Set the size of the input and output buffer

    VERIFY(SetupComm(m_hPort, 2048, 2048));

    // Terminates all outstanding read and write operations and clear the buffers

    VERIFY(PurgeComm(m_hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));

    // Reinitializes all IRDA port settings

    DCB dcb;

    dcb.DCBlength = sizeof(DCB);

    VERIFY(GetCommState(m_hPort, &dcb));

    dcb.BaudRate          = CBR_9600;
    dcb.fBinary           = TRUE;
    dcb.fParity           = TRUE;
    dcb.fOutxCtsFlow      = FALSE;
    dcb.fOutxDsrFlow      = FALSE;
    dcb.fDtrControl       = DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity   = FALSE;
    dcb.fTXContinueOnXoff = TRUE;
    dcb.fOutX             = FALSE;
    dcb.fInX              = FALSE;
    dcb.fErrorChar        = FALSE;
    dcb.fNull             = FALSE;
    dcb.fRtsControl       = RTS_CONTROL_DISABLE;
    dcb.fAbortOnError     = FALSE;
 // dcb.fDummy2
 // dcb.wReserved
 // dcb.XonLim
 // dcb.XoffLim
    dcb.ByteSize          = 8;
    dcb.Parity            = NOPARITY;
    dcb.StopBits          = ONESTOPBIT;
 // dcb.XonChar
 // dcb.XoffChar
 // dcb.ErrorChar
 // dcb.EofChar
 // dcb.EvtChar
 // dcb.wReserved1

    VERIFY(SetCommState(m_hPort, &dcb));

    // Set the timeouts for all read and write operations

    COMMTIMEOUTS timeouts;

    VERIFY(GetCommTimeouts(m_hPort, &timeouts));

    timeouts.ReadIntervalTimeout         = MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier  = 0;
    timeouts.ReadTotalTimeoutConstant    = 0;
    timeouts.WriteTotalTimeoutMultiplier = 100;
    timeouts.WriteTotalTimeoutConstant   = 0;

    VERIFY(SetCommTimeouts(m_hPort, &timeouts));

    // Set the serial port to infrared (IR) mode
#if defined(UNDER_CE) // for Pocket PC application
    EscapeCommFunction(m_hPort, SETIR);
#endif // #if defined(UNDER_CE)

    return TRUE;
}

void CIrdaPort::Close()
{
    // Close the IRDA port

    if (IsOpen())
    {
        VERIFY(PurgeComm(m_hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));

#if defined(UNDER_CE) // for Pocket PC application
        EscapeCommFunction(m_hPort, CLRIR);
#endif // #if defined(UNDER_CE)

        VERIFY(CloseHandle(m_hPort));

        m_hPort = INVALID_HANDLE_VALUE;
    }
}

BOOL CIrdaPort::IsOpen() const
{
    return m_hPort != INVALID_HANDLE_VALUE;
}

DWORD CIrdaPort::Read(void* pData, DWORD dwCount) const
{
    ASSERT(IsOpen());

    DWORD dwBytesRead = 0;

    ReadFile(m_hPort, pData, dwCount, &dwBytesRead, NULL);

    return dwBytesRead;
}

BOOL CIrdaPort::ReadWithTimeout(void* pData, DWORD dwCount, DWORD dwTimeout /*= 5000*/) const
{
    ASSERT(pData);
    ASSERT(dwCount > 0);
    ASSERT(IsOpen());

	DWORD n = 0;

	DWORD dwStart = GetTickCount();

	while (n < dwCount)
	{
    	if ((GetTickCount() - dwStart) >= dwTimeout)
		{
		    return FALSE;
		}

	    DWORD dwRead = Read(static_cast<BYTE*>(pData) + n, sizeof(BYTE));

        if (dwRead > 0)
		{
		    dwStart = GetTickCount();

		    n += dwRead;
		}
	}

	return TRUE;
}

DWORD CIrdaPort::Write(const void* pData, DWORD dwCount) const
{
    ASSERT(IsOpen());

    DWORD dwBytesWritten = 0;

    WriteFile(m_hPort, pData, dwCount, &dwBytesWritten, NULL);

    return dwBytesWritten;
}

BOOL CIrdaPort::WriteWithTimeout(const void* pData, DWORD dwCount, DWORD dwTimeout /*= 5000*/) const
{
    ASSERT(pData);
    ASSERT(dwCount > 0);
    ASSERT(IsOpen());

	DWORD n = 0;

	DWORD dwStart = GetTickCount();

	while (n < dwCount)
	{
    	if ((GetTickCount() - dwStart) >= dwTimeout)
		{
		    return FALSE;
		}

	    DWORD dwWritten = Write(static_cast<const BYTE*>(pData) + n, sizeof(BYTE));

        if (dwWritten > 0)
		{
		    dwStart = GetTickCount();

		    n += dwWritten;
		}
	}

	return TRUE;
}

BOOL CIrdaPort::WaitForResponse(CString& strResponse, DWORD dwTimeout /*= 5000*/) const
{
    ASSERT(IsOpen());

    BOOL bData = FALSE;

    unsigned char cCurrentChar  = '\0';
    unsigned char cLastChar     = '\0';
    unsigned char cLastLastChar = '\0';

    strResponse.Empty();

    DWORD dwStartTicks = GetTickCount();

    while (TRUE)
    {
        // Has the timeout occured?

		if ((GetTickCount() - dwStartTicks) >= dwTimeout)
        {
 		    return FALSE;
        }

        // Receive the data from the serial port

        if (Read(&cCurrentChar, sizeof(cCurrentChar)) > 0)
        {
            // Reset the idle timeout since data was received

            dwStartTicks = GetTickCount();

			if (isprint(cCurrentChar) && cLastLastChar == 0x0D && cLastChar == 0x0A && !bData)
			{
				bData = TRUE;  // Received start sequence (<CR><LF>)
			}
			else if (isprint(cLastLastChar) && cLastChar == 0x0D && cCurrentChar == 0x0A && bData)
			{
				break;  // Received end sequence (<CR><LF>)
			}

            // Add the character to the string

            if (bData && isprint(cCurrentChar))
            {
                char szANSI[2] = { cCurrentChar, '\0' };

                strResponse += CString(szANSI);
            }

            cLastLastChar = cLastChar;
			cLastChar     = cCurrentChar;
        }
        else
        {
            Sleep(10);
        }

    } // while (TRUE)

    return TRUE;
}

BOOL CIrdaPort::Send(const CString& strSend, DWORD dwTimeout /*= 5000*/) const
{
    ASSERT(IsOpen());

    USES_CONVERSION; // Need for T2CA() macro

	VERIFY(PurgeComm(m_hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));

    CString str(strSend);

    str += _T("\r"); // Add <CR> at the end of the string

    return WriteWithTimeout(T2CA((LPCTSTR) str), str.GetLength(), dwTimeout);
}

⌨️ 快捷键说明

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