44 #include <sys/param.h>
47 #if defined(BSD) && !defined(__GNU__)
48 #include <IOKit/serial/ioss.h>
49 #include <sys/ioctl.h>
60 #include <sys/param.h>
67 #define snprintf _snprintf
70 #pragma warning(disable : 4996)
86 #if defined(_WIN32) || defined(ANDROID)
99 FD_SET(m_PortFD, &readout);
106 retval = select(m_PortFD + 1, &readout,
nullptr,
nullptr, &tv);
112 else if (retval == -1)
135 bytes_w =
::write(m_PortFD,
buffer + (*nbytes_written), nbytes);
140 for (uint32_t i = *nbytes_written; i < bytes_w + *nbytes_written; i++)
143 *nbytes_written += bytes_w;
154 uint32_t nbytes = strlen(
string);
155 return write(
reinterpret_cast<const uint8_t*
>(
string), nbytes, nbytes_written);
167 uint32_t numBytesToRead = nbytes;
175 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"%s: Request to read %d bytes with %d timeout for m_PortFD %d", __FUNCTION__,
176 nbytes, timeout, m_PortFD);
178 while (numBytesToRead > 0)
180 if ((timeoutResponse = checkTimeout(timeout)))
181 return timeoutResponse;
183 bytesRead =
::read(m_PortFD,
buffer + (*nbytes_read), numBytesToRead);
188 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"%d bytes read and %d bytes remaining...", bytesRead,
189 numBytesToRead - bytesRead);
190 for (uint32_t i = *nbytes_read; i < (*nbytes_read + bytesRead); i++)
193 *nbytes_read += bytesRead;
194 numBytesToRead -= bytesRead;
203 uint32_t *nbytes_read)
217 uint8_t *read_char =
nullptr;
219 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"%s: Request to read until stop char '%#02X' with %d timeout for m_PortFD %d",
220 __FUNCTION__, stop_byte, timeout, m_PortFD);
224 if ((timeoutResponse = checkTimeout(timeout)))
225 return timeoutResponse;
227 read_char =
reinterpret_cast<uint8_t*
>(
buffer + *nbytes_read);
228 bytesRead =
::read(m_PortFD, read_char, 1);
233 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"%s: buffer[%d]=%#X (%c)", __FUNCTION__, (*nbytes_read), *read_char, *read_char);
237 if (*read_char == stop_byte)
239 else if (*nbytes_read >= nsize)
246 #if defined(BSD) && !defined(__GNU__)
260 t_fd = open(
device, O_RDWR | O_NOCTTY | O_NONBLOCK);
272 if (ioctl(t_fd, TIOCEXCL) == -1)
281 if (fcntl(t_fd, F_SETFL, 0) == -1)
363 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid bit rate.", bit_rate);
384 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid data bit count.", word_size);
400 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid parity selection value.", parity);
413 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid stop bit count.", stop_bits);
417 #if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4)
423 speed_t speed = 14400;
424 if (ioctl(t_fd, IOSSIOSPEED, &speed) == -1)
426 IDLog(
"Error calling ioctl(..., IOSSIOSPEED, ...) - %s(%d).\n", strerror(
errno),
errno);
440 if (ioctl(t_fd, TIOCSDTR) == -1)
445 if (ioctl(t_fd, TIOCCDTR) == -1)
450 handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
451 if (ioctl(t_fd, TIOCMSET, &handshake) == -1)
460 if (ioctl(t_fd, TIOCMGET, &handshake) == -1)
466 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"Handshake lines currently set to %d", handshake);
468 #if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
469 unsigned long mics = 1UL;
477 if (ioctl(t_fd, IOSSDATALAT, &mics) == -1)
511 if ((t_fd = open(
device, O_RDWR | O_NOCTTY)) == -1)
521 DEBUGDEVICE(m_DriverName, m_DebugChannel,
"connect: failed getting tty attributes.");
587 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid bit rate.", bit_rate);
592 perror(
"connect: failed setting bit rate.");
600 tty_setting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | HUPCL | CRTSCTS);
619 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid data bit count.", word_size);
635 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid parity selection value.", parity);
648 DEBUGFDEVICE(m_DriverName, m_DebugChannel,
"connect: %d is not a valid stop bit count.", stop_bits);
654 tty_setting.c_iflag &= ~(PARMRK | ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | IXANY);
663 tty_setting.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP);
671 tcflush(t_fd, TCIOFLUSH);
674 DEBUGDEVICE(m_DriverName, m_DebugChannel,
"connect: failed setting attributes on serial port.");
696 tcflush(m_PortFD, TCIOFLUSH);
697 int err = close(m_PortFD);
708 char error_string[512] = {0};
716 snprintf(error_string, 512,
"Read Error: %s", strerror(
errno));
720 snprintf(error_string, 512,
"Write Error: %s", strerror(
errno));
724 snprintf(error_string, 512,
"Select Error: %s", strerror(
errno));
728 return "Timeout error";
732 snprintf(error_string, 512,
733 "Port failure Error: %s. Try adding your user to the dialout group and restart (sudo adduser "
737 snprintf(error_string, 512,
"Port failure Error: %s. Check if device is connected to this port.",
742 return "Parameter error";
746 snprintf(error_string, 512,
"%s", strerror(
errno));
750 return "Read overflow";
753 return "Error: unrecognized error code";
756 #if defined(_MSC_VER)
TTY_RESPONSE read(uint8_t *buffer, uint32_t nbytes, uint8_t timeout, uint32_t *nbytes_read)
read buffer from terminal
TTYBase(const char *driverName)
const std::string error(TTY_RESPONSE code) const
Retrieve the tty error message.
TTY_RESPONSE writeString(const char *string, uint32_t *nbytes_written)
Writes a null terminated string to fd.
TTY_RESPONSE readSection(uint8_t *buffer, uint32_t nsize, uint8_t stop_byte, uint8_t timeout, uint32_t *nbytes_read)
read buffer from terminal with a delimiter
TTY_RESPONSE disconnect()
Closes a tty connection and flushes the bus.
TTY_RESPONSE write(const uint8_t *buffer, uint32_t nbytes, uint32_t *nbytes_written)
Writes a buffer to fd.
TTY_RESPONSE connect(const char *device, uint32_t bit_rate, uint8_t word_size, uint8_t parity, uint8_t stop_bits)
Establishes a tty connection to a terminal device.
void IDLog(const char *fmt,...)
#define DEBUGDEVICE(device, priority, msg)
#define DEBUGFDEVICE(device, priority, msg,...)
std::vector< uint8_t > buffer
struct termios tty_setting