IPBS_Station/SDK/Depend/CSerialPort/test/CSerialPortVirtual.cpp
2024-08-13 17:07:34 +08:00

163 lines
3.9 KiB
C++

#include "CSerialPortVirtual.h"
#include "CSerialPort/iutils.hpp"
#ifdef _WIN32
#include <Windows.h>
#include <tchar.h> //_T
#else
#include <errno.h> // perror
#include <pty.h> // openpty
#include <stdio.h> // printf
#include <sys/select.h> // select FD_ISSET FD_SET FD_ZERO
#include <unistd.h> // read write
#define PORT_NAME_MAX_LEN 256
#define READ_DATA_MAX_LEN 4096
#endif
using namespace itas109;
CSerialPortVirtual::CSerialPortVirtual() {}
CSerialPortVirtual::~CSerialPortVirtual() {}
bool CSerialPortVirtual::createPair(char *portName1, char *portName2)
{
#ifdef _WIN32
bool ret = false;
HINSTANCE libInst;
if (8 == sizeof(char *)) // 64bit application
{
libInst = LoadLibrary(_T("VSPDCTL64.DLL"));
}
else
{
libInst = LoadLibrary(_T("VSPDCTL.DLL"));
}
if (libInst)
{
typedef bool(__stdcall * CreatePairFn)(char *Port1, char *Port2);
CreatePairFn CreatePair = (CreatePairFn)GetProcAddress(libInst, "CreatePair");
if (CreatePair)
{
ret = CreatePair(portName1, portName2); // portName1 = "COM1", portName2 = "COM2"
}
FreeLibrary(libInst);
}
return ret;
#else
int error = -1;
int master1 = 0, slave1 = 0;
int master2 = 0, slave2 = 0;
char slaveName1[PORT_NAME_MAX_LEN] = {0};
char slaveName2[PORT_NAME_MAX_LEN] = {0};
error = openpty(&master1, &slave1, slaveName1, NULL, NULL);
if (-1 == error)
{
perror("openpty failed\n");
return -1;
}
error = openpty(&master2, &slave2, slaveName2, NULL, NULL);
if (-1 == error)
{
perror("openpty failed\n");
return -1;
}
printf("virtual serial port names: %s %s\n", slaveName1, slaveName2);
itas109::IUtils::strncpy(portName1, slaveName1, 256);
itas109::IUtils::strncpy(portName2, slaveName2, 256);
fd_set readfds; // only care read fdset
bool isMaster1 = false;
int recLen = 0;
char data[READ_DATA_MAX_LEN] = {0};
while (1)
{
// select will reset all params every time
FD_ZERO(&readfds); // clear all read fdset
FD_SET(master1, &readfds); // add to read fdset
FD_SET(master2, &readfds); // add to read fdset
// -1 error, 0 timeout, >0 ok
error = select(master1 > master2 ? master1 + 1 : master2 + 1, &readfds, NULL, NULL, NULL);
if (error < 0)
{
perror("select failed");
break;
}
isMaster1 = FD_ISSET(master1, &readfds);
recLen = read(isMaster1 ? master1 : master2, data, READ_DATA_MAX_LEN);
if (recLen > 0)
{
printf("from %s - [%d] %s\n", isMaster1 ? slaveName1 : slaveName2, recLen, data);
// send data to other pty
write(isMaster1 ? master2 : master1, data, recLen);
}
else if (recLen == 0)
{
printf("%s closed\n", isMaster1 ? slaveName1 : slaveName2);
break;
}
else
{
if (errno == EINTR)
{
continue;
}
else
{
perror("read failed\n");
break;
}
}
}
close(master1);
close(slave1);
close(master2);
close(slave2);
#endif // _WIN32
}
bool itas109::CSerialPortVirtual::deletePair(char *portName)
{
#ifdef _WIN32
bool ret = false;
HINSTANCE libInst;
if (8 == sizeof(char *)) // 64bit application
{
libInst = LoadLibrary(_T("VSPDCTL64.DLL"));
}
else
{
libInst = LoadLibrary(_T("VSPDCTL.DLL"));
}
if (libInst)
{
typedef bool(__stdcall * DeletePairFn)(char *Port1);
DeletePairFn DeletePair = (DeletePairFn)GetProcAddress(libInst, "DeletePair");
if (DeletePair)
{
ret = DeletePair(portName);
}
FreeLibrary(libInst);
}
return ret;
#else
return true;
#endif
}