Lely core libraries 1.9.2
attr.c
Go to the documentation of this file.
1
24#include "attr.h"
25#include "io.h"
26#include <lely/util/errnum.h>
27
28#include <assert.h>
29
30#if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
31
32int
34{
35 assert(attr);
36
37#ifdef _WIN32
38 return io_attr_lpDCB(attr)->BaudRate;
39#else
40 switch (cfgetospeed((const struct termios *)attr)) {
41 case B0: return 0;
42 case B50: return 50;
43 case B75: return 75;
44 case B110: return 110;
45 case B134: return 134;
46 case B150: return 150;
47 case B200: return 200;
48 case B300: return 300;
49 case B600: return 600;
50 case B1200: return 1200;
51 case B1800: return 1800;
52 case B2400: return 2400;
53 case B4800: return 4800;
54 case B9600: return 9600;
55 case B19200: return 19200;
56 case B38400: return 38400;
57#ifdef B7200
58 case B7200: return 7200;
59#endif
60#ifdef B14400
61 case B14400: return 14400;
62#endif
63#ifdef B57600
64 case B57600: return 57600;
65#endif
66#ifdef B115200
67 case B115200: return 115200;
68#endif
69#ifdef B230400
70 case B230400: return 230400;
71#endif
72#ifdef B460800
73 case B460800: return 460800;
74#endif
75#ifdef B500000
76 case B500000: return 500000;
77#endif
78#ifdef B576000
79 case B576000: return 576000;
80#endif
81#ifdef B921600
82 case B921600: return 921600;
83#endif
84#ifdef B1000000
85 case B1000000: return 1000000;
86#endif
87#ifdef B1152000
88 case B1152000: return 1152000;
89#endif
90#ifdef B2000000
91 case B2000000: return 2000000;
92#endif
93#ifdef B3000000
94 case B3000000: return 3000000;
95#endif
96#ifdef B3500000
97 case B3500000: return 3500000;
98#endif
99#ifdef B4000000
100 case B4000000: return 4000000;
101#endif
102 default: set_errnum(ERRNUM_INVAL); return -1;
103 }
104#endif
105}
106
107int
109{
110 assert(attr);
111
112#ifdef _WIN32
113 io_attr_lpDCB(attr)->BaudRate = speed;
114
115 return 0;
116#else
117 speed_t baud;
118 switch (speed) {
119 case 0: baud = B0; break;
120 case 50: baud = B50; break;
121 case 75: baud = B75; break;
122 case 110: baud = B110; break;
123 case 134: baud = B134; break;
124 case 150: baud = B150; break;
125 case 200: baud = B200; break;
126 case 300: baud = B300; break;
127 case 600: baud = B600; break;
128 case 1200: baud = B1200; break;
129 case 1800: baud = B1800; break;
130 case 2400: baud = B2400; break;
131 case 4800: baud = B4800; break;
132 case 9600: baud = B9600; break;
133 case 19200: baud = B19200; break;
134 case 38400: baud = B38400; break;
135#ifdef B7200
136 case 7200: baud = B7200; break;
137#endif
138#ifdef B14400
139 case 14400: baud = B14400; break;
140#endif
141#ifdef B57600
142 case 57600: baud = B57600; break;
143#endif
144#ifdef B115200
145 case 115200: baud = B115200; break;
146#endif
147#ifdef B230400
148 case 230400: baud = B230400; break;
149#endif
150#ifdef B460800
151 case 460800: baud = B460800; break;
152#endif
153#ifdef B500000
154 case 500000: baud = B500000; break;
155#endif
156#ifdef B576000
157 case 576000: baud = B576000; break;
158#endif
159#ifdef B921600
160 case 921600: baud = B921600; break;
161#endif
162#ifdef B1000000
163 case 1000000: baud = B1000000; break;
164#endif
165#ifdef B1152000
166 case 1152000: baud = B1152000; break;
167#endif
168#ifdef B2000000
169 case 2000000: baud = B2000000; break;
170#endif
171#ifdef B3000000
172 case 3000000: baud = B3000000; break;
173#endif
174#ifdef B3500000
175 case 3500000: baud = B3500000; break;
176#endif
177#ifdef B4000000
178 case 4000000: baud = B4000000; break;
179#endif
180 default: set_errnum(ERRNUM_INVAL); return -1;
181 }
182
183 if (__unlikely(cfsetispeed((struct termios *)attr, baud) == -1))
184 return -1;
185 if (__unlikely(cfsetospeed((struct termios *)attr, baud) == -1))
186 return -1;
187
188 return 0;
189#endif
190}
191
192int
194{
195 assert(attr);
196
197#ifdef _WIN32
198 LPDCB lpDCB = io_attr_lpDCB(attr);
199 return lpDCB->fOutX || lpDCB->fInX;
200#else
201 return !!(((const struct termios *)attr)->c_iflag & (IXOFF | IXON));
202#endif
203}
204
205int
206io_attr_set_flow_control(io_attr_t *attr, int flow_control)
207{
208 assert(attr);
209
210#ifdef _WIN32
211 LPDCB lpDCB = io_attr_lpDCB(attr);
212 lpDCB->fOutxCtsFlow = FALSE;
213 lpDCB->fOutxDsrFlow = FALSE;
214 lpDCB->fDtrControl = DTR_CONTROL_ENABLE;
215 lpDCB->fRtsControl = RTS_CONTROL_ENABLE;
216 if (flow_control) {
217 lpDCB->fOutX = TRUE;
218 lpDCB->fInX = TRUE;
219 } else {
220 lpDCB->fOutX = FALSE;
221 lpDCB->fInX = FALSE;
222 }
223
224 return 0;
225#else
226 struct termios *ios = (struct termios *)attr;
227 if (flow_control)
228 ios->c_iflag |= IXOFF | IXON;
229 else
230 ios->c_iflag &= ~(IXOFF | IXON);
231
232 return 0;
233#endif
234}
235
236int
238{
239 assert(attr);
240
241#ifdef _WIN32
242 switch (io_attr_lpDCB(attr)->Parity) {
243 case EVENPARITY: return IO_PARITY_EVEN;
244 case ODDPARITY: return IO_PARITY_ODD;
245 default: return IO_PARITY_NONE;
246 }
247#else
248 const struct termios *ios = (const struct termios *)attr;
249 if (ios->c_cflag & PARENB)
250 return (ios->c_cflag & PARODD) ? IO_PARITY_ODD : IO_PARITY_EVEN;
251 return IO_PARITY_NONE;
252#endif
253}
254
255int
257{
258 assert(attr);
259
260#ifdef _WIN32
261 LPDCB lpDCB = io_attr_lpDCB(attr);
262 switch (parity) {
263 case IO_PARITY_NONE:
264 lpDCB->fParity = FALSE;
265 lpDCB->Parity = NOPARITY;
266 return 0;
267 case IO_PARITY_ODD:
268 lpDCB->fParity = TRUE;
269 lpDCB->Parity = ODDPARITY;
270 return 0;
271 case IO_PARITY_EVEN:
272 lpDCB->fParity = TRUE;
273 lpDCB->Parity = EVENPARITY;
274 return 0;
275 default: set_errnum(ERRNUM_INVAL); return -1;
276 }
277#else
278 struct termios *ios = (struct termios *)attr;
279 switch (parity) {
280 case IO_PARITY_NONE:
281 ios->c_iflag |= IGNPAR;
282 ios->c_cflag &= ~(PARENB | PARODD);
283 return 0;
284 case IO_PARITY_ODD:
285 ios->c_iflag &= ~(IGNPAR | PARMRK);
286 ios->c_iflag |= INPCK;
287 ios->c_cflag |= PARENB;
288 ios->c_cflag &= ~PARODD;
289 return 0;
290 case IO_PARITY_EVEN:
291 ios->c_iflag &= ~(IGNPAR | PARMRK);
292 ios->c_iflag |= INPCK;
293 ios->c_cflag |= (PARENB | PARODD);
294 return 0;
295 default: set_errnum(ERRNUM_INVAL); return -1;
296 }
297#endif
298}
299
300int
302{
303 assert(attr);
304
305#ifdef _WIN32
306 return io_attr_lpDCB(attr)->StopBits == TWOSTOPBITS;
307#else
308 return !!(((const struct termios *)attr)->c_cflag & CSTOPB);
309#endif
310}
311
312int
313io_attr_set_stop_bits(io_attr_t *attr, int stop_bits)
314{
315 assert(attr);
316
317#ifdef _WIN32
318 LPDCB lpDCB = io_attr_lpDCB(attr);
319 if (stop_bits)
320 lpDCB->StopBits = TWOSTOPBITS;
321 else
322 lpDCB->StopBits = ONESTOPBIT;
323
324 return 0;
325#else
326 struct termios *ios = (struct termios *)attr;
327 if (stop_bits)
328 ios->c_cflag |= CSTOPB;
329 else
330 ios->c_cflag &= ~CSTOPB;
331
332 return 0;
333#endif
334}
335
336int
338{
339 assert(attr);
340
341#ifdef _WIN32
342 return io_attr_lpDCB(attr)->ByteSize;
343#else
344 switch (((const struct termios *)attr)->c_cflag & CSIZE) {
345 case CS5: return 5;
346 case CS6: return 6;
347 case CS7: return 7;
348 case CS8: return 8;
349 default: set_errnum(ERRNUM_INVAL); return -1;
350 }
351#endif
352}
353
354int
355io_attr_set_char_size(io_attr_t *attr, int char_size)
356{
357 assert(attr);
358
359#ifdef _WIN32
360 io_attr_lpDCB(attr)->ByteSize = char_size;
361
362 return 0;
363#else
364 struct termios *ios = (struct termios *)attr;
365 ios->c_cflag &= ~CSIZE;
366 switch (char_size) {
367 case 5: ios->c_cflag |= CS5; return 0;
368 case 6: ios->c_cflag |= CS6; return 0;
369 case 7: ios->c_cflag |= CS7; return 0;
370 case 8: ios->c_cflag |= CS8; return 0;
371 default: set_errnum(ERRNUM_INVAL); return -1;
372 }
373#endif
374}
375
376#endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
int io_attr_get_char_size(const io_attr_t *attr)
Obtains the character size (in bits) from the attributes of a serial I/O device.
Definition: attr.c:337
int io_attr_get_flow_control(const io_attr_t *attr)
Checks if flow control is enabled in the attributes of a serial I/O device.
Definition: attr.c:193
int io_attr_set_parity(io_attr_t *attr, int parity)
Sets the parity scheme of a serial I/O device.
Definition: attr.c:256
int io_attr_get_speed(const io_attr_t *attr)
Returns the baud rate from the attributes of a serial I/O device, or -1 on error.
Definition: attr.c:33
int io_attr_set_flow_control(io_attr_t *attr, int flow_control)
Disables flow control for a serial I/O device if flow_control is zero, and enables it otherwise.
Definition: attr.c:206
int io_attr_set_stop_bits(io_attr_t *attr, int stop_bits)
Sets the number of stop bits used in a serial I/O device to one if stop_bits is zero,...
Definition: attr.c:313
int io_attr_set_speed(io_attr_t *attr, int speed)
Sets the baud rate of a serial I/O device.
Definition: attr.c:108
int io_attr_get_parity(const io_attr_t *attr)
Obtains the parity scheme from the attributes of a serial I/O device.
Definition: attr.c:237
int io_attr_get_stop_bits(const io_attr_t *attr)
Obtains the number of stop bits used from the attributes of a serial I/O device.
Definition: attr.c:301
int io_attr_set_char_size(io_attr_t *attr, int char_size)
Sets the character size (in bits) of a serial I/O device.
Definition: attr.c:355
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_INVAL
Invalid argument.
Definition: errnum.h:129
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
Definition: features.h:286
@ IO_PARITY_NONE
No parity.
Definition: attr.h:50
@ IO_PARITY_ODD
Odd parity.
Definition: attr.h:52
@ IO_PARITY_EVEN
Even parity.
Definition: attr.h:54
This is the internal header file of the serial I/O attributes declarations.
This is the internal header file of the I/O library.
An opaque serial I/O device attributes type.
Definition: attr.h:34