|
|
#include "global.h"
|
|
|
#include "DeviceStr.h"
|
|
|
|
|
|
DeviceStr::DeviceStr()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
DeviceStr::~DeviceStr()
|
|
|
{
|
|
|
CloseDev();
|
|
|
}
|
|
|
|
|
|
void DeviceStr::SetDevType(int type)
|
|
|
{
|
|
|
m_hDev = NULL;
|
|
|
m_ov.hEvent = NULL;
|
|
|
|
|
|
m_printType = type;
|
|
|
}
|
|
|
|
|
|
int DeviceStr::InitStr()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//
|
|
|
int DeviceStr::OpenDev(char * pDev, UINT baud, int type)
|
|
|
{
|
|
|
int iRet;
|
|
|
m_printType = type;
|
|
|
|
|
|
if (m_hDev != NULL)
|
|
|
{
|
|
|
CloseHandle(m_hDev);
|
|
|
m_hDev = NULL;
|
|
|
}
|
|
|
|
|
|
// create events
|
|
|
if (m_ov.hEvent != NULL)
|
|
|
{
|
|
|
ResetEvent(m_ov.hEvent);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
}
|
|
|
|
|
|
switch (type)
|
|
|
{
|
|
|
case PRINTTYPE_COM:
|
|
|
iRet = OpenComDev(pDev, baud);
|
|
|
break;
|
|
|
|
|
|
case PRINTTYPE_LPT:
|
|
|
case PRINTTYPE_USBLPT:
|
|
|
iRet = OpenLptDev(pDev);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
return iRet;
|
|
|
}
|
|
|
|
|
|
//
|
|
|
int DeviceStr::OpenComDev(char * portnr, UINT baud)
|
|
|
{
|
|
|
char parity = 'N'; //奇偶校验
|
|
|
UINT databits = 8; //数据位
|
|
|
UINT stopbits = 1; //停止位
|
|
|
DWORD dwCommEvents = EV_RXCHAR; //消息类型
|
|
|
|
|
|
sprintf(szPort, "\\\\.\\%s", portnr);///可以显示COM10以上端口//add by itas109 2014-01-09
|
|
|
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);
|
|
|
|
|
|
m_hDev = CreateFile(szPort, // communication port string (COMX)
|
|
|
GENERIC_READ | GENERIC_WRITE, // read/write types
|
|
|
0, // comm devices must be opened with exclusive access
|
|
|
NULL, // no security attributes
|
|
|
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
|
|
|
FILE_FLAG_OVERLAPPED, // Async I/O
|
|
|
0); // template must be 0 for comm devices
|
|
|
|
|
|
///创建失败
|
|
|
if (m_hDev == ((HANDLE)(-1)))
|
|
|
{
|
|
|
m_hDev = NULL;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
// set the timeout values
|
|
|
///设置超时
|
|
|
m_CommTimeouts.ReadIntervalTimeout = 1000;
|
|
|
m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
|
|
|
m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
|
|
|
m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
|
|
|
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
|
|
|
|
|
|
if (!SetCommTimeouts(m_hDev, &m_CommTimeouts)) ///设置超时
|
|
|
{
|
|
|
CloseDev();
|
|
|
return -2;
|
|
|
}
|
|
|
|
|
|
if (!SetCommMask(m_hDev, dwCommEvents)) ///设置通信事件
|
|
|
{
|
|
|
CloseDev();
|
|
|
return -3;
|
|
|
}
|
|
|
|
|
|
if (GetCommState(m_hDev, &m_dcb))///获取当前DCB参数
|
|
|
{
|
|
|
m_dcb.EvtChar = 'q';///设置字件字符
|
|
|
m_dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
|
|
|
|
|
if (BuildCommDCB(szBaud, &m_dcb))///填写DCB结构
|
|
|
{
|
|
|
if (!SetCommState(m_hDev, &m_dcb)) ///配置DCB
|
|
|
{
|
|
|
CloseDev();
|
|
|
return -4;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloseDev();
|
|
|
return -4;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloseDev();
|
|
|
return -5;
|
|
|
}
|
|
|
|
|
|
// flush the port
|
|
|
///终止读写并清空接收和发送
|
|
|
PurgeComm(m_hDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//
|
|
|
int DeviceStr::OpenLptDev(char * pDev)
|
|
|
{
|
|
|
m_ov.Offset = 0;
|
|
|
m_ov.OffsetHigh = 0;
|
|
|
|
|
|
m_hDev = CreateFile(pDev, GENERIC_READ | GENERIC_WRITE,
|
|
|
0, NULL, OPEN_EXISTING,
|
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
|
NULL);
|
|
|
|
|
|
if (m_hDev == ((HANDLE)(-1)))
|
|
|
{
|
|
|
m_hDev = NULL;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int DeviceStr::WriteToDev(mySendFrame * ptr)
|
|
|
{
|
|
|
BOOL bWrite = TRUE;
|
|
|
BOOL bResult = TRUE;
|
|
|
|
|
|
DWORD BytesSent = 0;
|
|
|
|
|
|
/* DWORD dwError = 0;
|
|
|
if (ClearCommError(m_hDev, &dwError, NULL))
|
|
|
{
|
|
|
PurgeComm(m_hDev, PURGE_TXABORT | PURGE_TXCLEAR);
|
|
|
}
|
|
|
*/
|
|
|
// Clear buffer
|
|
|
Sleep(20);
|
|
|
if (PRINTTYPE_COM == m_printType)
|
|
|
{
|
|
|
PurgeComm(m_hDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
|
|
|
}
|
|
|
|
|
|
m_ov.Offset = 0;
|
|
|
m_ov.OffsetHigh = 0;
|
|
|
|
|
|
///写入
|
|
|
bResult = WriteFile(m_hDev, // Handle to COMM Port
|
|
|
ptr->buf, // Pointer to message buffer in calling finction
|
|
|
// strlen((char*)port->m_szWriteBuffer), // Length of message to send
|
|
|
ptr->iDatalen, // Length of message to send // add by mrlong
|
|
|
&BytesSent, // Where to store the number of bytes sent
|
|
|
&m_ov);
|
|
|
|
|
|
if (bResult)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
DWORD dwError = GetLastError();
|
|
|
switch (dwError)
|
|
|
{
|
|
|
case ERROR_IO_PENDING:
|
|
|
|
|
|
// continue to GetOverlappedResults()
|
|
|
BytesSent = 0;
|
|
|
bWrite = FALSE;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
// all other error codes
|
|
|
return -1;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
mySleep(ptr->iDatalen);
|
|
|
if (!bWrite)
|
|
|
{
|
|
|
bWrite = TRUE;
|
|
|
|
|
|
bResult = GetOverlappedResult(m_hDev, // Handle to COMM port
|
|
|
&m_ov, // Overlapped structure
|
|
|
&BytesSent, // Stores number of bytes sent
|
|
|
FALSE); // Wait flag
|
|
|
if (0 == bResult)
|
|
|
{
|
|
|
return -2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int DeviceStr::ReadFromDev(mySendFrame * pFrame)
|
|
|
{
|
|
|
COMSTAT comstat;
|
|
|
|
|
|
BOOL bRead = TRUE;
|
|
|
BOOL bResult = TRUE;
|
|
|
DWORD dwError = 0;
|
|
|
DWORD BytesRead = 0;
|
|
|
unsigned char RXBuff;
|
|
|
char * ptr;
|
|
|
|
|
|
ptr = pFrame->buf;
|
|
|
bResult = ClearCommError(m_hDev, &dwError, &comstat);
|
|
|
if (comstat.cbInQue == 0)
|
|
|
{
|
|
|
// break out when all bytes have been read
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
///串口读出,读出缓冲区中字节
|
|
|
bResult = ReadFile(m_hDev, // Handle to COMM port
|
|
|
&RXBuff, // RX Buffer Pointer
|
|
|
1, // Read one byte
|
|
|
&BytesRead, // Stores number of bytes read
|
|
|
&m_ov); // pointer to the m_ov structure
|
|
|
// deal with the error code
|
|
|
if (bResult)
|
|
|
{
|
|
|
ptr[0] = RXBuff;
|
|
|
pFrame->iDatalen = 1;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
switch (dwError = GetLastError())
|
|
|
{
|
|
|
case ERROR_IO_PENDING:
|
|
|
{
|
|
|
// asynchronous i/o is still in progress
|
|
|
// Proceed on to GetOverlappedResults();
|
|
|
///异步IO仍在进行
|
|
|
bRead = FALSE;
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
|
{
|
|
|
// Another error has occured. Process this error.
|
|
|
return -2;
|
|
|
break;
|
|
|
//return;///防止读写数据时,串口非正常断开导致死循环一直执行。add by itas109 2014-01-09 与上面liquanhai添加防死锁的代码差不多
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!bRead)
|
|
|
{
|
|
|
bRead = TRUE;
|
|
|
Sleep(50);
|
|
|
bResult = GetOverlappedResult(m_hDev, // Handle to COMM port
|
|
|
&m_ov, // Overlapped structure
|
|
|
&BytesRead, // Stores number of bytes read
|
|
|
FALSE); // Wait flag
|
|
|
|
|
|
// deal with the error code
|
|
|
if (!bResult)
|
|
|
{
|
|
|
return -3;
|
|
|
//port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ptr[0] = RXBuff;
|
|
|
pFrame->iDatalen = 1;
|
|
|
return 0;
|
|
|
}
|
|
|
} //
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
void DeviceStr::CloseDev()
|
|
|
{
|
|
|
if (m_hDev)
|
|
|
{
|
|
|
CloseHandle(m_hDev);
|
|
|
m_hDev = NULL;
|
|
|
}
|
|
|
|
|
|
if (m_ov.hEvent != NULL)
|
|
|
{
|
|
|
CloseHandle(m_ov.hEvent);
|
|
|
m_ov.hEvent = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int DeviceStr::mySleep(int iLen)
|
|
|
{
|
|
|
int iTime;
|
|
|
|
|
|
iTime = 100 + iLen * 2;
|
|
|
Sleep(iTime);
|
|
|
|
|
|
return 0;
|
|
|
} |