/* PIP - Platform Independent Primitives COM Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PISERIAL_H #define PISERIAL_H #include "pitimer.h" #include "piiodevice.h" #ifndef WINDOWS # include # include # include # ifndef B50 # define B50 0000001 # endif # ifndef B50 # define B75 0000002 # endif # ifndef B1500000 # define B1500000 0010012 # endif # ifndef B2000000 # define B2000000 0010013 # endif # ifndef B2500000 # define B2500000 0010014 # endif # ifndef B3000000 # define B3000000 0010015 # endif # ifndef B3500000 # define B3500000 0010016 # endif # ifndef B4000000 # define B4000000 0010017 # endif #else # 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 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 B128000 128000 # define B256000 256000 # define B1500000 1500000 # define B2000000 2000000 # define B2500000 2500000 # define B3000000 3000000 # define B3500000 3500000 # define B4000000 4000000 #endif class PISerial: public PIIODevice { public: // slot is any function format "bool (void*, uchar*, int)" // slot_header is any function format "bool (void*, uchar*, uchar*, int)" PISerial(const PIString & device, void * data = 0, ReadRetFunc slot = 0); PISerial(void * data = 0, ReadRetFunc slot = 0); ~PISerial(); enum Parameters {ParityControl = 0x1, ParityOdd = 0x2, TwoStopBits = 0x4, HardwareFlowControl = 0x8}; enum Speed { S50 = 50, S75 = 75, S110 = 110, S300 = 300, S600 = 600, S1200 = 1200, S2400 = 2400, S4800 = 4800, S9600 = 9600, S19200 = 19200, S38400 = 38400, S57600 = 57600, S115200 = 115200, S1500000 = 1500000, // Linux only S2000000 = 2000000, // Linux only S2500000 = 2500000, // Linux only S3000000 = 3000000, // Linux only S3500000 = 3500000, // Linux only S4000000 = 4000000 // Linux only }; void setData(void * d) {data = d;} //void setSlot(SerialFunc func) {ret_func = func;} void setSpeed(PISerial::Speed speed) {ospeed = ispeed = speed;} void setOutSpeed(PISerial::Speed speed) {ospeed = speed;} void setInSpeed(PISerial::Speed speed) {ispeed = speed;} void setDevice(const PIString & dev) {path_ = dev;} void setParameters(PIFlags parameters_) {params = parameters_;} void setParameter(PISerial::Parameters parameter, bool on = true) {params.setFlag(parameter, on);} bool isParameterSet(PISerial::Parameters parameter) const {return params[parameter];} PIFlags parameters() const {return params;} bool setPin(int number, bool on); bool isPin(int number) const; bool setLE(bool on) {return setBit(TIOCM_LE, on, "LE");} // useless function, just formally bool setDTR(bool on) {return setBit(TIOCM_DTR, on, "DTR");} bool setRTS(bool on) {return setBit(TIOCM_RTS, on, "RTS");} bool setCTS(bool on) {return setBit(TIOCM_CTS, on, "CTS");} // useless function, just formally bool setST(bool on) {return setBit(TIOCM_ST, on, "ST");} // useless function, just formally bool setSR(bool on) {return setBit(TIOCM_SR, on, "SR");} // useless function, just formally bool setCAR(bool on) {return setBit(TIOCM_CAR, on, "CAR");} // useless function, just formally bool setRNG(bool on) {return setBit(TIOCM_RNG, on, "RNG");} // useless function, just formally bool setDSR(bool on) {return setBit(TIOCM_DSR, on, "DSR");} // useless function, just formally bool isLE() const {return isBit(TIOCM_LE, "LE");} bool isDTR() const {return isBit(TIOCM_DTR, "DTR");} bool isRTS() const {return isBit(TIOCM_RTS, "RTS");} bool isCTS() const {return isBit(TIOCM_CTS, "CTS");} bool isST() const {return isBit(TIOCM_ST, "ST");} bool isSR() const {return isBit(TIOCM_SR, "SR");} bool isCAR() const {return isBit(TIOCM_CAR, "CAR");} bool isRNG() const {return isBit(TIOCM_RNG, "RNG");} bool isDSR() const {return isBit(TIOCM_DSR, "DSR");} void setVTime(int t) {vtime = t;} void setReadIsBlocking(bool yes) { #ifdef WINDOWS COMMTIMEOUTS times; times.ReadIntervalTimeout = yes ? vtime : MAXDWORD; times.ReadTotalTimeoutConstant = yes ? 1 : 0; times.ReadTotalTimeoutMultiplier = 0; times.WriteTotalTimeoutConstant = 1; times.WriteTotalTimeoutMultiplier = 0; if (isOpened()) SetCommTimeouts(hCom, ×); #else if (isOpened()) fcntl(fd, F_SETFL, yes ? 0 : O_NONBLOCK); #endif } const PIString & device() const {return path_;} PISerial::Speed outSpeed() const {return ospeed;} PISerial::Speed inSpeed() const {return ispeed;} int VTime() const {return vtime;} #ifndef WINDOWS void flush() {if (fd != -1) tcflush(fd, TCIOFLUSH);} #endif int read(void * read_to, int max_size) { #ifdef WINDOWS if (!canRead()) return -1; WaitCommEvent(hCom, 0, 0); ReadFile(hCom, read_to, max_size, &readed, 0); return readed; #else if (!canRead()) return -1; return ::read(fd, read_to, max_size); #endif } bool read(void * data, int size, double timeout_ms); PIString read(int size = -1, double timeout_ms = 1000.); PIByteArray readData(int size = -1, double timeout_ms = 1000.); int write(const void * data, int max_size, bool wait); int write(const void * data, int max_size) {return write(data, max_size, false);} bool send(const void * data, int size, bool wait = false) {return (write(data, size, wait) == size);} bool send(const PIString & data, bool wait = false) {return (write(data.data(), data.lengthAscii(), wait) == data.size_s());} bool send(const PIByteArray & data, bool wait = false) {return (write(data.data(), data.size_s(), wait) == data.size_s());} protected: virtual void received(void * data, int size) {;} int convertSpeed(PISerial::Speed speed); bool setBit(int bit, bool on, const PIString & bname); bool isBit(int bit, const PIString & bname) const; static bool headerValidate(void * d, uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} bool openDevice(); bool closeDevice(); #ifdef WINDOWS DCB desc, sdesc; void * hCom; DWORD readed, mask; #else termios desc, sdesc; uint readed; #endif int fd, vtime; PISerial::Speed ospeed, ispeed; PITimer timer; void * headerPtr, * data; PIFlags params; }; #endif // PISERIAL_H