summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-console/io_serial.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-console/io_serial.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/io_serial.cpp155
1 files changed, 153 insertions, 2 deletions
diff --git a/noncore/apps/opie-console/io_serial.cpp b/noncore/apps/opie-console/io_serial.cpp
index 42c86b5..9a81de9 100644
--- a/noncore/apps/opie-console/io_serial.cpp
+++ b/noncore/apps/opie-console/io_serial.cpp
@@ -1,12 +1,163 @@
1#include <fcntl.h>
2#include <termios.h>
3#include <errno.h>
4#include <unistd.h>
1#include "io_serial.h" 5#include "io_serial.h"
2 6
3IOSerial::IOSerial(const Config &config) : IOLayer(config) { 7IOSerial::IOSerial(const Config &config) : IOLayer(config) {
8 m_fd = 0;
9 reload(config);
4} 10}
5 11
6 12
7void IOSerial::error(int number, const QString &error) { 13IOSerial::~IOSerial() {
14 if (m_fd) {
15 close();
16 }
8} 17}
9 18
10void IOSerial::received(const QByteArray &array) { 19void IOSerial::send(const QByteArray &data) {
20 if (m_fd) {
21 write(m_fd, data.data(), data.size());
22 } else {
23 emit error(Refuse, tr("Not connected"));
24 }
11} 25}
12 26
27void IOSerial::close() {
28 if (m_fd) {
29 delete m_read;
30 delete m_error;
31 ::close(m_fd);
32 m_fd = 0;
33 } else {
34 emit error(Refuse, tr("Not connected"));
35 }
36}
37
38bool IOSerial::open() {
39 if (!m_fd) {
40 struct termios tty;
41 m_fd = ::open(m_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
42 if (m_fd < 0) {
43 emit error(CouldNotOpen, strerror(errno));
44 return FALSE;
45 }
46 tcgetattr(m_fd, &tty);
47
48 /* Baud rate */
49 int speed = getBaud(m_baud);
50 if (speed == -1) {
51 emit error(Refuse, tr("Invalid baud rate"));
52 }
53 cfsetospeed(&tty, speed);
54 cfsetispeed(&tty, speed);
55
56 /* Take care of Space / Mark parity */
57 if (m_dbits == 7 && (m_parity == ParitySpace || m_parity == ParityMark)) {
58 m_dbits = 8;
59 }
60
61 /* Data bits */
62 switch (m_dbits) {
63 case 5: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5; break;
64 case 6: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6; break;
65 case 7: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7; break;
66 case 8: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; break;
67 }
68
69 /* Raw, no echo mode */
70 tty.c_iflag = IGNBRK;
71 tty.c_lflag = 0;
72 tty.c_oflag = 0;
73 tty.c_cflag |= CLOCAL | CREAD;
74
75 /* Stop bits */
76 if (m_sbits == 2) {
77 tty.c_cflag |= CSTOPB;
78 } else {
79 tty.c_cflag &= ~CSTOPB;
80 }
81
82 tty.c_cc[VMIN] = 1;
83 tty.c_cc[VTIME] = 5;
84
85 /* Flow control */
86 if (m_flow & FlowSW)
87 tty.c_iflag |= IXON | IXOFF;
88 else
89 tty.c_iflag &= ~(IXON|IXOFF|IXANY);
90
91 if (m_flow & FlowHW)
92 tty.c_cflag |= CRTSCTS;
93 else
94 tty.c_cflag &= ~CRTSCTS;
95
96 /* Parity */
97 tty.c_cflag &= ~(PARENB | PARODD);
98 if (m_parity & ParityEven)
99 tty.c_cflag |= PARENB;
100 else if (m_parity & ParityOdd)
101 tty.c_cflag |= (PARENB | PARODD);
102
103 /* Set the changes */
104 tcsetattr(m_fd, TCSANOW, &tty);
105
106 /* Notifications on read & errors */
107 m_read = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
108 m_error = new QSocketNotifier(m_fd, QSocketNotifier::Exception, this);
109 connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived()));
110 connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured()));
111 return TRUE;
112 } else {
113 emit error(Refuse, tr("Device is already connected"));
114 return FALSE;
115 }
116}
117
118void IOSerial::reload(const Config &config) {
119 m_device = config.readEntry("Device", SERIAL_DEFAULT_DEVICE);
120 m_baud = config.readNumEntry("Baud", SERIAL_DEFAULT_BAUD);
121}
122
123int IOSerial::getBaud(int baud) const {
124 switch (baud) {
125 case 300: return B300; break;
126 case 600: return B600; break;
127 case 1200: return B1200; break;
128 case 2400: return B2400; break;
129 case 4800: return B4800; break;
130 case 9600: return B9600; break;
131 case 19200: return B19200; break;
132 case 38400: return B38400; break;
133 case 57600: return B57600; break;
134 case 115200: return B115200; break;
135 }
136 return -1;
137}
138
139void IOSerial::errorOccured() {
140 emit error(ClosedUnexpected, strerror(errno));
141 close();
142}
143
144void IOSerial::dataArrived() {
145 QByteArray array;
146 char buf[4096];
147
148 int len = read(m_fd, buf, 4096);
149 if (len == 0)
150 close();
151 if (len < 0)
152 return;
153 array.setRawData(buf, len);
154 emit received(array);
155}
156
157QString IOSerial::identifier() const {
158 return "serial";
159}
160
161QString IOSerial::name() const {
162 return "RS232 Serial IO Layer";
163}