16 #include <sys/ioctl.h>
19 #include <sys/param.h>
27 #ifndef _CRT_SECURE_NO_DEPRECATE
28 #define _CRT_SECURE_NO_DEPRECATE
30 #pragma warning(disable : 4996)
37 #define FSEEK(x) _fseeki64(m_handle, x, SEEK_SET)
38 #define FSEEK_R(x) _fseeki64(m_handle, x, SEEK_END)
39 #define FTELL() _ftelli64(m_handle)
41 #define FSEEK(x) fseeko(m_handle, x, SEEK_SET)
42 #define FSEEK_R(x) fseeko(m_handle, x, SEEK_END)
43 #define FTELL() ftello(m_handle)
49 #define XDA1LOG_OBSOLETE XSENSLOG
51 #define XDA1LOG_OBSOLETE(...) (void)0
72 memset(&m_commState, 0,
sizeof(m_commState));
113 if (::GetCommTimeouts(
m_handle, &cto))
115 cto.ReadIntervalTimeout = MAXDWORD;
116 cto.ReadTotalTimeoutConstant = 0;
117 cto.ReadTotalTimeoutMultiplier = 0;
118 if (::SetCommTimeouts(
m_handle, &cto))
166 rv = EscapeCommFunction(
m_handle, SETDTR);
168 rv = EscapeCommFunction(
m_handle, CLRDTR);
174 rv = EscapeCommFunction(
m_handle, SETRTS);
176 rv = EscapeCommFunction(
m_handle, CLRRTS);
227 if (!PurgeComm(
m_handle, PURGE_TXCLEAR | PURGE_RXCLEAR))
262 return m_handle != INVALID_HANDLE_VALUE;
287 gJournal,
"port " << portInfo.portName().toStdString() <<
" at "
288 << portInfo.baudrate() <<
" baud");
293 gJournal,
"Port " << portInfo.portName().toStdString()
294 <<
" is already open");
301 char winPortName[256];
304 sprintf(winPortName,
"\\\\.\\%s", portInfo.portName().c_str());
306 winPortName, GENERIC_READ | GENERIC_WRITE, 0,
nullptr, OPEN_EXISTING, 0,
308 if (
m_handle == INVALID_HANDLE_VALUE)
311 gJournal,
"Port " << portInfo.portName().toStdString()
312 <<
" cannot be opened");
319 commState.DCBlength =
sizeof(DCB);
322 if (!GetCommState(
m_handle, &commState))
325 commState.BaudRate = (int)portInfo.baudrate();
326 commState.Parity = NOPARITY;
327 commState.ByteSize = 8;
328 commState.StopBits = TWOSTOPBITS;
329 commState.fDsrSensitivity =
FALSE;
330 commState.fOutxCtsFlow =
FALSE;
331 commState.fOutxDsrFlow =
FALSE;
332 commState.fOutX =
FALSE;
333 commState.fInX =
FALSE;
334 commState.fRtsControl = RTS_CONTROL_ENABLE;
335 if (!SetCommState(
m_handle, (LPDCB)&commState))
339 commState.StopBits = ONESTOPBIT;
340 if (!SetCommState(
m_handle, (LPDCB)&commState))
343 std::string tmp = portInfo.portName().toStdString();
344 m_port = atoi(&tmp.c_str()[3]);
350 if (!EscapeCommFunction(
m_handle, SETDTR))
354 if (!SetupComm(
m_handle, readBufSize, writeBufSize))
361 PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
375 std::string pn = portInfo.portName().toStdString();
390 if (flock(
m_handle, LOCK_EX | LOCK_NB))
401 if (cfsetispeed(&m_commState, portInfo.baudrate()) != 0)
return XRV_ERROR;
403 if (cfsetospeed(&m_commState, portInfo.baudrate()) != 0)
return XRV_ERROR;
406 m_commState.c_cflag |= (CLOCAL | CREAD);
409 m_commState.c_cflag &= ~(CSIZE | PARENB);
410 m_commState.c_cflag |= CS8;
411 m_commState.c_cflag |= CSTOPB;
413 m_commState.c_cflag &= ~CRTSCTS;
414 m_commState.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
416 m_commState.c_iflag &=
417 ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
419 m_commState.c_oflag &= ~OPOST;
421 m_commState.c_cc[VMIN] = 0;
422 m_commState.c_cc[VTIME] = (
m_timeout + 99) / 100;
425 if (tcsetattr(
m_handle, TCSANOW, &m_commState) != 0)
428 termios checkCommState;
431 if ((m_commState.c_cflag != checkCommState.c_cflag) ||
432 (m_commState.c_iflag != checkCommState.c_iflag) ||
433 (m_commState.c_oflag != checkCommState.c_oflag) ||
434 (m_commState.c_cc[VMIN] != checkCommState.c_cc[VMIN]) ||
435 (m_commState.c_cc[VTIME] != checkCommState.c_cc[VTIME]))
439 "commstates do not match, which is OK for USB connected MkIV "
450 if (ioctl(
m_handle, TIOCMGET, &cmbits) < 0)
454 "TIOCMGET failed, which is OK for USB connected MkIV devices");
457 cmbits |= TIOCM_RTS | TIOCM_DTR;
459 if (ioctl(
m_handle, TIOCMSET, &cmbits) < 0)
463 "TIOCMSET failed, which is OK for USB connected MkIV devices");
468 gJournal,
"Port " << portInfo.portName().toStdString() <<
" opened");
476 FILE* pf =
fopen(filename,
"r");
477 if (pf ==
nullptr)
return false;
491 strcpy(basename, filename);
492 basename[strlen(basename) - 4] = 0;
496 sprintf(filename2,
"%s_%d.log", basename, counter++);
499 sprintf(filename2,
"%s_n.log", basename);
503 strcpy(filename, filename2);
527 JLTRACE(gJournal,
"ReadFile result " << rres <<
", length " <<
length);
531 DWORD wErr = ::GetLastError();
532 JLALERT(gJournal,
"ReadFile returned windows error " << wErr);
533 if (wErr >= ERROR_INVALID_FUNCTION && wErr <= ERROR_INVALID_HANDLE)
549 timeout.tv_usec = (
m_timeout - (timeout.tv_sec * 1000)) * 1000;
551 int res = select(FD_SETSIZE, &fd,
nullptr, &err, &timeout);
579 fname,
"rx_%s_%d.log", devname + 1,
587 #ifdef LOG_RX_TX_FLUSH
594 gJournal,
"returned success, read "
596 <<
" bytes, first: " << JLHEXLOG(
data[0]));
612 JLDEBUG(gJournal,
"Setting timeout to " << ms <<
" ms");
617 COMMTIMEOUTS commTimeouts;
619 if (!GetCommTimeouts(
626 commTimeouts.ReadIntervalTimeout = 0;
627 commTimeouts.ReadTotalTimeoutConstant =
m_timeout;
628 commTimeouts.ReadTotalTimeoutMultiplier = 0;
629 commTimeouts.WriteTotalTimeoutConstant =
m_timeout;
630 commTimeouts.WriteTotalTimeoutMultiplier = 0;
635 commTimeouts.ReadIntervalTimeout = MAXDWORD;
636 commTimeouts.ReadTotalTimeoutConstant = 0;
637 commTimeouts.ReadTotalTimeoutMultiplier = 0;
638 commTimeouts.WriteTotalTimeoutConstant = 0;
639 commTimeouts.WriteTotalTimeoutMultiplier = 0;
642 if (!SetCommTimeouts(
647 m_commState.c_cc[VMIN] = 0;
648 m_commState.c_cc[VTIME] = (
m_timeout + 99) / 100;
691 gJournal,
"Read " <<
data.size() <<
" of " <<
maxLength <<
" bytes");
706 if (written ==
nullptr) written = &bytes;
737 fname,
"tx_%s_%d.log", devname + 1,
745 #ifdef LOG_RX_TX_FLUSH