Fixes for OSX serial writing.
This commit is contained in:
parent
711bcbf745
commit
6860aed85b
|
@ -906,6 +906,10 @@ bool CModem::readVersion()
|
||||||
if (ret != 3)
|
if (ret != 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
m_serial.setNonblock(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (unsigned int count = 0U; count < MAX_RESPONSES; count++) {
|
for (unsigned int count = 0U; count < MAX_RESPONSES; count++) {
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
RESP_TYPE_MMDVM resp = getResponse();
|
RESP_TYPE_MMDVM resp = getResponse();
|
||||||
|
|
|
@ -237,8 +237,11 @@ CSerialController::~CSerialController()
|
||||||
bool CSerialController::open()
|
bool CSerialController::open()
|
||||||
{
|
{
|
||||||
assert(m_fd == -1);
|
assert(m_fd == -1);
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); /*open in block mode under OSX*/
|
||||||
|
#else
|
||||||
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY, 0);
|
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY, 0);
|
||||||
|
#endif
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
LogError("Cannot open device - %s", m_device.c_str());
|
LogError("Cannot open device - %s", m_device.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
@ -257,6 +260,23 @@ bool CSerialController::open()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
termios.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
|
||||||
|
termios.c_cflag &= ~CSIZE;
|
||||||
|
termios.c_cflag |= CS8; /* 8-bit characters */
|
||||||
|
termios.c_cflag &= ~PARENB; /* no parity bit */
|
||||||
|
termios.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
|
||||||
|
termios.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
|
||||||
|
|
||||||
|
/* setup for non-canonical mode */
|
||||||
|
termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||||
|
termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||||
|
termios.c_oflag &= ~OPOST;
|
||||||
|
|
||||||
|
/* fetch bytes as they become available */
|
||||||
|
termios.c_cc[VMIN] = 1;
|
||||||
|
termios.c_cc[VTIME] = 1;
|
||||||
|
#else
|
||||||
termios.c_lflag &= ~(ECHO | ECHOE | ICANON | IEXTEN | ISIG);
|
termios.c_lflag &= ~(ECHO | ECHOE | ICANON | IEXTEN | ISIG);
|
||||||
termios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY);
|
termios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY);
|
||||||
termios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS);
|
termios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS);
|
||||||
|
@ -264,6 +284,7 @@ bool CSerialController::open()
|
||||||
termios.c_oflag &= ~(OPOST);
|
termios.c_oflag &= ~(OPOST);
|
||||||
termios.c_cc[VMIN] = 0;
|
termios.c_cc[VMIN] = 0;
|
||||||
termios.c_cc[VTIME] = 10;
|
termios.c_cc[VTIME] = 10;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (m_speed) {
|
switch (m_speed) {
|
||||||
case SERIAL_1200:
|
case SERIAL_1200:
|
||||||
|
@ -327,9 +348,27 @@ bool CSerialController::open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
setNonblock(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
int CSerialController::setNonblock(bool nonblock)
|
||||||
|
{
|
||||||
|
int flag = ::fcntl(m_fd, F_GETFD, 0);
|
||||||
|
|
||||||
|
if (nonblock)
|
||||||
|
flag |= O_NONBLOCK;
|
||||||
|
else
|
||||||
|
flag &= ~O_NONBLOCK;
|
||||||
|
|
||||||
|
return ::fcntl(m_fd, F_SETFL, flag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int CSerialController::read(unsigned char* buffer, unsigned int length)
|
int CSerialController::read(unsigned char* buffer, unsigned int length)
|
||||||
{
|
{
|
||||||
assert(buffer != NULL);
|
assert(buffer != NULL);
|
||||||
|
@ -344,13 +383,11 @@ int CSerialController::read(unsigned char* buffer, unsigned int length)
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(m_fd, &fds);
|
FD_SET(m_fd, &fds);
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
if (offset == 0U) {
|
if (offset == 0U) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
n = ::select(m_fd + 1, &fds, NULL, NULL, &tv);
|
n = ::select(m_fd + 1, &fds, NULL, NULL, &tv);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -380,6 +417,26 @@ int CSerialController::read(unsigned char* buffer, unsigned int length)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSerialController::canWrite(){
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
fd_set wset;
|
||||||
|
FD_ZERO(&wset);
|
||||||
|
FD_SET(m_fd, &wset);
|
||||||
|
|
||||||
|
struct timeval timeo;
|
||||||
|
timeo.tv_sec = 0;
|
||||||
|
timeo.tv_usec = 0;
|
||||||
|
|
||||||
|
int rc = select(m_fd + 1, NULL, &wset, NULL, &timeo);
|
||||||
|
if (rc >0 && FD_ISSET(m_fd, &wset))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
||||||
{
|
{
|
||||||
assert(buffer != NULL);
|
assert(buffer != NULL);
|
||||||
|
@ -389,9 +446,10 @@ int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned int ptr = 0U;
|
unsigned int ptr = 0U;
|
||||||
|
|
||||||
while (ptr < length) {
|
while (ptr < length) {
|
||||||
ssize_t n = ::write(m_fd, buffer + ptr, length - ptr);
|
ssize_t n = 0U;
|
||||||
|
if (canWrite())
|
||||||
|
n = ::write(m_fd, buffer + ptr, length - ptr);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
LogError("Error returned from write(), errno=%d", errno);
|
LogError("Error returned from write(), errno=%d", errno);
|
||||||
|
|
|
@ -53,6 +53,10 @@ public:
|
||||||
|
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
virtual int setNonblock(bool nonblock);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_device;
|
std::string m_device;
|
||||||
SERIAL_SPEED m_speed;
|
SERIAL_SPEED m_speed;
|
||||||
|
@ -65,6 +69,8 @@ private:
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
int readNonblock(unsigned char* buffer, unsigned int length);
|
int readNonblock(unsigned char* buffer, unsigned int length);
|
||||||
|
#else
|
||||||
|
bool canWrite();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue