code format
This commit is contained in:
@@ -1,133 +1,137 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
COM
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "piserial.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "pidir.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "piwaitevent_p.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(MICRO_PIP)
|
||||
# define PISERIAL_NO_PINS
|
||||
#endif
|
||||
#if defined(PISERIAL_NO_PINS) || defined(WINDOWS)
|
||||
# define TIOCM_LE 1
|
||||
# define TIOCM_DTR 4
|
||||
# define TIOCM_RTS 7
|
||||
# define TIOCM_CTS 8
|
||||
# define TIOCM_ST 3
|
||||
# define TIOCM_SR 2
|
||||
# define TIOCM_CAR 1
|
||||
# define TIOCM_RNG 9
|
||||
# define TIOCM_DSR 6
|
||||
# define TIOCM_LE 1
|
||||
# define TIOCM_DTR 4
|
||||
# define TIOCM_RTS 7
|
||||
# define TIOCM_CTS 8
|
||||
# define TIOCM_ST 3
|
||||
# define TIOCM_SR 2
|
||||
# define TIOCM_CAR 1
|
||||
# define TIOCM_RNG 9
|
||||
# define TIOCM_DSR 6
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
# ifndef INITGUID
|
||||
# define INITGUID
|
||||
# include <guiddef.h>
|
||||
# undef INITGUID
|
||||
# define INITGUID
|
||||
# include <guiddef.h>
|
||||
# undef INITGUID
|
||||
# else
|
||||
# include <guiddef.h>
|
||||
# include <guiddef.h>
|
||||
# endif
|
||||
// clang-format off
|
||||
# include <ntddmodm.h>
|
||||
# include <winreg.h>
|
||||
# include <windows.h>
|
||||
# include <winioctl.h>
|
||||
# include <cfgmgr32.h>
|
||||
# include <setupapi.h>
|
||||
# define B50 50
|
||||
# define B75 75
|
||||
# define B110 110
|
||||
# define B300 300
|
||||
# define B600 600
|
||||
# define B1200 1200
|
||||
# define B2400 2400
|
||||
# define B4800 4800
|
||||
# define B9600 9600
|
||||
# define B14400 14400
|
||||
# define B19200 19200
|
||||
# define B38400 38400
|
||||
# define B57600 57600
|
||||
# define B115200 115200
|
||||
# define B230400 230400
|
||||
# define B460800 460800
|
||||
# define B500000 500000
|
||||
# define B576000 576000
|
||||
# define B921600 921600
|
||||
# define B1000000 1000000
|
||||
# define B1152000 1152000
|
||||
# define B1500000 1500000
|
||||
# define B2000000 2000000
|
||||
# define B2500000 2500000
|
||||
# define B3000000 3000000
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
// clang-format on
|
||||
# define B50 50
|
||||
# define B75 75
|
||||
# define B110 110
|
||||
# define B300 300
|
||||
# define B600 600
|
||||
# define B1200 1200
|
||||
# define B2400 2400
|
||||
# define B4800 4800
|
||||
# define B9600 9600
|
||||
# define B14400 14400
|
||||
# define B19200 19200
|
||||
# define B38400 38400
|
||||
# define B57600 57600
|
||||
# define B115200 115200
|
||||
# define B230400 230400
|
||||
# define B460800 460800
|
||||
# define B500000 500000
|
||||
# define B576000 576000
|
||||
# define B921600 921600
|
||||
# define B1000000 1000000
|
||||
# define B1152000 1152000
|
||||
# define B1500000 1500000
|
||||
# define B2000000 2000000
|
||||
# define B2500000 2500000
|
||||
# define B3000000 3000000
|
||||
# define B3500000 3500000
|
||||
# define B4000000 4000000
|
||||
#else
|
||||
# include <termios.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <termios.h>
|
||||
# ifndef B50
|
||||
# define B50 0000001
|
||||
# define B50 0000001
|
||||
# endif
|
||||
# ifndef B75
|
||||
# define B75 0000002
|
||||
# define B75 0000002
|
||||
# endif
|
||||
# ifndef B230400
|
||||
# define B230400 0010003
|
||||
# define B230400 0010003
|
||||
# endif
|
||||
# ifndef B460800
|
||||
# define B460800 0010004
|
||||
# define B460800 0010004
|
||||
# endif
|
||||
# ifndef B500000
|
||||
# define B500000 0010005
|
||||
# define B500000 0010005
|
||||
# endif
|
||||
# ifndef B576000
|
||||
# define B576000 0010006
|
||||
# define B576000 0010006
|
||||
# endif
|
||||
# ifndef B921600
|
||||
# define B921600 0010007
|
||||
# define B921600 0010007
|
||||
# endif
|
||||
# ifndef B1000000
|
||||
# define B1000000 0010010
|
||||
# define B1000000 0010010
|
||||
# endif
|
||||
# ifndef B1152000
|
||||
# define B1152000 0010011
|
||||
# define B1152000 0010011
|
||||
# endif
|
||||
# ifndef B1500000
|
||||
# define B1500000 0010012
|
||||
# define B1500000 0010012
|
||||
# endif
|
||||
# ifndef B2000000
|
||||
# define B2000000 0010013
|
||||
# define B2000000 0010013
|
||||
# endif
|
||||
# ifndef B2500000
|
||||
# define B2500000 0010014
|
||||
# define B2500000 0010014
|
||||
# endif
|
||||
# ifndef B3000000
|
||||
# define B3000000 0010015
|
||||
# define B3000000 0010015
|
||||
# endif
|
||||
# ifndef B3500000
|
||||
# define B3500000 0010016
|
||||
# define B3500000 0010016
|
||||
# endif
|
||||
# ifndef B4000000
|
||||
# define B4000000 0010017
|
||||
# define B4000000 0010017
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CRTSCTS
|
||||
@@ -174,7 +178,7 @@ PRIVATE_DEFINITION_START(PISerial)
|
||||
#ifdef WINDOWS
|
||||
PIWaitEvent event_write;
|
||||
DCB desc, sdesc;
|
||||
HANDLE hCom = nullptr;
|
||||
HANDLE hCom = nullptr;
|
||||
DWORD readed = 0, mask = 0;
|
||||
OVERLAPPED overlap, overlap_write;
|
||||
#else
|
||||
@@ -184,22 +188,19 @@ PRIVATE_DEFINITION_START(PISerial)
|
||||
PRIVATE_DEFINITION_END(PISerial)
|
||||
|
||||
|
||||
|
||||
|
||||
PIString PISerial::DeviceInfo::id() const {
|
||||
return PIString::fromNumber(vID, 16).toLowerCase().expandLeftTo(4, '0') + ":" +
|
||||
PIString::fromNumber(pID, 16).toLowerCase().expandLeftTo(4, '0');
|
||||
PIString::fromNumber(pID, 16).toLowerCase().expandLeftTo(4, '0');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PISerial::PISerial(): PIIODevice("", ReadWrite) {
|
||||
construct();
|
||||
}
|
||||
|
||||
|
||||
PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_): PIIODevice(device_, ReadWrite) {
|
||||
PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags<PISerial::Parameters> params_)
|
||||
: PIIODevice(device_, ReadWrite) {
|
||||
construct();
|
||||
setPath(device_);
|
||||
setSpeed(speed_);
|
||||
@@ -219,7 +220,7 @@ PISerial::~PISerial() {
|
||||
|
||||
void PISerial::construct() {
|
||||
sending = false;
|
||||
//setPriority(piHigh);
|
||||
// setPriority(piHigh);
|
||||
setParameters(0);
|
||||
setSpeed(S115200);
|
||||
setDataBitsCount(8);
|
||||
@@ -245,16 +246,12 @@ bool PISerial::setPin(int number, bool on) {
|
||||
case 2: return setSR(on); break;
|
||||
case 3: return setST(on); break;
|
||||
case 4: return setDTR(on); break;
|
||||
case 5:
|
||||
piCoutObj << "Pin number 5 is ground";
|
||||
return false;
|
||||
case 5: piCoutObj << "Pin number 5 is ground"; return false;
|
||||
case 6: return setDSR(on); break;
|
||||
case 7: return setRTS(on); break;
|
||||
case 8: return setCTS(on); break;
|
||||
case 9: return setRNG(on); break;
|
||||
default:
|
||||
piCoutObj << "Pin number " << number << " doesn`t exists!";
|
||||
return false;
|
||||
default: piCoutObj << "Pin number " << number << " doesn`t exists!"; return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -271,32 +268,66 @@ bool PISerial::isPin(int number) const {
|
||||
case 7: return isRTS(); break;
|
||||
case 8: return isCTS(); break;
|
||||
case 9: return isRNG(); break;
|
||||
default:
|
||||
piCoutObj << "Pin number " << number << " doesn`t exists!";
|
||||
return false;
|
||||
default: piCoutObj << "Pin number " << number << " doesn`t exists!"; return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PISerial::setLE(bool on) {return setBit(TIOCM_LE, on, "LE");}
|
||||
bool PISerial::setDTR(bool on) {return setBit(TIOCM_DTR, on, "DTR");}
|
||||
bool PISerial::setRTS(bool on) {return setBit(TIOCM_RTS, on, "RTS");}
|
||||
bool PISerial::setCTS(bool on) {return setBit(TIOCM_CTS, on, "CTS");}
|
||||
bool PISerial::setST(bool on) {return setBit(TIOCM_ST, on, "ST");}
|
||||
bool PISerial::setSR(bool on) {return setBit(TIOCM_SR, on, "SR");}
|
||||
bool PISerial::setCAR(bool on) {return setBit(TIOCM_CAR, on, "CAR");}
|
||||
bool PISerial::setRNG(bool on) {return setBit(TIOCM_RNG, on, "RNG");}
|
||||
bool PISerial::setDSR(bool on) {return setBit(TIOCM_DSR, on, "DSR");}
|
||||
bool PISerial::setLE(bool on) {
|
||||
return setBit(TIOCM_LE, on, "LE");
|
||||
}
|
||||
bool PISerial::setDTR(bool on) {
|
||||
return setBit(TIOCM_DTR, on, "DTR");
|
||||
}
|
||||
bool PISerial::setRTS(bool on) {
|
||||
return setBit(TIOCM_RTS, on, "RTS");
|
||||
}
|
||||
bool PISerial::setCTS(bool on) {
|
||||
return setBit(TIOCM_CTS, on, "CTS");
|
||||
}
|
||||
bool PISerial::setST(bool on) {
|
||||
return setBit(TIOCM_ST, on, "ST");
|
||||
}
|
||||
bool PISerial::setSR(bool on) {
|
||||
return setBit(TIOCM_SR, on, "SR");
|
||||
}
|
||||
bool PISerial::setCAR(bool on) {
|
||||
return setBit(TIOCM_CAR, on, "CAR");
|
||||
}
|
||||
bool PISerial::setRNG(bool on) {
|
||||
return setBit(TIOCM_RNG, on, "RNG");
|
||||
}
|
||||
bool PISerial::setDSR(bool on) {
|
||||
return setBit(TIOCM_DSR, on, "DSR");
|
||||
}
|
||||
|
||||
bool PISerial::isLE() const {return isBit(TIOCM_LE, "LE");}
|
||||
bool PISerial::isDTR() const {return isBit(TIOCM_DTR, "DTR");}
|
||||
bool PISerial::isRTS() const {return isBit(TIOCM_RTS, "RTS");}
|
||||
bool PISerial::isCTS() const {return isBit(TIOCM_CTS, "CTS");}
|
||||
bool PISerial::isST() const {return isBit(TIOCM_ST, "ST");}
|
||||
bool PISerial::isSR() const {return isBit(TIOCM_SR, "SR");}
|
||||
bool PISerial::isCAR() const {return isBit(TIOCM_CAR, "CAR");}
|
||||
bool PISerial::isRNG() const {return isBit(TIOCM_RNG, "RNG");}
|
||||
bool PISerial::isDSR() const {return isBit(TIOCM_DSR, "DSR");}
|
||||
bool PISerial::isLE() const {
|
||||
return isBit(TIOCM_LE, "LE");
|
||||
}
|
||||
bool PISerial::isDTR() const {
|
||||
return isBit(TIOCM_DTR, "DTR");
|
||||
}
|
||||
bool PISerial::isRTS() const {
|
||||
return isBit(TIOCM_RTS, "RTS");
|
||||
}
|
||||
bool PISerial::isCTS() const {
|
||||
return isBit(TIOCM_CTS, "CTS");
|
||||
}
|
||||
bool PISerial::isST() const {
|
||||
return isBit(TIOCM_ST, "ST");
|
||||
}
|
||||
bool PISerial::isSR() const {
|
||||
return isBit(TIOCM_SR, "SR");
|
||||
}
|
||||
bool PISerial::isCAR() const {
|
||||
return isBit(TIOCM_CAR, "CAR");
|
||||
}
|
||||
bool PISerial::isRNG() const {
|
||||
return isBit(TIOCM_RNG, "RNG");
|
||||
}
|
||||
bool PISerial::isDSR() const {
|
||||
return isBit(TIOCM_DSR, "DSR");
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
@@ -349,9 +380,9 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||
}
|
||||
#ifndef PISERIAL_NO_PINS
|
||||
# ifdef WINDOWS
|
||||
static int bit_map_on [] = {0, 0, 0, 0, SETDTR, 0, 0, SETRTS, 0, 0, 0};
|
||||
static int bit_map_on[] = {0, 0, 0, 0, SETDTR, 0, 0, SETRTS, 0, 0, 0};
|
||||
static int bit_map_off[] = {0, 0, 0, 0, CLRDTR, 0, 0, CLRRTS, 0, 0, 0};
|
||||
int action = (on ? bit_map_on : bit_map_off)[bit];
|
||||
int action = (on ? bit_map_on : bit_map_off)[bit];
|
||||
if (action > 0) {
|
||||
if (EscapeCommFunction(PRIVATE->hCom, action) == 0) {
|
||||
piCoutObj << "setBit" << bname << " error: " << errorString();
|
||||
@@ -381,8 +412,7 @@ bool PISerial::isBit(int bit, const PIString & bname) const {
|
||||
# ifdef WINDOWS
|
||||
# else
|
||||
int ret = 0;
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0)
|
||||
piCoutObj << "isBit" << bname << " error: " << errorString();
|
||||
if (ioctl(fd, TIOCMGET, &ret) < 0) piCoutObj << "isBit" << bname << " error: " << errorString();
|
||||
return ret & bit;
|
||||
# endif
|
||||
#endif
|
||||
@@ -464,21 +494,23 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
||||
int ret, all = 0;
|
||||
if (timeout_ms > 0.) {
|
||||
bool br = setOption(BlockingRead, false);
|
||||
all = readDevice(data, 1);
|
||||
all = readDevice(data, 1);
|
||||
tm_.reset();
|
||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(&((uchar * )data)[all], size - all);
|
||||
if (ret > 0) all += ret;
|
||||
else piMinSleep();
|
||||
ret = readDevice(&((uchar *)data)[all], size - all);
|
||||
if (ret > 0)
|
||||
all += ret;
|
||||
else
|
||||
piMinSleep();
|
||||
}
|
||||
setOption(BlockingRead, br);
|
||||
received(data, all);
|
||||
return (all == size);
|
||||
} else {
|
||||
bool br = setOption(BlockingRead, true);
|
||||
all = readDevice(data, 1);
|
||||
all = readDevice(data, 1);
|
||||
while (all < size) {
|
||||
ret = readDevice(&((uchar * )data)[all], size - all);
|
||||
ret = readDevice(&((uchar *)data)[all], size - all);
|
||||
if (ret > 0) all += ret;
|
||||
}
|
||||
setOption(BlockingRead, br);
|
||||
@@ -518,15 +550,18 @@ PIString PISerial::readString(int size, double timeout_ms) {
|
||||
if (size <= 0) {
|
||||
while (tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, 1024);
|
||||
if (ret <= 0) piMinSleep();
|
||||
else str += PIString((char*)td, ret);
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else
|
||||
str += PIString((char *)td, ret);
|
||||
}
|
||||
} else {
|
||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str += PIString((char*)td, ret);
|
||||
str += PIString((char *)td, ret);
|
||||
all += ret;
|
||||
}
|
||||
}
|
||||
@@ -534,13 +569,14 @@ PIString PISerial::readString(int size, double timeout_ms) {
|
||||
setOption(BlockingRead, br);
|
||||
} else {
|
||||
bool br = setOption(BlockingRead, true);
|
||||
all = readDevice(td, 1);
|
||||
str += PIString((char*)td, all);
|
||||
all = readDevice(td, 1);
|
||||
str += PIString((char *)td, all);
|
||||
while (all < size) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str += PIString((char*)td, ret);
|
||||
str += PIString((char *)td, ret);
|
||||
all += ret;
|
||||
}
|
||||
}
|
||||
@@ -580,13 +616,16 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
||||
if (size <= 0) {
|
||||
while (tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, 1024);
|
||||
if (ret <= 0) piMinSleep();
|
||||
else str.append(td, ret);
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else
|
||||
str.append(td, ret);
|
||||
}
|
||||
} else {
|
||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str.append(td, ret);
|
||||
all += ret;
|
||||
@@ -596,11 +635,12 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
||||
setOption(BlockingRead, br);
|
||||
} else {
|
||||
bool br = setOption(BlockingRead, true);
|
||||
all = readDevice(td, 1);
|
||||
all = readDevice(td, 1);
|
||||
str.append(td, all);
|
||||
while (all < size) {
|
||||
ret = readDevice(td, size - all);
|
||||
if (ret <= 0) piMinSleep();
|
||||
if (ret <= 0)
|
||||
piMinSleep();
|
||||
else {
|
||||
str.append(td, ret);
|
||||
all += ret;
|
||||
@@ -617,17 +657,18 @@ bool PISerial::send(const void * data, int size) {
|
||||
int ret = 0;
|
||||
int wsz = 0;
|
||||
do {
|
||||
ret = write(&(((uchar*)data)[wsz]), size - wsz);
|
||||
ret = write(&(((uchar *)data)[wsz]), size - wsz);
|
||||
if (ret > 0) wsz += ret;
|
||||
//piCout << ret << wsz;
|
||||
else return false;
|
||||
// piCout << ret << wsz;
|
||||
else
|
||||
return false;
|
||||
} while (wsz < size);
|
||||
return (wsz == size);
|
||||
}
|
||||
|
||||
|
||||
void PISerial::interrupt() {
|
||||
//piCoutObj << "interrupt";
|
||||
// piCoutObj << "interrupt";
|
||||
PRIVATE->event.interrupt();
|
||||
#ifdef WINDOWS
|
||||
PRIVATE->event_write.interrupt();
|
||||
@@ -636,13 +677,13 @@ void PISerial::interrupt() {
|
||||
|
||||
|
||||
bool PISerial::openDevice() {
|
||||
PIString p = path();
|
||||
//piCout << "ser open" << p;
|
||||
PIString p = path();
|
||||
// piCout << "ser open" << p;
|
||||
PIString pl = p.toLowerCase().removeAll(' ');
|
||||
if (!pl.startsWith("/") && !pl.startsWith("com")) {
|
||||
p.clear();
|
||||
PIVector<DeviceInfo> devs = availableDevicesInfo();
|
||||
piForeachC (DeviceInfo & d, devs) {
|
||||
piForeachC(DeviceInfo & d, devs) {
|
||||
if (d.id() == pl) {
|
||||
p = d.path;
|
||||
break;
|
||||
@@ -655,9 +696,15 @@ bool PISerial::openDevice() {
|
||||
if (p.isEmpty()) return false;
|
||||
#ifdef WINDOWS
|
||||
DWORD ds = 0, sm = 0;
|
||||
if (isReadable()) {ds |= GENERIC_READ; sm |= FILE_SHARE_READ;}
|
||||
if (isWriteable()) {ds |= GENERIC_WRITE; sm |= FILE_SHARE_WRITE;}
|
||||
PIString wp = "//./" + p;
|
||||
if (isReadable()) {
|
||||
ds |= GENERIC_READ;
|
||||
sm |= FILE_SHARE_READ;
|
||||
}
|
||||
if (isWriteable()) {
|
||||
ds |= GENERIC_WRITE;
|
||||
sm |= FILE_SHARE_WRITE;
|
||||
}
|
||||
PIString wp = "//./" + p;
|
||||
PRIVATE->hCom = CreateFileA(wp.dataAscii(), ds, sm, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
|
||||
if (PRIVATE->hCom == INVALID_HANDLE_VALUE) {
|
||||
piCoutObj << "Unable to open \"" << p << "\"";
|
||||
@@ -679,7 +726,7 @@ bool PISerial::openDevice() {
|
||||
}
|
||||
tcgetattr(fd, &PRIVATE->desc);
|
||||
PRIVATE->sdesc = PRIVATE->desc;
|
||||
//piCoutObj << "Initialized " << p;
|
||||
// piCoutObj << "Initialized " << p;
|
||||
#endif
|
||||
applySettings();
|
||||
PRIVATE->event.create();
|
||||
@@ -699,7 +746,7 @@ bool PISerial::closeDevice() {
|
||||
#ifdef WINDOWS
|
||||
SetCommState(PRIVATE->hCom, &PRIVATE->sdesc);
|
||||
SetCommMask(PRIVATE->hCom, PRIVATE->mask);
|
||||
// piCoutObj << "close" <<
|
||||
// piCoutObj << "close" <<
|
||||
CloseHandle(PRIVATE->hCom);
|
||||
PRIVATE->hCom = 0;
|
||||
#else
|
||||
@@ -723,10 +770,11 @@ void PISerial::applySettings() {
|
||||
GetCommMask(PRIVATE->hCom, &PRIVATE->mask);
|
||||
SetCommMask(PRIVATE->hCom, EV_RXCHAR);
|
||||
GetCommState(PRIVATE->hCom, &PRIVATE->sdesc);
|
||||
// piCoutObj << PRIVATE->sdesc.fBinary << PRIVATE->sdesc.fAbortOnError << PRIVATE->sdesc.fDsrSensitivity << PRIVATE->sdesc.fDtrControl << PRIVATE->sdesc.fDummy2 << PRIVATE->sdesc.fErrorChar;
|
||||
PRIVATE->desc = PRIVATE->sdesc;
|
||||
// piCoutObj << PRIVATE->sdesc.fBinary << PRIVATE->sdesc.fAbortOnError << PRIVATE->sdesc.fDsrSensitivity << PRIVATE->sdesc.fDtrControl
|
||||
//<< PRIVATE->sdesc.fDummy2 << PRIVATE->sdesc.fErrorChar;
|
||||
PRIVATE->desc = PRIVATE->sdesc;
|
||||
PRIVATE->desc.DCBlength = sizeof(PRIVATE->desc);
|
||||
PRIVATE->desc.BaudRate = convertSpeed(outSpeed());
|
||||
PRIVATE->desc.BaudRate = convertSpeed(outSpeed());
|
||||
if (dataBitsCount() >= 5 && dataBitsCount() <= 8)
|
||||
PRIVATE->desc.ByteSize = dataBitsCount();
|
||||
else
|
||||
@@ -734,7 +782,7 @@ void PISerial::applySettings() {
|
||||
PIFlags<Parameters> params = parameters();
|
||||
if (params[PISerial::ParityControl]) {
|
||||
PRIVATE->desc.fParity = 1;
|
||||
PRIVATE->desc.Parity = params[PISerial::ParityOdd] ? 1 : 2;
|
||||
PRIVATE->desc.Parity = params[PISerial::ParityOdd] ? 1 : 2;
|
||||
}
|
||||
PRIVATE->desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT;
|
||||
if (SetCommState(PRIVATE->hCom, &PRIVATE->desc) == -1) {
|
||||
@@ -745,13 +793,14 @@ void PISerial::applySettings() {
|
||||
if (fd == -1) return;
|
||||
tcgetattr(fd, &PRIVATE->desc);
|
||||
PRIVATE->desc.c_oflag = PRIVATE->desc.c_lflag = PRIVATE->desc.c_cflag = 0;
|
||||
PRIVATE->desc.c_iflag = IGNBRK;
|
||||
PRIVATE->desc.c_cflag = CLOCAL | HUPCL;
|
||||
PRIVATE->desc.c_iflag = IGNBRK;
|
||||
PRIVATE->desc.c_cflag = CLOCAL | HUPCL;
|
||||
switch (dataBitsCount()) {
|
||||
case 5: PRIVATE->desc.c_cflag |= (CSIZE & CS5); break;
|
||||
case 6: PRIVATE->desc.c_cflag |= (CSIZE & CS6); break;
|
||||
case 7: PRIVATE->desc.c_cflag |= (CSIZE & CS7); break;
|
||||
case 8: default: PRIVATE->desc.c_cflag |= (CSIZE & CS8); break;
|
||||
case 8:
|
||||
default: PRIVATE->desc.c_cflag |= (CSIZE & CS8); break;
|
||||
};
|
||||
if (isReadable()) PRIVATE->desc.c_cflag |= CREAD;
|
||||
PIFlags<Parameters> params = parameters();
|
||||
@@ -761,7 +810,7 @@ void PISerial::applySettings() {
|
||||
PRIVATE->desc.c_cflag |= PARENB;
|
||||
if (params[PISerial::ParityOdd]) PRIVATE->desc.c_cflag |= PARODD;
|
||||
}
|
||||
PRIVATE->desc.c_cc[VMIN] = 1;
|
||||
PRIVATE->desc.c_cc[VMIN] = 1;
|
||||
PRIVATE->desc.c_cc[VTIME] = vtime;
|
||||
|
||||
cfsetispeed(&PRIVATE->desc, convertSpeed(inSpeed()));
|
||||
@@ -781,13 +830,12 @@ void PISerial::applySettings() {
|
||||
void PISerial::setTimeouts() {
|
||||
#ifdef WINDOWS
|
||||
COMMTIMEOUTS times;
|
||||
times.ReadIntervalTimeout = isOptionSet(BlockingRead) ? vtime : MAXDWORD;
|
||||
times.ReadTotalTimeoutConstant = isOptionSet(BlockingRead) ? 0 : 1;
|
||||
times.ReadTotalTimeoutMultiplier = isOptionSet(BlockingRead) ? 0 : MAXDWORD;
|
||||
times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1;
|
||||
times.ReadIntervalTimeout = isOptionSet(BlockingRead) ? vtime : MAXDWORD;
|
||||
times.ReadTotalTimeoutConstant = isOptionSet(BlockingRead) ? 0 : 1;
|
||||
times.ReadTotalTimeoutMultiplier = isOptionSet(BlockingRead) ? 0 : MAXDWORD;
|
||||
times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1;
|
||||
times.WriteTotalTimeoutMultiplier = 0;
|
||||
if (SetCommTimeouts(PRIVATE->hCom, ×) == -1)
|
||||
piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
if (SetCommTimeouts(PRIVATE->hCom, ×) == -1) piCoutObj << "Unable to set timeouts for \"" << path() << "\"";
|
||||
#else
|
||||
fcntl(fd, F_SETFL, isOptionSet(BlockingRead) ? 0 : O_NONBLOCK);
|
||||
#endif
|
||||
@@ -810,54 +858,53 @@ void PISerial::setTimeouts() {
|
||||
//! \~\sa \a readData(), \a readString()
|
||||
ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) {
|
||||
#ifdef WINDOWS
|
||||
if (!canRead()) return -1;
|
||||
if (sending) return -1;
|
||||
//piCoutObj << "read ..." << PRIVATE->hCom;
|
||||
memset(&(PRIVATE->overlap), 0, sizeof(PRIVATE->overlap));
|
||||
PRIVATE->overlap.hEvent = PRIVATE->event.getEvent();
|
||||
ReadFile(PRIVATE->hCom, read_to, max_size, NULL, &(PRIVATE->overlap));
|
||||
PRIVATE->readed = 0;
|
||||
if (PRIVATE->event.wait()) {
|
||||
GetOverlappedResult(PRIVATE->hCom, &(PRIVATE->overlap), &(PRIVATE->readed), FALSE);
|
||||
} else
|
||||
return -1;
|
||||
//piCoutObj << "read done" << PRIVATE->readed;
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_TIMEOUT && PRIVATE->readed == 0)
|
||||
return 0;
|
||||
if (err == ERROR_BAD_COMMAND || err == ERROR_ACCESS_DENIED) {
|
||||
piCoutObj << "read error" << (PRIVATE->readed) << errorString();
|
||||
stop();
|
||||
if (!canRead()) return -1;
|
||||
if (sending) return -1;
|
||||
// piCoutObj << "read ..." << PRIVATE->hCom;
|
||||
memset(&(PRIVATE->overlap), 0, sizeof(PRIVATE->overlap));
|
||||
PRIVATE->overlap.hEvent = PRIVATE->event.getEvent();
|
||||
ReadFile(PRIVATE->hCom, read_to, max_size, NULL, &(PRIVATE->overlap));
|
||||
PRIVATE->readed = 0;
|
||||
if (PRIVATE->event.wait()) {
|
||||
GetOverlappedResult(PRIVATE->hCom, &(PRIVATE->overlap), &(PRIVATE->readed), FALSE);
|
||||
} else
|
||||
return -1;
|
||||
// piCoutObj << "read done" << PRIVATE->readed;
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_TIMEOUT && PRIVATE->readed == 0) return 0;
|
||||
if (err == ERROR_BAD_COMMAND || err == ERROR_ACCESS_DENIED) {
|
||||
piCoutObj << "read error" << (PRIVATE->readed) << errorString();
|
||||
stop();
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
// piCoutObj << "read" << (PRIVATE->readed) << errorString();
|
||||
return PRIVATE->readed;
|
||||
#else
|
||||
if (!canRead()) return -1;
|
||||
if (!PRIVATE->event.wait(fd)) return -1;
|
||||
ssize_t ret = ::read(fd, read_to, max_size);
|
||||
if (ret < 0) {
|
||||
int err = errno;
|
||||
if (err == EBADF || err == EFAULT || err == EINVAL || err == EIO) {
|
||||
stopThreadedRead();
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
//piCoutObj << "read" << (PRIVATE->readed) << errorString();
|
||||
return PRIVATE->readed;
|
||||
#else
|
||||
if (!canRead()) return -1;
|
||||
if (!PRIVATE->event.wait(fd)) return -1;
|
||||
ssize_t ret = ::read(fd, read_to, max_size);
|
||||
if (ret < 0) {
|
||||
int err = errno;
|
||||
if (err == EBADF || err == EFAULT || err == EINVAL || err == EIO) {
|
||||
stopThreadedRead();
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) {
|
||||
if (fd == -1 || !canWrite()) {
|
||||
//piCoutObj << "Can`t write to uninitialized COM";
|
||||
// piCoutObj << "Can`t write to uninitialized COM";
|
||||
return -1;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
DWORD wrote(0);
|
||||
//piCoutObj << "send ..." << max_size;// << ": " << PIString((char*)data, max_size);
|
||||
// piCoutObj << "send ..." << max_size;// << ": " << PIString((char*)data, max_size);
|
||||
sending = true;
|
||||
memset(&(PRIVATE->overlap_write), 0, sizeof(PRIVATE->overlap_write));
|
||||
PRIVATE->overlap_write.hEvent = PRIVATE->event_write.getEvent();
|
||||
@@ -866,20 +913,20 @@ ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) {
|
||||
GetOverlappedResult(PRIVATE->hCom, &(PRIVATE->overlap_write), &wrote, FALSE);
|
||||
}
|
||||
sending = false;
|
||||
//piCoutObj << "send ok" << wrote;// << " bytes in " << path();
|
||||
// piCoutObj << "send ok" << wrote;// << " bytes in " << path();
|
||||
#else
|
||||
ssize_t wrote;
|
||||
wrote = ::write(fd, data, max_size);
|
||||
if (isOptionSet(BlockingWrite)) tcdrain(fd);
|
||||
#endif
|
||||
return (ssize_t)wrote;
|
||||
//piCoutObj << "Error while sending";
|
||||
// piCoutObj << "Error while sending";
|
||||
}
|
||||
|
||||
|
||||
bool PISerial::configureDevice(const void * e_main, const void * e_parent) {
|
||||
PIConfig::Entry * em = (PIConfig::Entry * )e_main;
|
||||
PIConfig::Entry * ep = (PIConfig::Entry * )e_parent;
|
||||
PIConfig::Entry * em = (PIConfig::Entry *)e_main;
|
||||
PIConfig::Entry * ep = (PIConfig::Entry *)e_parent;
|
||||
setDevice(readDeviceSetting<PIString>("device", device(), em, ep));
|
||||
setSpeed((PISerial::Speed)(readDeviceSetting<int>("speed", (int)outSpeed(), em, ep)));
|
||||
setDataBitsCount(readDeviceSetting<int>("dataBitsCount", dataBitsCount(), em, ep));
|
||||
@@ -894,11 +941,16 @@ PIString PISerial::constructFullPathDevice() const {
|
||||
PIString ret;
|
||||
ret += path() + ":" + PIString::fromNumber(int(inSpeed())) + ":" + PIString::fromNumber(dataBitsCount());
|
||||
if (parameters()[ParityControl]) {
|
||||
if (parameters()[ParityOdd]) ret += ":O";
|
||||
else ret += ":E";
|
||||
} else ret += ":N";
|
||||
if (parameters()[TwoStopBits]) ret += ":2";
|
||||
else ret += ":1";
|
||||
if (parameters()[ParityOdd])
|
||||
ret += ":O";
|
||||
else
|
||||
ret += ":E";
|
||||
} else
|
||||
ret += ":N";
|
||||
if (parameters()[TwoStopBits])
|
||||
ret += ":2";
|
||||
else
|
||||
ret += ":1";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -916,14 +968,19 @@ void PISerial::configureFromFullPathDevice(const PIString & full_path) {
|
||||
PIString p(pl[i]);
|
||||
switch (i) {
|
||||
case 0: setProperty("path", p); break;
|
||||
case 1: setProperty("outSpeed", p.toInt()); setProperty("inSpeed", p.toInt()); break;
|
||||
case 1:
|
||||
setProperty("outSpeed", p.toInt());
|
||||
setProperty("inSpeed", p.toInt());
|
||||
break;
|
||||
case 2: setProperty("dataBitsCount", p.toInt()); break;
|
||||
case 3:
|
||||
p = p.left(1).toLowerCase();
|
||||
if (p != "n") setParameter(ParityControl);
|
||||
if (p == "o") setParameter(ParityOdd);
|
||||
break;
|
||||
case 4: if (p.toInt() == 2) setParameter(TwoStopBits); break;
|
||||
case 4:
|
||||
if (p.toInt() == 2) setParameter(TwoStopBits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
applySettings();
|
||||
@@ -936,17 +993,23 @@ PIPropertyStorage PISerial::constructVariantDevice() const {
|
||||
PIVariantTypes::Enum e;
|
||||
|
||||
PIVector<int> as = availableSpeeds();
|
||||
piForeachC (int s, as) {e << PIVariantTypes::Enumerator(s, PIString::fromNumber(s));}
|
||||
piForeachC(int s, as) {
|
||||
e << PIVariantTypes::Enumerator(s, PIString::fromNumber(s));
|
||||
}
|
||||
e.selectValue((int)inSpeed());
|
||||
ret.addProperty("speed", e);
|
||||
|
||||
e = PIVariantTypes::Enum();
|
||||
for (int i = 5; i <= 8; ++i) {e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));}
|
||||
for (int i = 5; i <= 8; ++i) {
|
||||
e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));
|
||||
}
|
||||
e.selectValue(dataBitsCount());
|
||||
ret.addProperty("dataBits", e);
|
||||
|
||||
e = PIVariantTypes::Enum();
|
||||
e << "None" << "Odd" << "Even";
|
||||
e << "None"
|
||||
<< "Odd"
|
||||
<< "Even";
|
||||
if (parameters()[ParityControl]) {
|
||||
if (parameters()[ParityOdd])
|
||||
e.selectValue(1);
|
||||
@@ -957,7 +1020,9 @@ PIPropertyStorage PISerial::constructVariantDevice() const {
|
||||
ret.addProperty("parity", e);
|
||||
|
||||
e = PIVariantTypes::Enum();
|
||||
for (int i = 1; i <= 2; ++i) {e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));}
|
||||
for (int i = 1; i <= 2; ++i) {
|
||||
e << PIVariantTypes::Enumerator(i, PIString::fromNumber(i));
|
||||
}
|
||||
e.selectValue(parameters()[TwoStopBits] ? 2 : 1);
|
||||
ret.addProperty("stopBits", e);
|
||||
return ret;
|
||||
@@ -970,21 +1035,19 @@ void PISerial::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
setDataBitsCount(d.propertyValueByName("dataBits").toEnum().selectedValue());
|
||||
PIVariantTypes::Enum e = d.propertyValueByName("parity").toEnum();
|
||||
setParameter(ParityControl, e.selectedValue() > 0);
|
||||
setParameter(ParityOdd , e.selectedValue() == 1);
|
||||
setParameter(TwoStopBits , d.propertyValueByName("stopBits").toEnum().selectedValue() == 2);
|
||||
setParameter(ParityOdd, e.selectedValue() == 1);
|
||||
setParameter(TwoStopBits, d.propertyValueByName("stopBits").toEnum().selectedValue() == 2);
|
||||
}
|
||||
|
||||
|
||||
PIVector<int> PISerial::availableSpeeds() {
|
||||
PIVector<int> spds;
|
||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 <<
|
||||
9600 <<
|
||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 << 9600 <<
|
||||
#ifdef WINDOWS
|
||||
14400 <<
|
||||
14400 <<
|
||||
#endif
|
||||
19200 << 38400 << 57600 << 115200 << 230400 <<
|
||||
460800 << 500000 << 576000 << 921600 << 1000000 << 1152000 <<
|
||||
1500000 << 2000000 << 2500000 << 3000000 << 3500000 << 4000000;
|
||||
19200 << 38400 << 57600 << 115200 << 230400 << 460800 << 500000 << 576000 << 921600 << 1000000 << 1152000 << 1500000 << 2000000
|
||||
<< 2500000 << 3000000 << 3500000 << 4000000;
|
||||
return spds;
|
||||
}
|
||||
|
||||
@@ -992,7 +1055,7 @@ PIVector<int> PISerial::availableSpeeds() {
|
||||
PIStringList PISerial::availableDevices(bool test) {
|
||||
PIVector<DeviceInfo> devs = availableDevicesInfo(test);
|
||||
PIStringList ret;
|
||||
piForeachC (DeviceInfo & d, devs)
|
||||
piForeachC(DeviceInfo & d, devs)
|
||||
ret << d.path;
|
||||
return ret;
|
||||
}
|
||||
@@ -1002,15 +1065,11 @@ PIStringList PISerial::availableDevices(bool test) {
|
||||
PIString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) {
|
||||
PIString ret;
|
||||
const HKEY key = SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
|
||||
if (key == INVALID_HANDLE_VALUE)
|
||||
return ret;
|
||||
static const wchar_t * const keyTokens[] = {
|
||||
L"PortName\0",
|
||||
L"PortNumber\0"
|
||||
};
|
||||
static const int keys_count = sizeof(keyTokens) / sizeof(keyTokens[0]);
|
||||
if (key == INVALID_HANDLE_VALUE) return ret;
|
||||
static const wchar_t * const keyTokens[] = {L"PortName\0", L"PortNumber\0"};
|
||||
static const int keys_count = sizeof(keyTokens) / sizeof(keyTokens[0]);
|
||||
for (int i = 0; i < keys_count; ++i) {
|
||||
DWORD dataType = 0;
|
||||
DWORD dataType = 0;
|
||||
DWORD bytesRequired = MAX_PATH;
|
||||
PIVector<wchar_t> outputBuffer(MAX_PATH + 1);
|
||||
for (;;) {
|
||||
@@ -1026,8 +1085,7 @@ PIString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ret.isEmpty())
|
||||
break;
|
||||
if (!ret.isEmpty()) break;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return ret;
|
||||
@@ -1035,14 +1093,19 @@ PIString devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData)
|
||||
|
||||
|
||||
PIString deviceRegistryProperty(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData, DWORD property) {
|
||||
DWORD dataType = 0;
|
||||
DWORD dataType = 0;
|
||||
DWORD bytesRequired = MAX_PATH;
|
||||
PIVector<wchar_t> outputBuffer(MAX_PATH + 1);
|
||||
for (;;) {
|
||||
if (SetupDiGetDeviceRegistryPropertyW(deviceInfoSet, deviceInfoData, property, &dataType, (PBYTE)outputBuffer.data(), bytesRequired, &bytesRequired))
|
||||
if (SetupDiGetDeviceRegistryPropertyW(deviceInfoSet,
|
||||
deviceInfoData,
|
||||
property,
|
||||
&dataType,
|
||||
(PBYTE)outputBuffer.data(),
|
||||
bytesRequired,
|
||||
&bytesRequired))
|
||||
break;
|
||||
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dataType != REG_SZ && dataType != REG_EXPAND_SZ))
|
||||
return PIString();
|
||||
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) return PIString();
|
||||
outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0);
|
||||
}
|
||||
return PIString(outputBuffer.data());
|
||||
@@ -1073,20 +1136,20 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
PIVector<DeviceInfo> ret;
|
||||
DeviceInfo di;
|
||||
#ifdef WINDOWS
|
||||
static const GUID guids[] = {GUID_DEVINTERFACE_MODEM, GUID_DEVINTERFACE_COMPORT};
|
||||
static const GUID guids[] = {GUID_DEVINTERFACE_MODEM, GUID_DEVINTERFACE_COMPORT};
|
||||
static const int guids_cnt = sizeof(guids) / sizeof(GUID);
|
||||
for (int i = 0; i < guids_cnt; ++i) {
|
||||
const HDEVINFO dis = SetupDiGetClassDevs(&(guids[i]), NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if (dis == INVALID_HANDLE_VALUE) continue;
|
||||
SP_DEVINFO_DATA did;
|
||||
memset(&did, 0, sizeof(did));
|
||||
did.cbSize = sizeof(did);
|
||||
did.cbSize = sizeof(did);
|
||||
DWORD index = 0;
|
||||
while (SetupDiEnumDeviceInfo(dis, index++, &did)) {
|
||||
di = DeviceInfo();
|
||||
di = DeviceInfo();
|
||||
di.path = devicePortName(dis, &did);
|
||||
if (!di.path.startsWith("COM")) continue;
|
||||
di.description = deviceRegistryProperty(dis, &did, SPDRP_DEVICEDESC);
|
||||
di.description = deviceRegistryProperty(dis, &did, SPDRP_DEVICEDESC);
|
||||
di.manufacturer = deviceRegistryProperty(dis, &did, SPDRP_MFG);
|
||||
PIString id_str = deviceInstanceIdentifier(did.DevInst);
|
||||
if (!parseID(id_str, di)) {
|
||||
@@ -1097,25 +1160,34 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
}
|
||||
}
|
||||
ret << di;
|
||||
//piCout << "dev" << did.DevInst << di;
|
||||
// piCout << "dev" << did.DevInst << di;
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(dis);
|
||||
}
|
||||
#else
|
||||
# ifndef ANDROID
|
||||
PIStringList prefixes;
|
||||
# ifdef QNX
|
||||
# ifdef QNX
|
||||
prefixes << "ser";
|
||||
# else
|
||||
prefixes << "ttyS" << "ttyO" << "ttyUSB" << "ttyACM" << "ttyGS"
|
||||
<< "ttyMI" << "ttymxc" << "ttyAMA" << "rfcomm" << "ircomm";
|
||||
# ifdef FREE_BSD
|
||||
# else
|
||||
prefixes << "ttyS"
|
||||
<< "ttyO"
|
||||
<< "ttyUSB"
|
||||
<< "ttyACM"
|
||||
<< "ttyGS"
|
||||
<< "ttyMI"
|
||||
<< "ttymxc"
|
||||
<< "ttyAMA"
|
||||
<< "rfcomm"
|
||||
<< "ircomm";
|
||||
# ifdef FREE_BSD
|
||||
prefixes << "cu";
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
# endif
|
||||
# ifdef MAC_OS
|
||||
prefixes.clear();
|
||||
prefixes << "cu." << "tty.";
|
||||
# endif
|
||||
prefixes << "cu."
|
||||
<< "tty.";
|
||||
# endif
|
||||
PIFile file_prefixes("/proc/tty/drivers", PIIODevice::ReadOnly);
|
||||
if (file_prefixes.open()) {
|
||||
PIString fc = file_prefixes.readAll(true), line, cpref;
|
||||
@@ -1129,45 +1201,40 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
words << line.takeWord();
|
||||
if (words.size_s() < 2) break;
|
||||
if (words.back() != "serial") continue;
|
||||
cpref = words[1];
|
||||
cpref = words[1];
|
||||
int li = cpref.findLast("/");
|
||||
if (li > 0) cpref.cutLeft(li + 1);
|
||||
prefixes << cpref;
|
||||
}
|
||||
prefixes.removeDuplicates();
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
PIDir dir("/dev");
|
||||
PIVector<PIFile::FileInfo> de = dir.entries();
|
||||
# ifdef LINUX
|
||||
# ifdef LINUX
|
||||
char linkbuf[1024];
|
||||
# endif
|
||||
piForeachC (PIFile::FileInfo & e, de) { // TODO changes in FileInfo
|
||||
piForeachC (PIString & p, prefixes) {
|
||||
# endif
|
||||
piForeachC(PIFile::FileInfo & e, de) { // TODO changes in FileInfo
|
||||
piForeachC(PIString & p, prefixes) {
|
||||
if (e.name().startsWith(p)) {
|
||||
di = DeviceInfo();
|
||||
di.path = e.path;
|
||||
# ifdef LINUX
|
||||
di = DeviceInfo();
|
||||
di.path = e.path;
|
||||
# ifdef LINUX
|
||||
ssize_t lsz = readlink(("/sys/class/tty/" + e.name()).dataAscii(), linkbuf, 1024);
|
||||
if (lsz > 0) {
|
||||
PIString fpath = "/sys/class/tty/" + PIString(linkbuf, lsz) + "/";
|
||||
PIFile _f;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
fpath += "../";
|
||||
//piCout << "try" << fpath;
|
||||
if (_f.open(fpath + "idVendor", PIIODevice::ReadOnly))
|
||||
di.vID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "idProduct", PIIODevice::ReadOnly))
|
||||
di.pID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "product", PIIODevice::ReadOnly))
|
||||
di.description = PIString(_f.readAll()).trim();
|
||||
if (_f.open(fpath + "manufacturer", PIIODevice::ReadOnly))
|
||||
di.manufacturer = PIString(_f.readAll()).trim();
|
||||
if (di.pID > 0)
|
||||
break;
|
||||
// piCout << "try" << fpath;
|
||||
if (_f.open(fpath + "idVendor", PIIODevice::ReadOnly)) di.vID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "idProduct", PIIODevice::ReadOnly)) di.pID = PIString(_f.readAll()).trim().toInt(16);
|
||||
if (_f.open(fpath + "product", PIIODevice::ReadOnly)) di.description = PIString(_f.readAll()).trim();
|
||||
if (_f.open(fpath + "manufacturer", PIIODevice::ReadOnly)) di.manufacturer = PIString(_f.readAll()).trim();
|
||||
if (di.pID > 0) break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
ret << di;
|
||||
}
|
||||
}
|
||||
@@ -1177,7 +1244,13 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
if (test) {
|
||||
for (int i = 0; i < ret.size_s(); ++i) {
|
||||
#ifdef WINDOWS
|
||||
void * hComm = CreateFileA(ret[i].path.dataAscii(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
|
||||
void * hComm = CreateFileA(ret[i].path.dataAscii(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
|
||||
0);
|
||||
if (hComm == INVALID_HANDLE_VALUE) {
|
||||
#else
|
||||
int fd = ::open(ret[i].path.dataAscii(), O_NOCTTY | O_RDONLY);
|
||||
@@ -1191,9 +1264,8 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
||||
#ifndef WINDOWS
|
||||
int void_ = 0;
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
if (::read(fd, &void_, 1) == -1)
|
||||
rok = errno != EIO;
|
||||
|
||||
if (::read(fd, &void_, 1) == -1) rok = errno != EIO;
|
||||
|
||||
#endif
|
||||
if (!rok) {
|
||||
ret.remove(i);
|
||||
@@ -1221,9 +1293,9 @@ void PISerial::threadedReadBufferSizeChanged() {
|
||||
#if defined(LINUX)
|
||||
serial_struct ss;
|
||||
ioctl(fd, TIOCGSERIAL, &ss);
|
||||
//piCoutObj << "b" << ss.xmit_fifo_size;
|
||||
// piCoutObj << "b" << ss.xmit_fifo_size;
|
||||
ss.xmit_fifo_size = piMaxi(threadedReadBufferSize(), 4096);
|
||||
ioctl(fd, TIOCSSERIAL, &ss);
|
||||
//piCoutObj << "a" << ss.xmit_fifo_size;
|
||||
// piCoutObj << "a" << ss.xmit_fifo_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user