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

📄 sh_serial.cpp

📁 rsa算法打的一个包
💻 CPP
字号:
// Serial.cpp: implementation of the SH_Serial class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SH_Serial.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#include "SH_List.h"

static UINT                            SH_SerialTimerID = 0;
static SH_List<SH_Serial *>            SH_SerialList; 

static VOID CALLBACK SH_SerialTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
    SH_Position   pos;
    SH_Serial   * pSerial;
    pos = SH_SerialList.GetHeadPosition();

    while(pos)
    {
        pSerial = (SH_Serial*)SH_SerialList.GetNext(pos);

        if(pSerial && pSerial->IsOpen()) 
        {
            pSerial->RRecv();

            if(pSerial->GetBufferLength() > 0)
                pSerial->OnRead();
            else
                pSerial->OnIdle();
        }
    }
}

//////////////////////////////////////////////////////////////////////
// SH_Serial Construction/Destruction
//////////////////////////////////////////////////////////////////////

VOID SH_Serial::Initialize()
{
    if(SH_SerialTimerID)
        return;
    SH_SerialTimerID = ::SetTimer(NULL,0x01,100,SH_SerialTimerProc);

    SH_SerialList.RemoveAll();
}

VOID SH_Serial::Uninitialize()
{
    if(SH_SerialTimerID)
    {
        ::KillTimer(NULL,SH_SerialTimerID);
        SH_SerialTimerID = 0;
    }

}

VOID SH_Serial::AddToQueue()
{
    SH_Position pos;
    SH_Serial * pSerial;
    pos = SH_SerialList.GetHeadPosition();

    while(pos)
    {
        pSerial = SH_SerialList.GetNext(pos);
        if(pSerial == this && pSerial->GetPort() == GetPort())
            return;
    }

    SH_SerialList.AddTail(this);
}

VOID SH_Serial::RemoveFromQueue()
{
    SH_Position oldpos,pos;
    SH_Serial * pSerial;
    
    pos = SH_SerialList.GetHeadPosition();

    while(pos)
    {
        oldpos = pos;
        pSerial = SH_SerialList.GetNext(pos);
        if(pSerial == this && pSerial->GetPort() == GetPort())
        {
            SH_SerialList.RemoveAt(oldpos);
            return;
        }
    }
}

SH_Serial::SH_Serial()
{
    Initialize();

    m_hSerial     = INVALID_HANDLE_VALUE;

    memset(&m_RO,0,sizeof(OVERLAPPED));
	memset(&m_SO,0,sizeof(OVERLAPPED));

	m_RO.hEvent = CreateEvent(NULL, true, false, NULL);
	m_SO.hEvent = CreateEvent(NULL, true, false, NULL);

    m_pBuffer = NULL;
}

VOID SH_Serial::Default(UINT uPort,DWORD dwBaud,BYTE btByteSize,char chParity,BYTE btStopBit,int nBufSiz) 
{
    m_nPort       = uPort;
    m_dwBaudRate  = dwBaud;
    m_btStopBit   = btStopBit;
    m_chParify    = chParity;
    m_btByteSize  = btByteSize;

    if(m_pBuffer == NULL)
    {
        m_pBuffer = new SH_Buffer(nBufSiz);
        ASSERT(m_pBuffer != NULL);
    }
}

LPCTSTR SH_Serial::MakeDef()
{
    static CString strDef;

    strDef.Format("baud=%d parity=%c data=%d stop=%d",
        m_dwBaudRate,
        m_chParify,
        m_btByteSize,
        m_btStopBit);

    return strDef;
}

SH_Serial::~SH_Serial()
{
    Close();
	
    if(m_RO.hEvent != INVALID_HANDLE_VALUE)
		CloseHandle(m_RO.hEvent);

	if(m_SO.hEvent != INVALID_HANDLE_VALUE)
		CloseHandle(m_SO.hEvent);

    SAFE_DELETE(m_pBuffer);
    
    if(SH_SerialList.GetCount() == 0)
    {
        Uninitialize();
    }
}

BOOL SH_Serial::Open(UINT uPort,DWORD dwBaud/*=9600*/,BYTE btByteSize/*=8*/,char chParity/*=*'N'*/,BYTE btStopBit/*=1*/,int nBufSiz/*=4096*/)
{
    CString strCom,strDef;

	if(IsOpen())
    {
        TRACE("ERROR:Port %d has already open\n",uPort);
        return FALSE;
    }

    Default(uPort,dwBaud,btByteSize,chParity,btStopBit,nBufSiz);

    strCom.Format("\\.\\COM%d",m_nPort);

	m_hSerial = CreateFile(
		strCom,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,	
		NULL
		);

	if(m_hSerial == INVALID_HANDLE_VALUE)
        goto SERIAL_OPEN_FAIL;

	if(!SetupComm(m_hSerial, 4096, 4096))
        goto SERIAL_OPEN_FAIL;

	if(!GetCommState(m_hSerial, &m_DCB))
        goto SERIAL_OPEN_FAIL;

    strDef = MakeDef();


    if(!BuildCommDCB(strDef,&m_DCB))
        goto SERIAL_OPEN_FAIL;

   	if(!SetCommState(m_hSerial, &m_DCB))
        goto SERIAL_OPEN_FAIL;

	if(!PurgeComm(m_hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ))
        goto SERIAL_OPEN_FAIL;

    AddToQueue();

    return TRUE;

SERIAL_OPEN_FAIL:
    Close();
    TRACE("Comm Port Open Failed.Error no is %d\n",GetLastError());
	return FALSE;
}

BOOL SH_Serial::IsOpen()
{
    return (m_hSerial != INVALID_HANDLE_VALUE);
}

VOID SH_Serial::Close()
{
    if(m_hSerial != INVALID_HANDLE_VALUE)
    {
        RemoveFromQueue();
        
        CloseHandle(m_hSerial);
        
        m_hSerial = INVALID_HANDLE_VALUE;
    }
}

int SH_Serial::RRecv()
{
    int  len;
    char pBuffer[4096];

    len = RRecv(pBuffer,sizeof(pBuffer));
    
    if(len >0 && m_pBuffer)
    {
        len = m_pBuffer->Write(pBuffer,len);
    }

    return len;
}

int SH_Serial::RRecv(char * pBuffer, int nBufLen)
{
	COMSTAT  stat;
	DWORD error;

    if(!IsOpen())
		return 0;

	if(ClearCommError(m_hSerial, &error, &stat) && error > 0)
	{
		PurgeComm(m_hSerial, PURGE_RXABORT | PURGE_RXCLEAR);
		return 0;
	}

	if(stat.cbInQue < 1)
		return 0;

	unsigned long nRecvLen = 0;

	nBufLen = min((int)(nBufLen - 1), (int)stat.cbInQue);

	if(!ReadFile(m_hSerial, pBuffer, nBufLen, &nRecvLen, &m_RO)) 
	{
		if(GetLastError() == ERROR_IO_PENDING)
		{
			if(!GetOverlappedResult(m_hSerial, &m_RO, &nRecvLen, FALSE))
			{
				if(GetLastError() != ERROR_IO_INCOMPLETE)
						nRecvLen = 0;
			}
		}
		else
			nRecvLen = 0;
	}
	return (int)nRecvLen;
}

int SH_Serial::RSend(const char * pBuffer, int nBufLen)
{
	ULONG      uSendLen = 0;
	DWORD      error;
    COMSTAT    stat;
	
    if(!IsOpen())
		return 0;

	if(ClearCommError(m_hSerial, &error, &stat) && error > 0)
		PurgeComm(m_hSerial, PURGE_TXABORT | PURGE_TXCLEAR);	


	if(!WriteFile(m_hSerial, pBuffer, nBufLen, &uSendLen, &m_SO))
    {
        if( GetLastError() != ERROR_IO_PENDING)
		{
            uSendLen = 0;
        }
        else
        {
            /*Wait for transfer complete*/
            if(!GetOverlappedResult(m_hSerial,&m_SO,&uSendLen,TRUE))
            {
                TRACE("Send data failed\n");
                uSendLen = 0;
            }
        }
    }
	return (int)uSendLen;
}

int SH_Serial::Read(char * pBuffer,int nBufLen)
{
    return (int)(m_pBuffer?m_pBuffer->Read(pBuffer,nBufLen):0);
}

int SH_Serial::PseudoRead(char * pBuffer,int nBufLen)
{
    return (int)(m_pBuffer?m_pBuffer->PseudoRead(pBuffer,nBufLen):0);
}

int SH_Serial::GetBufferLength()
{
    return (int)(m_pBuffer?m_pBuffer->GetLength():0);
}

int SH_Serial::Write(const char * pBuffer,int nBufLen)
{
    return (int)RSend(pBuffer,nBufLen);
}

⌨️ 快捷键说明

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