1 // Copyright (c) 1999-2018 David Muse
2 // See the COPYING file for more information
3 
4 #include <rudiments/serialportprofile.h>
5 #include <rudiments/bytestring.h>
6 #include <rudiments/character.h>
7 #include <rudiments/charstring.h>
8 #include <rudiments/error.h>
9 
10 #ifdef RUDIMENTS_HAVE_UNISTD_H
11 	#include <unistd.h>
12 #endif
13 #include <stdio.h>
14 
15 class serialportprofileprivate {
16 	friend class serialportprofile;
17 	private:
18 		termios	_tio;
19 };
20 
serialportprofile()21 serialportprofile::serialportprofile() {
22 	pvt=new serialportprofileprivate;
23 	defaultOptions();
24 }
25 
~serialportprofile()26 serialportprofile::~serialportprofile() {
27 	delete pvt;
28 }
29 
setControlCharacters(const unsigned char * c_cc)30 void serialportprofile::setControlCharacters(const unsigned char *c_cc) {
31 	bytestring::copy(&pvt->_tio.c_cc,c_cc,sizeof(unsigned char)*NCCS);
32 }
33 
defaultControlOptions()34 void serialportprofile::defaultControlOptions() {
35 	pvt->_tio.c_cflag=0;
36 }
37 
defaultLocalOptions()38 void serialportprofile::defaultLocalOptions() {
39 	pvt->_tio.c_lflag=0;
40 }
41 
defaultInputOptions()42 void serialportprofile::defaultInputOptions() {
43 	pvt->_tio.c_iflag=0;
44 }
45 
defaultOutputOptions()46 void serialportprofile::defaultOutputOptions() {
47 	pvt->_tio.c_oflag=0;
48 }
49 
defaultControlCharacters()50 void serialportprofile::defaultControlCharacters() {
51 	bytestring::zero(&pvt->_tio.c_cc,sizeof(pvt->_tio.c_cc));
52 }
53 
defaultOptions()54 void serialportprofile::defaultOptions() {
55 	bytestring::zero(&pvt->_tio,sizeof(pvt->_tio));
56 }
57 
58 static tcflag_t	br[]={
59 	B0,
60 	B50,
61 	B75,
62 	B110,
63 	B134,
64 	B150,
65 	B200,
66 	B300,
67 	B600,
68 	B1200,
69 	B1800,
70 	B2400,
71 	B4800,
72 	B9600,
73 	#if defined(B19200)
74 	B19200,
75 	#elif defined(EXTA)
76 	EXTA,
77 	#endif
78 	#if defined(B38400)
79 	B38400,
80 	#elif defined(EXTB)
81 	EXTB,
82 	#endif
83 	#ifdef B57600
84 	B57600,
85 	#endif
86 	#ifdef B76800
87 	B76800,
88 	#endif
89 	#ifdef B115200
90 	B115200,
91 	#endif
92 	#ifdef B230400
93 	B230400,
94 	#endif
95 	#ifdef B460800
96 	B460800,
97 	#endif
98 	#ifdef B500000
99 	B500000,
100 	#endif
101 	#ifdef B576000
102 	B576000,
103 	#endif
104 	#ifdef B921600
105 	B921600,
106 	#endif
107 	#ifdef B1000000
108 	B1000000,
109 	#endif
110 	#ifdef B1142000
111 	B1152000,
112 	#endif
113 	#ifdef B1500000
114 	B1500000,
115 	#endif
116 	#ifdef B2000000
117 	B2000000,
118 	#endif
119 	#ifdef B2500000
120 	B2500000,
121 	#endif
122 	#ifdef B3000000
123 	B3000000,
124 	#endif
125 	#ifdef B3500000
126 	B3500000,
127 	#endif
128 	#ifdef B4000000
129 	B4000000,
130 	#endif
131 };
132 
inputBaud(serialportprofile::baudrate_t baudrate)133 bool serialportprofile::inputBaud(serialportprofile::baudrate_t baudrate) {
134 	return !cfsetispeed(&pvt->_tio,br[baudrate]);
135 }
136 
outputBaud(serialportprofile::baudrate_t baudrate)137 bool serialportprofile::outputBaud(serialportprofile::baudrate_t baudrate) {
138 	return !cfsetospeed(&pvt->_tio,br[baudrate]);
139 }
140 
baud(serialportprofile::baudrate_t baudrate)141 void serialportprofile::baud(serialportprofile::baudrate_t baudrate) {
142 
143 	#ifdef CBAUD
144 		#ifdef CBAUDEX
145 		pvt->_tio.c_cflag&=~(CBAUD|CBAUDEX);
146 		#else
147 		pvt->_tio.c_cflag&=~CBAUD;
148 		#endif
149 	#else
150 		pvt->_tio.c_cflag&=~(B0|B50|B75|B110|B134|B150|B200|B300|
151 				B600|B1200|B1800|B2400|B4800|B9600
152 				#if defined(B19200)
153 				|B19200
154 				#elif defined(EXTA)
155 				|EXTA
156 				#endif
157 				#if defined(B38400)
158 				|B38400
159 				#elif defined(EXTB)
160 				|EXTB
161 				#endif
162 				#ifdef B57600
163 				|B57600
164 				#endif
165 				#ifdef B76800
166 				|B76800
167 				#endif
168 				#ifdef B115200
169 				|B115200
170 				#endif
171 				#ifdef B230400
172 				|B230400
173 				#endif
174 				#ifdef B460800
175 				|B460800
176 				#endif
177 				#ifdef B500000
178 				|B500000
179 				#endif
180 				#ifdef B576000
181 				|B576000
182 				#endif
183 				#ifdef B921600
184 				|B921600
185 				#endif
186 				#ifdef B1000000
187 				|B1000000
188 				#endif
189 				#ifdef B1142000
190 				|B1152000
191 				#endif
192 				#ifdef B1500000
193 				|B1500000
194 				#endif
195 				#ifdef B2000000
196 				|B2000000
197 				#endif
198 				#ifdef B2500000
199 				|B2500000
200 				#endif
201 				#ifdef B3000000
202 				|B3000000
203 				#endif
204 				#ifdef B3500000
205 				|B3500000
206 				#endif
207 				#ifdef B4000000
208 				|B4000000
209 				#endif
210 				);
211 	#endif
212 	pvt->_tio.c_cflag|=br[baudrate];
213 }
214 
characterSize(serialportprofile::charsize_t size)215 void serialportprofile::characterSize(serialportprofile::charsize_t size) {
216 	pvt->_tio.c_cflag&=~CSIZE;
217 	switch (size) {
218 		case cs_5:
219 			pvt->_tio.c_cflag|=CS5;
220 			return;
221 		case cs_6:
222 			pvt->_tio.c_cflag|=CS6;
223 			return;
224 		case cs_7:
225 			pvt->_tio.c_cflag|=CS7;
226 			return;
227 		case cs_8:
228 			pvt->_tio.c_cflag|=CS8;
229 			return;
230 	}
231 	return;
232 }
233 
234 #define SET_FLAG(truefalse,flag,value) \
235 	if (truefalse) { pvt->_tio.flag|=value; } else { pvt->_tio.flag&=~value; }
236 
237 #define SET_CHAR(character,value) \
238 	pvt->_tio.c_cc[character]=value;
239 
240 #define GET_FLAG(flag,value) (pvt->_tio.flag&value)
241 
242 #define GET_CHAR(character) (pvt->_tio.c_cc[character])
243 
twoStopBits(bool truefalse)244 void serialportprofile::twoStopBits(bool truefalse) {
245 	SET_FLAG(truefalse,c_cflag,CSTOPB)
246 }
247 
receiverOn(bool truefalse)248 void serialportprofile::receiverOn(bool truefalse) {
249 	SET_FLAG(truefalse,c_cflag,CREAD)
250 }
251 
parityCheck(bool truefalse)252 void serialportprofile::parityCheck(bool truefalse) {
253 	SET_FLAG(truefalse,c_cflag,PARENB)
254 }
255 
oddParity(bool truefalse)256 void serialportprofile::oddParity(bool truefalse) {
257 	SET_FLAG(truefalse,c_cflag,PARODD)
258 }
259 
hangupOnClose(bool truefalse)260 void serialportprofile::hangupOnClose(bool truefalse) {
261 	SET_FLAG(truefalse,c_cflag,HUPCL)
262 }
263 
ignoreModemControlLines(bool truefalse)264 void serialportprofile::ignoreModemControlLines(bool truefalse) {
265 	SET_FLAG(truefalse,c_cflag,CLOCAL)
266 }
267 
blockJobControlOutput(bool truefalse)268 void serialportprofile::blockJobControlOutput(bool truefalse) {
269 	#ifdef LOBLK
270 		SET_FLAG(truefalse,c_cflag,LOBLK)
271 	#endif
272 }
273 
hardwareFlowControl(bool truefalse)274 void serialportprofile::hardwareFlowControl(bool truefalse) {
275 	#if defined(CRTSCTS)
276 		SET_FLAG(truefalse,c_cflag,CRTSCTS)
277 	#elif defined(NEW_CRTSCTS)
278 		SET_FLAG(truefalse,c_cflag,NEW_CRTSCTS)
279 	#elif defined(CRTS_IFLOW)
280 		SET_FLAG(truefalse,c_cflag,CRTS_IFLOW)
281 	#elif defined(CCTS_OFLOW)
282 		SET_FLAG(truefalse,c_cflag,CRTS_IFLOW)
283 	#endif
284 }
285 
286 // FIXME:
287 //	CDTRCTS - DTR/CTS full-duplex flow control
288 //	MDMBUF - DTR/DCD hardware flow control
289 //	CHWFLOW - (MDMBUF|CRTSCTS|CDTRCTS)
290 
baud()291 serialportprofile::baudrate_t serialportprofile::baud() {
292 	#ifdef CBAUD
293 		return (baudrate_t)GET_FLAG(c_cflag,CBAUD);
294 	#else
295 		tcflag_t	cbaud=
296 				(B0|B50|B75|B110|B134|B150|B200|B300|
297 				B600|B1200|B1800|B2400|B4800|B9600
298 				#if defined(B19200)
299 				|B19200
300 				#elif defined(EXTA)
301 				|EXTA
302 				#endif
303 				#if defined(B38400)
304 				|B38400
305 				#elif defined(EXTB)
306 				|EXTB
307 				#endif
308 				#ifdef B57600
309 				|B57600
310 				#endif
311 				#ifdef B76800
312 				|B76800
313 				#endif
314 				#ifdef B115200
315 				|B115200
316 				#endif
317 				#ifdef B230400
318 				|B230400
319 				#endif
320 				#ifdef B460800
321 				|B460800
322 				#endif
323 				#ifdef B500000
324 				|B500000
325 				#endif
326 				#ifdef B576000
327 				|B576000
328 				#endif
329 				#ifdef B921600
330 				|B921600
331 				#endif
332 				#ifdef B1000000
333 				|B1000000
334 				#endif
335 				#ifdef B1142000
336 				|B1152000
337 				#endif
338 				#ifdef B1500000
339 				|B1500000
340 				#endif
341 				#ifdef B2000000
342 				|B2000000
343 				#endif
344 				#ifdef B2500000
345 				|B2500000
346 				#endif
347 				#ifdef B3000000
348 				|B3000000
349 				#endif
350 				#ifdef B3500000
351 				|B3500000
352 				#endif
353 				#ifdef B4000000
354 				|B4000000
355 				#endif
356 				);
357 		return (baudrate_t)GET_FLAG(c_cflag,cbaud);
358 	#endif
359 }
360 
inputBaud()361 serialportprofile::baudrate_t serialportprofile::inputBaud() {
362 	return (serialportprofile::baudrate_t)cfgetispeed(&pvt->_tio);
363 }
364 
outputBaud()365 serialportprofile::baudrate_t serialportprofile::outputBaud() {
366 	return (serialportprofile::baudrate_t)cfgetospeed(&pvt->_tio);
367 }
368 
characterSize()369 serialportprofile::charsize_t serialportprofile::characterSize() {
370 	switch (GET_FLAG(c_cflag,CSIZE)) {
371 		// Haiku only supports CS7/CS8 and defines CS5,6 and 7 to 0x00
372 		#if CS5!=CS6
373 		case CS5:
374 			return cs_5;
375 		#endif
376 		#if CS6!=CS7
377 		case CS6:
378 			return cs_6;
379 		#endif
380 		case CS7:
381 			return cs_7;
382 	}
383 	return cs_8;
384 }
385 
twoStopBits()386 bool serialportprofile::twoStopBits() {
387 	return GET_FLAG(c_cflag,CSTOPB);
388 }
389 
receiverOn()390 bool serialportprofile::receiverOn() {
391 	return GET_FLAG(c_cflag,CREAD);
392 }
393 
parityCheck()394 bool serialportprofile::parityCheck() {
395 	return GET_FLAG(c_cflag,PARENB);
396 }
397 
oddParity()398 bool serialportprofile::oddParity() {
399 	return GET_FLAG(c_cflag,PARODD);
400 }
401 
hangupOnClose()402 bool serialportprofile::hangupOnClose() {
403 	return GET_FLAG(c_cflag,HUPCL);
404 }
405 
ignoreModemControlLines()406 bool serialportprofile::ignoreModemControlLines() {
407 	return GET_FLAG(c_cflag,CLOCAL);
408 }
409 
blockJobControlOutput()410 bool serialportprofile::blockJobControlOutput() {
411 	#ifdef LOBLK
412 		return GET_FLAG(c_cflag,LOBLK);
413 	#else
414 		RUDIMENTS_SET_ENOSYS
415 		return false;
416 	#endif
417 }
418 
hardwareFlowControl()419 bool serialportprofile::hardwareFlowControl() {
420 	#if defined(CRTSCTS)
421 		return GET_FLAG(c_cflag,CRTSCTS);
422 	#elif defined(NEW_CRTSCTS)
423 		return GET_FLAG(c_cflag,NEW_CRTSCTS);
424 	#elif defined(CRTS_IFLOW)
425 		return GET_FLAG(c_cflag,CRTS_IFLOW);
426 	#elif defined(CCTS_OFLOW)
427 		return GET_FLAG(c_cflag,CRTS_OFLOW);
428 	#else
429 		RUDIMENTS_SET_ENOSYS
430 		return false;
431 	#endif
432 }
433 
generateSignals(bool truefalse)434 void serialportprofile::generateSignals(bool truefalse){
435 	SET_FLAG(truefalse,c_lflag,ISIG)
436 }
437 
canonicalInput(bool truefalse)438 void serialportprofile::canonicalInput(bool truefalse) {
439 	SET_FLAG(truefalse,c_lflag,ICANON)
440 }
441 
escapedUpperCase(bool truefalse)442 void serialportprofile::escapedUpperCase(bool truefalse) {
443 	#ifdef XCASE
444 		SET_FLAG(truefalse,c_lflag,XCASE)
445 	#endif
446 }
447 
echoInput(bool truefalse)448 void serialportprofile::echoInput(bool truefalse) {
449 	SET_FLAG(truefalse,c_lflag,ECHO)
450 }
451 
eraseCharactersOn(bool truefalse)452 void serialportprofile::eraseCharactersOn(bool truefalse) {
453 	SET_FLAG(truefalse,c_lflag,ECHOE)
454 }
455 
killCharacterOn(bool truefalse)456 void serialportprofile::killCharacterOn(bool truefalse) {
457 	SET_FLAG(truefalse,c_lflag,ECHOK)
458 }
459 
echoNewLine(bool truefalse)460 void serialportprofile::echoNewLine(bool truefalse) {
461 	SET_FLAG(truefalse,c_lflag,ECHONL)
462 }
463 
extendedFunctions(bool truefalse)464 void serialportprofile::extendedFunctions(bool truefalse) {
465 	SET_FLAG(truefalse,c_lflag,IEXTEN)
466 }
467 
echoControlCharacters(bool truefalse)468 void serialportprofile::echoControlCharacters(bool truefalse) {
469 	#ifdef ECHOCTL
470 		SET_FLAG(truefalse,c_lflag,ECHOCTL)
471 	#endif
472 }
473 
echoErasedCharacter(bool truefalse)474 void serialportprofile::echoErasedCharacter(bool truefalse) {
475 	#ifdef ECHOPRT
476 		SET_FLAG(truefalse,c_lflag,ECHOPRT)
477 	#endif
478 }
479 
emulateKill(bool truefalse)480 void serialportprofile::emulateKill(bool truefalse) {
481 	#ifdef ECHOKE
482 		SET_FLAG(truefalse,c_lflag,ECHOKE)
483 	#endif
484 }
485 
noFlushAfterInterruptOrQuit(bool truefalse)486 void serialportprofile::noFlushAfterInterruptOrQuit(bool truefalse) {
487 	SET_FLAG(truefalse,c_lflag,NOFLSH)
488 }
489 
retypePendingCharacters(bool truefalse)490 void serialportprofile::retypePendingCharacters(bool truefalse) {
491 	#ifdef PENDIN
492 		SET_FLAG(truefalse,c_lflag,PENDIN)
493 	#endif
494 }
495 
sendSignalForBackgroundOutput(bool truefalse)496 void serialportprofile::sendSignalForBackgroundOutput(bool truefalse) {
497 	SET_FLAG(truefalse,c_lflag,TOSTOP)
498 }
499 
generateSignals()500 bool serialportprofile::generateSignals() {
501 	return GET_FLAG(c_lflag,ISIG);
502 }
503 
canonicalInput()504 bool serialportprofile::canonicalInput() {
505 	return GET_FLAG(c_lflag,ICANON);
506 }
507 
escapedUpperCase()508 bool serialportprofile::escapedUpperCase() {
509 	#ifdef XCASE
510 		return GET_FLAG(c_lflag,XCASE);
511 	#else
512 		RUDIMENTS_SET_ENOSYS
513 		return false;
514 	#endif
515 }
516 
echoInput()517 bool serialportprofile::echoInput() {
518 	return GET_FLAG(c_lflag,ECHO);
519 }
520 
eraseCharactersOn()521 bool serialportprofile::eraseCharactersOn() {
522 	return GET_FLAG(c_lflag,ECHOE);
523 }
524 
killCharacterOn()525 bool serialportprofile::killCharacterOn() {
526 	return GET_FLAG(c_lflag,ECHOK);
527 }
528 
echoNewLine()529 bool serialportprofile::echoNewLine() {
530 	return GET_FLAG(c_lflag,ECHONL);
531 }
532 
extendedFunctions()533 bool serialportprofile::extendedFunctions() {
534 	return GET_FLAG(c_lflag,IEXTEN);
535 }
536 
echoControlCharacters()537 bool serialportprofile::echoControlCharacters() {
538 	#ifdef ECHOCTL
539 		return GET_FLAG(c_lflag,ECHOCTL);
540 	#else
541 		RUDIMENTS_SET_ENOSYS
542 		return false;
543 	#endif
544 }
545 
echoErasedCharacter()546 bool serialportprofile::echoErasedCharacter() {
547 	#ifdef ECHOPRT
548 		return GET_FLAG(c_lflag,ECHOPRT);
549 	#else
550 		RUDIMENTS_SET_ENOSYS
551 		return false;
552 	#endif
553 }
554 
emulateKill()555 bool serialportprofile::emulateKill() {
556 	#ifdef ECHOKE
557 		return GET_FLAG(c_lflag,ECHOKE);
558 	#else
559 		RUDIMENTS_SET_ENOSYS
560 		return false;
561 	#endif
562 }
563 
noFlushAfterInterruptOrQuit()564 bool serialportprofile::noFlushAfterInterruptOrQuit() {
565 	return GET_FLAG(c_lflag,NOFLSH);
566 }
567 
retypePendingCharacters()568 bool serialportprofile::retypePendingCharacters() {
569 	#ifdef PENDIN
570 		return GET_FLAG(c_lflag,PENDIN);
571 	#else
572 		RUDIMENTS_SET_ENOSYS
573 		return false;
574 	#endif
575 }
576 
sendSignalForBackgroundOutput()577 bool serialportprofile::sendSignalForBackgroundOutput() {
578 	return GET_FLAG(c_lflag,TOSTOP);
579 }
580 
inputParityCheck(bool truefalse)581 void serialportprofile::inputParityCheck(bool truefalse) {
582 	SET_FLAG(truefalse,c_iflag,INPCK)
583 }
584 
ignoreParityErrors(bool truefalse)585 void serialportprofile::ignoreParityErrors(bool truefalse) {
586 	SET_FLAG(truefalse,c_iflag,IGNPAR)
587 }
588 
markParityErrors(bool truefalse)589 void serialportprofile::markParityErrors(bool truefalse) {
590 	SET_FLAG(truefalse,c_iflag,PARMRK)
591 }
592 
stripParityBits(bool truefalse)593 void serialportprofile::stripParityBits(bool truefalse) {
594 	SET_FLAG(truefalse,c_iflag,ISTRIP)
595 }
596 
softwareFlowControlOnOutput(bool truefalse)597 void serialportprofile::softwareFlowControlOnOutput(bool truefalse) {
598 	SET_FLAG(truefalse,c_iflag,IXON)
599 }
600 
softwareFlowControlOnInput(bool truefalse)601 void serialportprofile::softwareFlowControlOnInput(bool truefalse) {
602 	SET_FLAG(truefalse,c_iflag,IXOFF)
603 }
604 
anyCharacterStartsFlow(bool truefalse)605 void serialportprofile::anyCharacterStartsFlow(bool truefalse) {
606 	SET_FLAG(truefalse,c_iflag,IXANY)
607 }
608 
ignoreBreak(bool truefalse)609 void serialportprofile::ignoreBreak(bool truefalse) {
610 	SET_FLAG(truefalse,c_iflag,IGNBRK)
611 }
612 
sendSignalOnBreak(bool truefalse)613 void serialportprofile::sendSignalOnBreak(bool truefalse) {
614 	SET_FLAG(truefalse,c_iflag,BRKINT)
615 }
616 
mapNewLineToCarriageReturnOnInput(bool truefalse)617 void serialportprofile::mapNewLineToCarriageReturnOnInput(bool truefalse) {
618 	SET_FLAG(truefalse,c_iflag,INLCR)
619 }
620 
ignoreCarriageReturn(bool truefalse)621 void serialportprofile::ignoreCarriageReturn(bool truefalse) {
622 	SET_FLAG(truefalse,c_iflag,IGNCR)
623 }
624 
mapCarriageReturnToNewLineOnInput(bool truefalse)625 void serialportprofile::mapCarriageReturnToNewLineOnInput(bool truefalse) {
626 	SET_FLAG(truefalse,c_iflag,ICRNL)
627 }
628 
lowerCase(bool truefalse)629 void serialportprofile::lowerCase(bool truefalse) {
630 	#ifdef IUCLC
631 		SET_FLAG(truefalse,c_iflag,IUCLC)
632 	#endif
633 }
634 
bellIfLineTooLong(bool truefalse)635 void serialportprofile::bellIfLineTooLong(bool truefalse) {
636 	#ifdef IMAXBEL
637 		SET_FLAG(truefalse,c_iflag,IMAXBEL)
638 	#endif
639 }
640 
inputParityCheck()641 bool serialportprofile::inputParityCheck() {
642 	return GET_FLAG(c_iflag,INPCK);
643 }
644 
ignoreParityErrors()645 bool serialportprofile::ignoreParityErrors() {
646 	return GET_FLAG(c_iflag,IGNPAR);
647 }
648 
markParityErrors()649 bool serialportprofile::markParityErrors() {
650 	return GET_FLAG(c_iflag,PARMRK);
651 }
652 
stripParityBits()653 bool serialportprofile::stripParityBits() {
654 	return GET_FLAG(c_iflag,ISTRIP);
655 }
656 
softwareFlowControlOnOutput()657 bool serialportprofile::softwareFlowControlOnOutput() {
658 	return GET_FLAG(c_iflag,IXON);
659 }
660 
softwareFlowControlOnInput()661 bool serialportprofile::softwareFlowControlOnInput() {
662 	return GET_FLAG(c_iflag,IXOFF);
663 }
664 
anyCharacterStartsFlow()665 bool serialportprofile::anyCharacterStartsFlow() {
666 	return GET_FLAG(c_iflag,IXANY);
667 }
668 
ignoreBreak()669 bool serialportprofile::ignoreBreak() {
670 	return GET_FLAG(c_iflag,IGNBRK);
671 }
672 
sendSignalOnBreak()673 bool serialportprofile::sendSignalOnBreak() {
674 	return GET_FLAG(c_iflag,BRKINT);
675 }
676 
mapNewLineToCarriageReturnOnInput()677 bool serialportprofile::mapNewLineToCarriageReturnOnInput() {
678 	return GET_FLAG(c_iflag,INLCR);
679 }
680 
ignoreCarriageReturn()681 bool serialportprofile::ignoreCarriageReturn() {
682 	return GET_FLAG(c_iflag,IGNCR);
683 }
684 
mapCarriageReturnToNewLineOnInput()685 bool serialportprofile::mapCarriageReturnToNewLineOnInput() {
686 	return GET_FLAG(c_iflag,ICRNL);
687 }
688 
lowerCase()689 bool serialportprofile::lowerCase() {
690 	#ifdef IUCLC
691 		return GET_FLAG(c_iflag,IUCLC);
692 	#else
693 		RUDIMENTS_SET_ENOSYS
694 		return false;
695 	#endif
696 }
697 
bellIfLineTooLong()698 bool serialportprofile::bellIfLineTooLong() {
699 	#ifdef IMAXBEL
700 		return GET_FLAG(c_iflag,IMAXBEL);
701 	#else
702 		RUDIMENTS_SET_ENOSYS
703 		return false;
704 	#endif
705 }
706 
postProcessOutput(bool truefalse)707 void serialportprofile::postProcessOutput(bool truefalse) {
708 	SET_FLAG(truefalse,c_oflag,OPOST)
709 }
710 
outputUpperCase(bool truefalse)711 void serialportprofile::outputUpperCase(bool truefalse) {
712 	#ifdef OLCUC
713 		SET_FLAG(truefalse,c_oflag,OLCUC)
714 	#endif
715 }
716 
mapNewLineToCarriageReturnNewLineOnOutput(bool truefalse)717 void serialportprofile::mapNewLineToCarriageReturnNewLineOnOutput(
718 							bool truefalse) {
719 	SET_FLAG(truefalse,c_oflag,ONLCR)
720 }
721 
discardEndOfTransmission(bool truefalse)722 void serialportprofile::discardEndOfTransmission(bool truefalse) {
723 	#ifdef ONOEOT
724 		SET_FLAG(truefalse,c_oflag,ONOEOT)
725 	#endif
726 }
727 
mapCarriageReturnToNewLineOnOutput(bool truefalse)728 void serialportprofile::mapCarriageReturnToNewLineOnOutput(bool truefalse) {
729 	#ifdef OCRNL
730 		SET_FLAG(truefalse,c_oflag,OCRNL)
731 	#endif
732 }
733 
dontOutputCarriageReturnAtColumnZero(bool truefalse)734 void serialportprofile::dontOutputCarriageReturnAtColumnZero(bool truefalse) {
735 	#ifdef ONOCR
736 		SET_FLAG(truefalse,c_oflag,ONOCR)
737 	#endif
738 }
739 
mapNewLineToCarriageReturnOnOutput(bool truefalse)740 void serialportprofile::mapNewLineToCarriageReturnOnOutput(bool truefalse) {
741 	#ifdef ONLRET
742 		SET_FLAG(truefalse,c_oflag,ONLRET)
743 	#endif
744 }
745 
useFillCharactersForDelay(bool truefalse)746 void serialportprofile::useFillCharactersForDelay(bool truefalse) {
747 	#ifdef OFILL
748 		SET_FLAG(truefalse,c_oflag,OFILL)
749 	#endif
750 }
751 
useDelForFill(bool truefalse)752 void serialportprofile::useDelForFill(bool truefalse) {
753 	#ifdef OFDEL
754 		SET_FLAG(truefalse,c_oflag,OFDEL)
755 	#endif
756 }
757 
expandTabToSpaces(bool truefalse)758 void serialportprofile::expandTabToSpaces(bool truefalse) {
759 	#if defined(XTABS)
760 		SET_FLAG(truefalse,c_oflag,XTABS)
761 	#elif defined(OXTABS)
762 		SET_FLAG(truefalse,c_oflag,OXTABS)
763 	#else
764 		SET_FLAG(truefalse,c_oflag,TAB3)
765 	#endif
766 }
767 
delayAfterNewLine(serialportprofile::newlinedelay_t nldelay)768 void serialportprofile::delayAfterNewLine(
769 		serialportprofile::newlinedelay_t nldelay) {
770 	#ifdef NLDLY
771 		static tcflag_t	nld[]={NL0,NL1};
772 		pvt->_tio.c_oflag&=~NLDLY;
773 		pvt->_tio.c_oflag|=nld[nldelay];
774 	#endif
775 }
776 
delayAfterCarriageReturn(serialportprofile::carriagereturndelay_t crdelay)777 void serialportprofile::delayAfterCarriageReturn(
778 		serialportprofile::carriagereturndelay_t crdelay) {
779 	#ifdef CRDLY
780 		static tcflag_t	crd[]={CR0,CR1,CR2,CR3};
781 		pvt->_tio.c_oflag&=~CRDLY;
782 		pvt->_tio.c_oflag|=crd[crdelay];
783 	#endif
784 }
785 
delayAfterTab(serialportprofile::tabdelay_t tabdelay)786 void serialportprofile::delayAfterTab(
787 		serialportprofile::tabdelay_t tabdelay) {
788 	#ifdef TABDLY
789 		static tcflag_t td[]={
790 			#ifdef TAB0
791 			TAB0,
792 			#endif
793 			#ifdef TAB1
794 			TAB1,
795 			#endif
796 			#ifdef TAB2
797 			TAB2,
798 			#endif
799 			#ifdef TAB3
800 			TAB3
801 			#endif
802 			};
803 		pvt->_tio.c_oflag&=~TABDLY;
804 		pvt->_tio.c_oflag|=td[tabdelay];
805 	#endif
806 }
807 
delayAfterBackSpace(serialportprofile::backspacedelay_t bsdelay)808 void serialportprofile::delayAfterBackSpace(
809 		serialportprofile::backspacedelay_t bsdelay) {
810 	#ifdef BSDLY
811 		static tcflag_t	bsd[]={BS0,BS1};
812 		pvt->_tio.c_oflag&=~BSDLY;
813 		pvt->_tio.c_oflag|=bsd[bsdelay];
814 	#endif
815 }
816 
delayAfterVerticalTab(serialportprofile::verticaltabdelay_t vtdelay)817 void serialportprofile::delayAfterVerticalTab(
818 		serialportprofile::verticaltabdelay_t vtdelay) {
819 	#ifdef VTDLY
820 		static tcflag_t	vtd[]={VT0,VT1};
821 		pvt->_tio.c_oflag&=~VTDLY;
822 		pvt->_tio.c_oflag|=vtd[vtdelay];
823 	#endif
824 }
825 
delayAfterFormFeed(serialportprofile::formfeeddelay_t ffdelay)826 void serialportprofile::delayAfterFormFeed(
827 		serialportprofile::formfeeddelay_t ffdelay) {
828 	#ifdef FFDLY
829 		static tcflag_t	ffd[]={FF0,FF1};
830 		pvt->_tio.c_oflag&=~FFDLY;
831 		pvt->_tio.c_oflag|=ffd[ffdelay];
832 	#endif
833 }
834 
postProcessOutput()835 bool serialportprofile::postProcessOutput() {
836 	return GET_FLAG(c_oflag,OPOST);
837 }
838 
outputUpperCase()839 bool serialportprofile::outputUpperCase() {
840 	#ifdef OLCUC
841 		return GET_FLAG(c_oflag,OLCUC);
842 	#else
843 		RUDIMENTS_SET_ENOSYS
844 		return false;
845 	#endif
846 }
847 
mapNewLineToCarriageReturnNewLineOnOutput()848 bool serialportprofile::mapNewLineToCarriageReturnNewLineOnOutput() {
849 	return GET_FLAG(c_oflag,ONLCR);
850 }
851 
discardEndOfTransmission()852 bool serialportprofile::discardEndOfTransmission() {
853 	#ifdef ONOEOT
854 		return GET_FLAG(c_oflag,ONOEOT);
855 	#else
856 		RUDIMENTS_SET_ENOSYS
857 		return false;
858 	#endif
859 }
860 
mapCarriageReturnToNewLineOnOutput()861 bool serialportprofile::mapCarriageReturnToNewLineOnOutput() {
862 	#ifdef OCRNL
863 		return GET_FLAG(c_oflag,OCRNL);
864 	#else
865 		RUDIMENTS_SET_ENOSYS
866 		return false;
867 	#endif
868 }
869 
dontOutputCarriageReturnAtColumnZero()870 bool serialportprofile::dontOutputCarriageReturnAtColumnZero() {
871 	#ifdef ONOCR
872 		return GET_FLAG(c_oflag,ONOCR);
873 	#else
874 		RUDIMENTS_SET_ENOSYS
875 		return false;
876 	#endif
877 }
878 
mapNewLineToCarriageReturnOnOutput()879 bool serialportprofile::mapNewLineToCarriageReturnOnOutput() {
880 	#ifdef ONLRET
881 		return GET_FLAG(c_oflag,ONLRET);
882 	#else
883 		RUDIMENTS_SET_ENOSYS
884 		return false;
885 	#endif
886 }
887 
useFillCharactersForDelay()888 bool serialportprofile::useFillCharactersForDelay() {
889 	#ifdef OFILL
890 		return GET_FLAG(c_oflag,OFILL);
891 	#else
892 		RUDIMENTS_SET_ENOSYS
893 		return false;
894 	#endif
895 }
896 
useDelForFill()897 bool serialportprofile::useDelForFill() {
898 	#ifdef OFDEL
899 		return GET_FLAG(c_oflag,OFDEL);
900 	#else
901 		RUDIMENTS_SET_ENOSYS
902 		return false;
903 	#endif
904 }
905 
expandTabToSpaces()906 bool serialportprofile::expandTabToSpaces() {
907 	#if defined(XTABS)
908 		return GET_FLAG(c_oflag,XTABS);
909 	#elif defined(OXTABS)
910 		return GET_FLAG(c_oflag,OXTABS);
911 	#else
912 		return GET_FLAG(c_oflag,TAB3);
913 	#endif
914 }
915 
916 serialportprofile::newlinedelay_t
delayAfterNewLine()917 		serialportprofile::delayAfterNewLine() {
918 	#ifdef NLDLY
919 		if (GET_FLAG(c_cflag,NLDLY)==NL1) {
920 			return nl_100;
921 		}
922 	#endif
923 	return nl_none;
924 }
925 
926 serialportprofile::carriagereturndelay_t
delayAfterCarriageReturn()927 		serialportprofile::delayAfterCarriageReturn() {
928 	#ifdef CRDLY
929 		switch (GET_FLAG(c_cflag,CRDLY)) {
930 			case CR1:
931 				return cr_depends;
932 			case CR2:
933 				return cr_100;
934 			case CR3:
935 				return cr_150;
936 		}
937 	#endif
938 	return cr_none;
939 }
940 
941 serialportprofile::tabdelay_t
delayAfterTab()942 		serialportprofile::delayAfterTab() {
943 	#ifdef TABDLY
944 		switch (GET_FLAG(c_cflag,TABDLY)) {
945 			#ifdef TAB1
946 			case TAB1:
947 				return td_1;
948 			#endif
949 			#ifdef TAB2
950 			case TAB2:
951 				return td_2;
952 			#endif
953 			#ifdef TAB3
954 			case TAB3:
955 				return td_xtabs;
956 			#endif
957 		}
958 	#endif
959 	return td_0;
960 }
961 
962 serialportprofile::backspacedelay_t
delayAfterBackSpace()963 		serialportprofile::delayAfterBackSpace() {
964 	#ifdef BSDLY
965 		if (GET_FLAG(c_cflag,BSDLY)==BS1) {
966 			return bs_50;
967 		}
968 	#endif
969 	return bs_none;
970 }
971 
972 serialportprofile::verticaltabdelay_t
delayAfterVerticalTab()973 		serialportprofile::delayAfterVerticalTab() {
974 	#ifdef VTDLY
975 		if (GET_FLAG(c_cflag,VTDLY)==VT1) {
976 			return vt_2;
977 		}
978 	#endif
979 	return vt_none;
980 }
981 
982 serialportprofile::formfeeddelay_t
delayAfterFormFeed()983 		serialportprofile::delayAfterFormFeed() {
984 	#ifdef FFDLY
985 		if (GET_FLAG(c_cflag,FFDLY)==FF1) {
986 			return ff_2;
987 		}
988 	#endif
989 	return ff_none;
990 }
991 
interruptCharacter(unsigned char character)992 void serialportprofile::interruptCharacter(unsigned char character) {
993 	SET_CHAR(VINTR,character)
994 }
995 
quitCharacter(unsigned char character)996 void serialportprofile::quitCharacter(unsigned char character) {
997 	SET_CHAR(VQUIT,character)
998 }
999 
eraseCharacter(unsigned char character)1000 void serialportprofile::eraseCharacter(unsigned char character) {
1001 	SET_CHAR(VERASE,character)
1002 }
1003 
killCharacter(unsigned char character)1004 void serialportprofile::killCharacter(unsigned char character) {
1005 	SET_CHAR(VKILL,character)
1006 }
1007 
endOfFileCharacter(unsigned char character)1008 void serialportprofile::endOfFileCharacter(unsigned char character) {
1009 	SET_CHAR(VEOF,character)
1010 }
1011 
endOfLineCharacter(unsigned char character)1012 void serialportprofile::endOfLineCharacter(unsigned char character) {
1013 	SET_CHAR(VEOL,character)
1014 }
1015 
secondEndOfLineCharacter(unsigned char character)1016 void serialportprofile::secondEndOfLineCharacter(unsigned char character) {
1017 	#ifdef VEOL2
1018 		SET_CHAR(VEOL2,character)
1019 	#endif
1020 }
1021 
switchCharacer(unsigned char character)1022 void serialportprofile::switchCharacer(unsigned char character) {
1023 	#if defined(VSWTCH)
1024 		SET_CHAR(VSWTCH,character)
1025 	#elif defined(VSWTC)
1026 		SET_CHAR(VSWTC,character)
1027 	#endif
1028 }
1029 
startCharacter(unsigned char character)1030 void serialportprofile::startCharacter(unsigned char character) {
1031 	SET_CHAR(VSTART,character)
1032 }
1033 
stopCharacter(unsigned char character)1034 void serialportprofile::stopCharacter(unsigned char character) {
1035 	SET_CHAR(VSTOP,character)
1036 }
1037 
suspendCharacter(unsigned char character)1038 void serialportprofile::suspendCharacter(unsigned char character) {
1039 	SET_CHAR(VSUSP,character)
1040 }
1041 
delayedSuspendCharacter(unsigned char character)1042 void serialportprofile::delayedSuspendCharacter(unsigned char character) {
1043 	#ifdef VDSUSP
1044 		SET_CHAR(VDSUSP,character)
1045 	#endif
1046 }
1047 
literalNextCharcter(unsigned char character)1048 void serialportprofile::literalNextCharcter(unsigned char character) {
1049 	#ifdef VLNEXT
1050 		SET_CHAR(VLNEXT,character)
1051 	#endif
1052 }
1053 
wordEraseCharcter(unsigned char character)1054 void serialportprofile::wordEraseCharcter(unsigned char character) {
1055 	#ifdef VWERASE
1056 		SET_CHAR(VWERASE,character)
1057 	#endif
1058 }
1059 
1060 
reprintCharacter(unsigned char character)1061 void serialportprofile::reprintCharacter(unsigned char character) {
1062 	#ifdef VREPRINT
1063 		SET_CHAR(VREPRINT,character)
1064 	#endif
1065 }
1066 
discardPendingOutputCharacter(unsigned char character)1067 void serialportprofile::discardPendingOutputCharacter(unsigned char character) {
1068 	#ifdef VDISCARD
1069 		SET_CHAR(VDISCARD,character)
1070 	#endif
1071 }
1072 
statusRequestCharacter(unsigned char character)1073 void serialportprofile::statusRequestCharacter(unsigned char character) {
1074 	#ifdef VSTATUS
1075 		SET_CHAR(VSTATUS,character)
1076 	#endif
1077 }
1078 
readThreshold(unsigned char count)1079 void serialportprofile::readThreshold(unsigned char count) {
1080 	SET_CHAR(VMIN,count)
1081 }
1082 
readTimeout(unsigned char deciseconds)1083 void serialportprofile::readTimeout(unsigned char deciseconds) {
1084 	SET_CHAR(VTIME,deciseconds)
1085 }
1086 
interruptCharacter()1087 unsigned char serialportprofile::interruptCharacter() {
1088 	return GET_CHAR(VINTR);
1089 }
1090 
quitCharacter()1091 unsigned char serialportprofile::quitCharacter() {
1092 	return GET_CHAR(VQUIT);
1093 }
1094 
eraseCharacter()1095 unsigned char serialportprofile::eraseCharacter() {
1096 	return GET_CHAR(VERASE);
1097 }
1098 
killCharacter()1099 unsigned char serialportprofile::killCharacter() {
1100 	return GET_CHAR(VKILL);
1101 }
1102 
endOfFileCharacter()1103 unsigned char serialportprofile::endOfFileCharacter() {
1104 	return GET_CHAR(VEOF);
1105 }
1106 
endOfLineCharacter()1107 unsigned char serialportprofile::endOfLineCharacter() {
1108 	return GET_CHAR(VEOL);
1109 }
1110 
secondEndOfLineCharacter()1111 unsigned char serialportprofile::secondEndOfLineCharacter() {
1112 	#ifdef VEOL2
1113 		return GET_CHAR(VEOL2);
1114 	#else
1115 		RUDIMENTS_SET_ENOSYS
1116 		return 0;
1117 	#endif
1118 }
1119 
switchCharacer()1120 unsigned char serialportprofile::switchCharacer() {
1121 	#if defined(VSWTCH)
1122 		return GET_CHAR(VSWTCH);
1123 	#elif defined(VSWTC)
1124 		return GET_CHAR(VSWTC);
1125 	#else
1126 		RUDIMENTS_SET_ENOSYS
1127 		return 0;
1128 	#endif
1129 }
1130 
startCharacter()1131 unsigned char serialportprofile::startCharacter() {
1132 	return GET_CHAR(VSTART);
1133 }
1134 
stopCharacter()1135 unsigned char serialportprofile::stopCharacter() {
1136 	return GET_CHAR(VSTOP);
1137 }
1138 
suspendCharacter()1139 unsigned char serialportprofile::suspendCharacter() {
1140 	return GET_CHAR(VSUSP);
1141 }
1142 
delayedSuspendCharacter()1143 unsigned char serialportprofile::delayedSuspendCharacter() {
1144 	#ifdef VDSUSP
1145 		return GET_CHAR(VDSUSP);
1146 	#else
1147 		RUDIMENTS_SET_ENOSYS
1148 		return 0;
1149 	#endif
1150 }
1151 
literalNextCharcter()1152 unsigned char serialportprofile::literalNextCharcter() {
1153 	#ifdef VLNEXT
1154 		return GET_CHAR(VLNEXT);
1155 	#else
1156 		RUDIMENTS_SET_ENOSYS
1157 		return 0;
1158 	#endif
1159 }
1160 
wordEraseCharcter()1161 unsigned char serialportprofile::wordEraseCharcter() {
1162 	#ifdef VWERASE
1163 		return GET_CHAR(VWERASE);
1164 	#else
1165 		RUDIMENTS_SET_ENOSYS
1166 		return 0;
1167 	#endif
1168 }
1169 
reprintCharacter()1170 unsigned char serialportprofile::reprintCharacter() {
1171 	#ifdef VREPRINT
1172 		return GET_CHAR(VREPRINT);
1173 	#else
1174 		RUDIMENTS_SET_ENOSYS
1175 		return 0;
1176 	#endif
1177 }
1178 
discardPendingOutputCharacter()1179 unsigned char serialportprofile::discardPendingOutputCharacter() {
1180 	#ifdef VDISCARD
1181 		return GET_CHAR(VDISCARD);
1182 	#else
1183 		RUDIMENTS_SET_ENOSYS
1184 		return 0;
1185 	#endif
1186 }
1187 
statusRequestCharacter()1188 unsigned char serialportprofile::statusRequestCharacter() {
1189 	#ifdef VSTATUS
1190 		return GET_CHAR(VSTATUS);
1191 	#else
1192 		RUDIMENTS_SET_ENOSYS
1193 		return 0;
1194 	#endif
1195 }
1196 
readThreshold()1197 unsigned char serialportprofile::readThreshold() {
1198 	return GET_CHAR(VMIN);
1199 }
1200 
readTimeout()1201 unsigned char serialportprofile::readTimeout() {
1202 	return GET_CHAR(VTIME);
1203 }
1204 
translateBaudString(const char * baudrate)1205 serialportprofile::baudrate_t serialportprofile::translateBaudString(
1206 							const char *baudrate) {
1207 
1208 	if (!charstring::compare(baudrate,"0")) {
1209 		return baud_0;
1210 	} else if (!charstring::compare(baudrate,"50")) {
1211 		return baud_50;
1212 	} else if (!charstring::compare(baudrate,"75")) {
1213 		return baud_75;
1214 	} else if (!charstring::compare(baudrate,"110")) {
1215 		return baud_110;
1216 	} else if (!charstring::compare(baudrate,"134")) {
1217 		return baud_134;
1218 	} else if (!charstring::compare(baudrate,"150")) {
1219 		return baud_150;
1220 	} else if (!charstring::compare(baudrate,"200")) {
1221 		return baud_200;
1222 	} else if (!charstring::compare(baudrate,"300")) {
1223 		return baud_300;
1224 	} else if (!charstring::compare(baudrate,"600")) {
1225 		return baud_600;
1226 	} else if (!charstring::compare(baudrate,"1200")) {
1227 		return baud_1200;
1228 	} else if (!charstring::compare(baudrate,"1800")) {
1229 		return baud_1800;
1230 	} else if (!charstring::compare(baudrate,"2400")) {
1231 		return baud_2400;
1232 	} else if (!charstring::compare(baudrate,"4800")) {
1233 		return baud_4800;
1234 	} else if (!charstring::compare(baudrate,"9600")) {
1235 		return baud_9600;
1236 	#if defined(B19200)
1237 	} else if (!charstring::compare(baudrate,"19200")) {
1238 		return baud_19200;
1239 	#elif defined(EXTA)
1240 	} else if (!charstring::compare(baudrate,"EXTA")) {
1241 		return baud_19200;
1242 	#endif
1243 	#if defined(B38400)
1244 	} else if (!charstring::compare(baudrate,"38400")) {
1245 		return baud_38400;
1246 	#elif defined(EXTB)
1247 	} else if (!charstring::compare(baudrate,"EXTB")) {
1248 		return baud_38400;
1249 	#endif
1250 	#ifdef B57600
1251 	} else if (!charstring::compare(baudrate,"57600")) {
1252 		return baud_57600;
1253 	#endif
1254 	#ifdef B76800
1255 	} else if (!charstring::compare(baudrate,"76800")) {
1256 		return baud_76800;
1257 	#endif
1258 	#ifdef B115200
1259 	} else if (!charstring::compare(baudrate,"115200")) {
1260 		return baud_115200;
1261 	#endif
1262 	#ifdef B230400
1263 	} else if (!charstring::compare(baudrate,"230400")) {
1264 		return baud_230400;
1265 	#endif
1266 	#ifdef B460800
1267 	} else if (!charstring::compare(baudrate,"460800")) {
1268 		return baud_460800;
1269 	#endif
1270 	#ifdef B500000
1271 	} else if (!charstring::compare(baudrate,"500000")) {
1272 		return baud_500000;
1273 	#endif
1274 	#ifdef B576000
1275 	} else if (!charstring::compare(baudrate,"576000")) {
1276 		return baud_576000;
1277 	#endif
1278 	#ifdef B921600
1279 	} else if (!charstring::compare(baudrate,"921600")) {
1280 		return baud_921600;
1281 	#endif
1282 	#ifdef B1000000
1283 	} else if (!charstring::compare(baudrate,"1000000")) {
1284 		return baud_1000000;
1285 	#endif
1286 	#ifdef B1142000
1287 	} else if (!charstring::compare(baudrate,"1152000")) {
1288 		return baud_1152000;
1289 	#endif
1290 	#ifdef B1500000
1291 	} else if (!charstring::compare(baudrate,"1500000")) {
1292 		return baud_1500000;
1293 	#endif
1294 	#ifdef B2000000
1295 	} else if (!charstring::compare(baudrate,"2000000")) {
1296 		return baud_2000000;
1297 	#endif
1298 	#ifdef B2500000
1299 	} else if (!charstring::compare(baudrate,"2500000")) {
1300 		return baud_2500000;
1301 	#endif
1302 	#ifdef B3000000
1303 	} else if (!charstring::compare(baudrate,"3000000")) {
1304 		return baud_3000000;
1305 	#endif
1306 	#ifdef B3500000
1307 	} else if (!charstring::compare(baudrate,"3500000")) {
1308 		return baud_3500000;
1309 	#endif
1310 	#ifdef B4000000
1311 	} else if (!charstring::compare(baudrate,"4000000")) {
1312 		return baud_4000000;
1313 	#endif
1314 	}
1315 	return baud_0;
1316 }
1317 
baud(const char * baudrate)1318 void serialportprofile::baud(const char *baudrate) {
1319 	baud(translateBaudString(baudrate));
1320 }
1321 
inputBaud(const char * baudrate)1322 bool serialportprofile::inputBaud(const char *baudrate) {
1323 	return inputBaud(translateBaudString(baudrate));
1324 }
1325 
outputBaud(const char * baudrate)1326 bool serialportprofile::outputBaud(const char *baudrate) {
1327 	return outputBaud(translateBaudString(baudrate));
1328 }
1329 
inputMode(serialportprofile::inputmode_t inputmode)1330 void serialportprofile::inputMode(serialportprofile::inputmode_t inputmode) {
1331 	if (inputmode==cannonical) {
1332 		canonicalInput(true);
1333 		echoInput(true);
1334 		eraseCharactersOn(true);
1335 	} else {
1336 		canonicalInput(false);
1337 		echoInput(false);
1338 		eraseCharactersOn(false);
1339 	}
1340 }
1341 
inputMode()1342 serialportprofile::inputmode_t serialportprofile::inputMode() {
1343 	return (canonicalInput() && echoInput() && eraseCharactersOn())?
1344 							cannonical:raw;
1345 }
1346 
evalOptionsString(const char * string)1347 void serialportprofile::evalOptionsString(const char *string) {
1348 
1349 	char	bitsperchar=string[0];
1350 	char	parity=character::toUpperCase(string[1]);
1351 	char	stopbits=string[2];
1352 
1353 	charsize_t	charsize=(charsize_t)cs_8;
1354 	switch (bitsperchar) {
1355 		case '5':
1356 			charsize=cs_5;
1357 			break;
1358 		case '6':
1359 			charsize=cs_6;
1360 			break;
1361 		case '7':
1362 			charsize=cs_7;
1363 			break;
1364 	}
1365 	characterSize(charsize);
1366 
1367 	switch (parity) {
1368 		case 'E':
1369 			inputParityCheck(true);
1370 			stripParityBits(true);
1371 			parityCheck(true);
1372 			oddParity(false);
1373 			break;
1374 		case 'O':
1375 			inputParityCheck(true);
1376 			stripParityBits(true);
1377 			parityCheck(true);
1378 			oddParity(true);
1379 			break;
1380 		default:
1381 			inputParityCheck(false);
1382 			stripParityBits(false);
1383 			parityCheck(false);
1384 			break;
1385 	}
1386 
1387 
1388 	twoStopBits((stopbits=='2'));
1389 }
1390 
flowControl(serialportprofile::flowcontrol_t flowcontrol)1391 void serialportprofile::flowControl(
1392 		serialportprofile::flowcontrol_t flowcontrol) {
1393 
1394 	if (flowcontrol==fc_none) {
1395 		softwareFlowControlOnOutput(false);
1396 		softwareFlowControlOnInput(false);
1397 		anyCharacterStartsFlow(false);
1398 		hardwareFlowControl(false);
1399 	} else if (flowcontrol==fc_software) {
1400 		softwareFlowControlOnOutput(true);
1401 		softwareFlowControlOnInput(true);
1402 		anyCharacterStartsFlow(true);
1403 		hardwareFlowControl(false);
1404 	} else if (flowcontrol==fc_hardware) {
1405 		softwareFlowControlOnOutput(false);
1406 		softwareFlowControlOnInput(false);
1407 		anyCharacterStartsFlow(false);
1408 		hardwareFlowControl(true);
1409 	}
1410 }
1411 
flowControl()1412 serialportprofile::flowcontrol_t serialportprofile::flowControl() {
1413 	if (hardwareFlowControl()) {
1414 		return fc_hardware;
1415 	} else if (softwareFlowControlOnOutput() ||
1416 			softwareFlowControlOnInput()) {
1417 		return fc_software;
1418 	} else {
1419 		return fc_none;
1420 	}
1421 }
1422 
setOptions(termios * tio)1423 void serialportprofile::setOptions(termios *tio) {
1424 	bytestring::copy(&pvt->_tio,tio,sizeof(pvt->_tio));
1425 }
1426 
getTermios()1427 termios *serialportprofile::getTermios() {
1428 	return &pvt->_tio;
1429 }
1430