663 lines
18 KiB
C++
663 lines
18 KiB
C++
#include "portproc.h"
|
|
|
|
#ifdef WIN32
|
|
const static char* DEVPATH = "\\\\.\\";
|
|
#else
|
|
const static char* DEVPATH = "/dev/";
|
|
#endif
|
|
//const static char* PARITY[] = { "NONE", "ODD", "EVEN" };
|
|
//const static char* STOPBIT[] = { "1", "1.5", "2" };
|
|
|
|
CPortProcess::CPortProcess()
|
|
{
|
|
m_nPortNo = -1;
|
|
#ifdef WIN32
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
#else
|
|
m_serialfd = -1;
|
|
#endif
|
|
|
|
memset(&buffers, 0, sizeof(buffers));
|
|
}
|
|
|
|
CPortProcess::~CPortProcess()
|
|
{
|
|
}
|
|
|
|
BOOLEAN CPortProcess::OnPreCreate(int id)
|
|
{
|
|
int i, uid;
|
|
CPortProcessItem *pItem;
|
|
|
|
if (!CProcess::OnPreCreate(id)) return FALSE;
|
|
|
|
m_nPortNo = config.processes[id].order;
|
|
if(m_nPortNo < 0 || m_nPortNo >= HARDWARE_PORTS_NUM) return FALSE;
|
|
|
|
if (!SerialPortOpen()) return FALSE;
|
|
|
|
for (i = 0; i < PROCESS_UNIT_NUM; i++)
|
|
{ //判断每个进程所链接的单元
|
|
uid = GetUnitID(i);
|
|
if (uid < 0 || uid >= UNIT_NUM) break;
|
|
pItem = GetItem(i);
|
|
if (NULL == pItem) break;
|
|
pItem->Attach(uid, -1);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN CPortProcess::OnCreated(int id)
|
|
{
|
|
return CProcess::OnCreated(id);
|
|
}
|
|
|
|
void CPortProcess::Destroy(void)
|
|
{
|
|
CProcess::Destroy();
|
|
|
|
SerialPortClose();
|
|
}
|
|
|
|
|
|
BOOLEAN CPortProcess::SerialPortOpen(void)
|
|
{
|
|
#ifdef WIN32
|
|
if (m_serialfd != INVALID_HANDLE_VALUE)
|
|
{
|
|
vLog(LOG_DEBUG, "before open serialfd is: %5d\n", m_serialfd);
|
|
CloseHandle(m_serialfd);
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
char* portname = (char*)malloc(strlen(DEVPATH) + MAX_NAME_SIZE + 1);
|
|
if (portname == NULL) return FALSE;
|
|
strcpy(portname, DEVPATH);
|
|
strcat(portname, config.hardware.ports[m_nPortNo].name);
|
|
m_serialfd = CreateFile(portname,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
(DWORD)0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL);
|
|
if (m_serialfd == INVALID_HANDLE_VALUE)
|
|
{
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "%s error(%d,%s)\r\n", portname, ntError, errorMsg);
|
|
return FALSE;
|
|
}
|
|
if (!SetupComm(m_serialfd, (DWORD)MAX_PORT_BUFFER_SIZE, (DWORD)MAX_PORT_BUFFER_SIZE))
|
|
{
|
|
CloseHandle(m_serialfd);
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "%s error(%d,%s)\r\n", portname, ntError, errorMsg);
|
|
return FALSE;
|
|
}
|
|
DCB dcb;
|
|
if (!GetCommState(m_serialfd, &dcb))
|
|
{
|
|
CloseHandle(m_serialfd);
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "%s error(%d,%s)\r\n", portname, ntError, errorMsg);
|
|
return FALSE;
|
|
}
|
|
|
|
dcb.BaudRate = config.hardware.ports[m_nPortNo].baud;
|
|
dcb.ByteSize = (BYTE)config.hardware.ports[m_nPortNo].data;
|
|
dcb.Parity = (BYTE)config.hardware.ports[m_nPortNo].parity;
|
|
dcb.fParity = (NOPARITY == config.hardware.ports[m_nPortNo].parity ? FALSE : TRUE);
|
|
dcb.StopBits = (BYTE)config.hardware.ports[m_nPortNo].stop;
|
|
|
|
dcb.fOutxDsrFlow = FALSE;
|
|
dcb.fDsrSensitivity = FALSE;
|
|
dcb.fOutxCtsFlow = FALSE;
|
|
|
|
dcb.fRtsControl = FALSE;
|
|
dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
|
dcb.fAbortOnError = TRUE;
|
|
dcb.fBinary = TRUE;
|
|
dcb.fTXContinueOnXoff = FALSE;
|
|
dcb.fOutX = FALSE;
|
|
dcb.fInX = FALSE;
|
|
dcb.ErrorChar = 0;
|
|
dcb.fNull = 0;
|
|
dcb.fDummy2 = 0;
|
|
|
|
if (!SetCommState(m_serialfd, &dcb))
|
|
{
|
|
CloseHandle(m_serialfd);
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "%s error(%d,%s)\r\n", portname, ntError, errorMsg);
|
|
return FALSE;
|
|
}
|
|
|
|
COMMTIMEOUTS commTimeouts;
|
|
commTimeouts.WriteTotalTimeoutConstant = 0;
|
|
commTimeouts.WriteTotalTimeoutMultiplier = 0;
|
|
commTimeouts.ReadTotalTimeoutMultiplier = 0;
|
|
commTimeouts.ReadTotalTimeoutConstant = 0;
|
|
commTimeouts.ReadIntervalTimeout = MAXDWORD;
|
|
|
|
if (!SetCommTimeouts(m_serialfd, &commTimeouts))
|
|
{
|
|
CloseHandle(m_serialfd);
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "%s error(%d,%s)\r\n", portname, ntError, errorMsg);
|
|
return FALSE;
|
|
}
|
|
#else
|
|
int i = 0;
|
|
struct termios newoptions, oldoptions;
|
|
const DWORD speed_table[] = { 0L, 50L, 75L, 110L, 134L, 150L, 200L, 300L, 600L, 1200L,
|
|
1800L, 2400L, 4800L, 9600L, 19200L, 38400L, 57600L, 115200L, 230400L, 460800L,
|
|
500000L, 576000L, 921600L };
|
|
const int m_speed[] = { B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200,
|
|
B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800,
|
|
B500000, B576000, B921600 };
|
|
int table_size = sizeof(speed_table) / sizeof(DWORD);
|
|
char* portname = (char*)malloc(strlen(DEVPATH) + MAX_NAME_SIZE + 1);
|
|
if (portname == NULL) return FALSE;
|
|
strcpy(portname, DEVPATH);
|
|
strcat(portname, config.hardware.ports[m_nPortNo].name);
|
|
|
|
if (m_serialfd > 0)
|
|
{
|
|
vLog(LOG_DEBUG, "before open serialfd = %d\n", m_serialfd);
|
|
close(m_serialfd);
|
|
m_serialfd = -1;
|
|
}
|
|
m_serialfd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL);
|
|
vLog(LOG_DEBUG, "starting to open port(%d) as %s and serialfd = %d\n", m_nPortNo, portname, m_serialfd);
|
|
if (m_serialfd == -1)
|
|
{
|
|
vLog(LOG_ERROR, "open port(%d) %s error(%d,%s).\n", m_nPortNo, portname, errno, strerror(errno));
|
|
free(portname);
|
|
portname = NULL;
|
|
return FALSE;
|
|
}
|
|
free(portname);
|
|
portname = NULL;
|
|
|
|
if (fcntl(m_serialfd, F_SETFL, 0) < 0)
|
|
{
|
|
vLog(LOG_ERROR, "fcntl error(%d,%s).\n", errno, strerror(errno));
|
|
close(m_serialfd);
|
|
m_serialfd = -1;
|
|
return FALSE;
|
|
}
|
|
|
|
if (isatty(m_serialfd) == 0)
|
|
{
|
|
vLog(LOG_ERROR, "standard input is not a terminal device!\n");
|
|
close(m_serialfd);
|
|
m_serialfd = -1;
|
|
return FALSE;
|
|
}
|
|
|
|
bzero(&oldoptions, sizeof(oldoptions));
|
|
if (tcgetattr(m_serialfd, &oldoptions) != 0)
|
|
{
|
|
vLog(LOG_ERROR, "get old attr error(%d,%s).\n", errno, strerror(errno));
|
|
return FALSE;
|
|
}
|
|
bzero(&newoptions, sizeof(newoptions));
|
|
cfmakeraw(&newoptions);
|
|
newoptions.c_cflag |= CLOCAL|CREAD;
|
|
//set baudrate
|
|
for (i = 0; i < table_size; i++)
|
|
{
|
|
if ((long)speed_table[i] == config.hardware.ports[m_nPortNo].baud) break;
|
|
}
|
|
if (i == 0 || i >= table_size)
|
|
{
|
|
vLog(LOG_WARN, "baudrate error! baudrate can't be %d and as default 9600.\n", (int)config.hardware.ports[m_nPortNo].baud);
|
|
i = 13;
|
|
}
|
|
if (cfsetispeed(&newoptions, m_speed[i]) != 0)
|
|
{
|
|
vLog(LOG_ERROR, "set in speed baudrate error(%d,%s).\n", errno, strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (cfsetospeed(&newoptions, m_speed[i]) != 0)
|
|
{
|
|
vLog(LOG_ERROR, "set out speed baudrate error(%d,%s).\n", errno, strerror(errno));
|
|
return FALSE;
|
|
}
|
|
//set bytesize
|
|
newoptions.c_cflag &= ~CSIZE;
|
|
switch (config.hardware.ports[m_nPortNo].data)
|
|
{
|
|
case 5:
|
|
newoptions.c_cflag |= CS5;
|
|
break;
|
|
case 6:
|
|
newoptions.c_cflag |= CS6;
|
|
break;
|
|
case 7:
|
|
newoptions.c_cflag |= CS7;
|
|
break;
|
|
case 8:
|
|
newoptions.c_cflag |= CS8;
|
|
break;
|
|
default:
|
|
newoptions.c_cflag |= CS8;
|
|
break;
|
|
}
|
|
//set stopbis
|
|
switch (config.hardware.ports[m_nPortNo].stop)
|
|
{
|
|
case 0: //一位停止位
|
|
newoptions.c_cflag &= ~CSTOPB;
|
|
break;
|
|
case 2: //两位停止位
|
|
newoptions.c_cflag |= CSTOPB;
|
|
break;
|
|
default:
|
|
newoptions.c_cflag &= ~CSTOPB;
|
|
break;
|
|
}
|
|
//set parity
|
|
switch (config.hardware.ports[m_nPortNo].parity)
|
|
{
|
|
case PARITY_NONE:
|
|
newoptions.c_cflag &= ~PARENB;
|
|
newoptions.c_iflag &= ~INPCK;
|
|
break;
|
|
case PARITY_ODD:
|
|
newoptions.c_cflag |= PARENB;
|
|
newoptions.c_cflag |= PARODD;
|
|
newoptions.c_iflag |= INPCK;
|
|
break;
|
|
case PARITY_EVEN:
|
|
newoptions.c_cflag |= PARENB;
|
|
newoptions.c_cflag &= ~PARODD;
|
|
newoptions.c_iflag |= INPCK;
|
|
break;
|
|
#if 0
|
|
case PARITY_MARK: //Mark校验
|
|
newoptions.c_cflag |= PARENB;
|
|
newoptions.c_cflag |= (CMSPAR | PARODD);
|
|
newoptions.c_iflag |= INPCK;
|
|
break;
|
|
case PARITY_SPACE: //Space校验
|
|
newoptions.c_cflag |= PARENB;
|
|
newoptions.c_cflag &= ~PARODD;
|
|
newoptions.c_cflag |= CMSPAR;
|
|
newoptions.c_iflag |= INPCK;
|
|
break;
|
|
#endif
|
|
default:
|
|
newoptions.c_cflag &= ~PARENB;
|
|
newoptions.c_iflag &= ~INPCK;
|
|
break;
|
|
}
|
|
|
|
newoptions.c_cc[VTIME] = 0;
|
|
newoptions.c_cc[VMIN] = 0;
|
|
newoptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
|
newoptions.c_iflag &= ~(ICRNL | IGNCR | INLCR | IGNBRK | BRKINT);
|
|
newoptions.c_iflag &= ~(IXON | IXOFF | IXANY);
|
|
newoptions.c_oflag &= ~(OCRNL | OLCUC | ONLCR | OPOST);
|
|
|
|
tcflush(m_serialfd, TCIFLUSH);
|
|
if (tcsetattr(m_serialfd, TCSANOW, &newoptions) != 0)
|
|
{
|
|
vLog(LOG_ERROR, "setattr error(%d,%s).\n", errno, strerror(errno));
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
void CPortProcess::SerialPortClose(void)
|
|
{
|
|
#ifdef WIN32
|
|
if (m_serialfd == INVALID_HANDLE_VALUE) return;
|
|
CloseHandle(m_serialfd);
|
|
m_serialfd = INVALID_HANDLE_VALUE;
|
|
#else
|
|
if (m_serialfd < 0) return;
|
|
close(m_serialfd);
|
|
m_serialfd = -1;
|
|
#endif
|
|
}
|
|
|
|
BOOLEAN CPortProcess::Run(void)
|
|
{
|
|
if (!CProcess::Run()) return FALSE;
|
|
|
|
SerialPortRead();
|
|
//数据发送
|
|
SerialPortWrite();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN CPortProcess::SerialPortTimeout(void)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CPortProcess::SerialPortRead(unsigned long timeout)
|
|
{
|
|
#ifdef WIN32
|
|
int len = -1;
|
|
int length;
|
|
DWORD nBytesRead;
|
|
BYTE buffer[MAX_PORT_BUFFER_SIZE];
|
|
|
|
if (!ReadFile(m_serialfd, buffer, MAX_PORT_BUFFER_SIZE, &nBytesRead, NULL))
|
|
{
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "ReadFile error(%d,%s)\r\n", ntError, errorMsg);
|
|
return;
|
|
}
|
|
len = (int)nBytesRead;
|
|
if (len > 0)
|
|
{
|
|
length = wMin(len, (MAX_PORT_BUFFER_SIZE - buffers.in_save));
|
|
memcpy(&buffers.in_buf[buffers.in_save], buffer, length);
|
|
memcpy(buffers.in_buf, &buffer[length], len - length);
|
|
buffers.in_save += len;
|
|
buffers.in_save &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
}
|
|
#else
|
|
int len;
|
|
int val;
|
|
int length;
|
|
BYTE buffer[MAX_PORT_BUFFER_SIZE];
|
|
fd_set rfds;
|
|
struct timeval tv;
|
|
|
|
if (m_serialfd < 0) return;
|
|
//读取数据
|
|
FD_ZERO(&rfds);
|
|
tv.tv_sec = 0;
|
|
if (timeout > 0) tv.tv_usec = timeout;
|
|
else tv.tv_usec = 20000;
|
|
FD_SET(m_serialfd, &rfds);
|
|
|
|
val = select(m_serialfd + 1, &rfds, NULL, NULL, &tv);
|
|
|
|
if (val > 0)
|
|
{
|
|
if (FD_ISSET(m_serialfd, &rfds))
|
|
{ //该串口有数据需要读取
|
|
ioctl(m_serialfd, FIONREAD, &len);
|
|
if (len > 0)
|
|
{
|
|
length = buffers.in_save + MAX_PORT_BUFFER_SIZE - buffers.in_load;
|
|
length &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
length = (MAX_PORT_BUFFER_SIZE - length);
|
|
length = wMin(len, length);
|
|
|
|
len = read(m_serialfd, buffer, length);
|
|
if (len > 0)
|
|
{
|
|
length = wMin(len, (MAX_PORT_BUFFER_SIZE - buffers.in_save));
|
|
memcpy(&buffers.in_buf[buffers.in_save], buffer, length);
|
|
memcpy(buffers.in_buf, &buffer[length], len - length);
|
|
buffers.in_save += len;
|
|
buffers.in_save &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (val == 0)
|
|
{ //timeout
|
|
SerialPortTimeout();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CPortProcess::SerialPortWrite(void)
|
|
{
|
|
#ifdef WIN32
|
|
int len;
|
|
int length;
|
|
DWORD nBytesWritten;
|
|
BYTE buffer[MAX_PORT_BUFFER_SIZE];
|
|
|
|
if (m_serialfd == INVALID_HANDLE_VALUE) return;
|
|
|
|
len = buffers.out_save + MAX_PORT_BUFFER_SIZE - buffers.out_load;
|
|
len &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
if (len <= 0) return;
|
|
|
|
length = wMin(len, (MAX_PORT_BUFFER_SIZE - buffers.out_load));
|
|
memcpy(buffer, &buffers.out_buf[buffers.out_load], length);
|
|
memcpy(&buffer[length], buffers.out_buf, len - length);
|
|
if (!WriteFile(m_serialfd, buffer, len, &nBytesWritten, NULL))
|
|
{
|
|
char errorMsg[256] = { '\0' };
|
|
DWORD ntError = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
ntError,
|
|
GetSystemDefaultLangID(),
|
|
errorMsg,
|
|
sizeof(errorMsg),
|
|
NULL);
|
|
vLog(LOG_ERROR, "WriteFile error(%d,%s)\r\n", ntError, errorMsg);
|
|
return;
|
|
}
|
|
buffers.out_load += nBytesWritten;
|
|
buffers.out_load &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
#else
|
|
int len;
|
|
int val;
|
|
int length;
|
|
BYTE buffer[MAX_PORT_BUFFER_SIZE];
|
|
fd_set wfds;
|
|
struct timeval tv;
|
|
|
|
if (m_serialfd < 0) return;
|
|
|
|
len = buffers.out_save + MAX_PORT_BUFFER_SIZE - buffers.out_load;
|
|
len &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
if (len > 0)
|
|
{ //存在数据发送
|
|
FD_ZERO(&wfds);
|
|
tv.tv_sec = 0;
|
|
tv.tv_usec = 20000;
|
|
FD_SET(m_serialfd, &wfds);
|
|
|
|
val = select(m_serialfd + 1, NULL, &wfds, NULL, &tv);
|
|
if (val > 0)
|
|
{
|
|
if (FD_ISSET(m_serialfd, &wfds))
|
|
{ //该串口可以发送数据
|
|
length = wMin(len, (MAX_PORT_BUFFER_SIZE - buffers.out_load));
|
|
memcpy(buffer, &buffers.out_buf[buffers.out_load], length);
|
|
memcpy(&buffer[length], buffers.out_buf, len - length);
|
|
tcflush(m_serialfd, TCOFLUSH);
|
|
write(m_serialfd, buffer, len);
|
|
tcdrain(m_serialfd);
|
|
buffers.out_load += len;
|
|
buffers.out_load &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
BOOLEAN CPortProcess::OnTimer(void)
|
|
{
|
|
if (!CProcess::OnTimer()) return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN CPortProcess::FindData(BYTE nChar)
|
|
{
|
|
int load;
|
|
|
|
load = buffers.in_load;
|
|
while (load != buffers.in_save)
|
|
{
|
|
if (buffers.in_buf[load] == nChar)
|
|
{
|
|
buffers.in_load = load;
|
|
return TRUE;
|
|
}
|
|
load++;
|
|
load &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
}
|
|
buffers.in_load = load;
|
|
return FALSE;
|
|
}
|
|
|
|
void CPortProcess::DropData(int count)
|
|
{
|
|
buffers.in_load += count;
|
|
buffers.in_load &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
}
|
|
|
|
BOOLEAN CPortProcess::GetData(BYTE* pBuf, int count)
|
|
{
|
|
int len, load;
|
|
|
|
len = buffers.in_save + MAX_PORT_BUFFER_SIZE - buffers.in_load;
|
|
len &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
if (len < count) return FALSE;
|
|
|
|
len = 0;
|
|
load = buffers.in_load;
|
|
while (load != buffers.in_save)
|
|
{
|
|
*pBuf = buffers.in_buf[load];
|
|
pBuf++;
|
|
len++;
|
|
load++;
|
|
load &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
if (len >= count) break;
|
|
}
|
|
return (len == count);
|
|
}
|
|
|
|
BOOLEAN CPortProcess::WriteData(const BYTE* pData, int count)
|
|
{
|
|
int i;
|
|
int save;
|
|
|
|
save = buffers.out_save;
|
|
for (i = 0; i < count; i++, pData++)
|
|
{
|
|
buffers.out_buf[save] = *pData;
|
|
save++;
|
|
save &= (MAX_PORT_BUFFER_SIZE - 1);
|
|
}
|
|
buffers.out_save = save;
|
|
return TRUE;
|
|
}
|
|
|
|
int CPortProcess::GetTimeout(void) const
|
|
{
|
|
int timeout;
|
|
|
|
timeout = config.hardware.ports[m_nPortNo].timeout / DELAY_TIMER;
|
|
if (timeout <= 0) timeout = TIME_BASE;
|
|
|
|
return timeout;
|
|
}
|
|
|
|
CPortProcessItem::CPortProcessItem()
|
|
{
|
|
m_uid = -1;
|
|
}
|
|
|
|
CPortProcessItem::~CPortProcessItem()
|
|
{
|
|
m_uid = -1;
|
|
}
|
|
|
|
void CPortProcessItem::Attach(int uid, int physicsAddress /* = 0 */, int commonAddress /* = 0 */, int originatorAddress /* = 0 */)
|
|
{
|
|
m_uid = uid;
|
|
m_physicsAddress = physicsAddress;
|
|
m_commonAddress = commonAddress;
|
|
m_originatorAddress = originatorAddress;
|
|
}
|
|
|
|
void CPortProcessItem::Release(void)
|
|
{
|
|
m_physicsAddress = 0;
|
|
m_commonAddress = 0;
|
|
m_originatorAddress = 0;
|
|
}
|
|
|
|
////CPortProcessItem类实现
|
|
CPortProcessItem *CPortProcess::CreateItem(int ord)
|
|
{
|
|
return(new CPortProcessItem);
|
|
}
|
|
|
|
void CPortProcess::DestroyItem(int ord, BOOLEAN bDeleted /* = FALSE */)
|
|
{
|
|
if (ord < 0 || ord >= PROCESS_UNIT_NUM) return;
|
|
if (!bDeleted)
|
|
{
|
|
CPortProcessItem *pItem = (CPortProcessItem *)m_pItems[ord];
|
|
if (pItem)
|
|
{
|
|
delete pItem;
|
|
}
|
|
}
|
|
m_pItems[ord] = NULL;
|
|
}
|
|
|