LibSerial 1.0.0
LibSerial provides a convenient, object oriented approach to accessing serial ports on POSIX systems.
Loading...
Searching...
No Matches
SerialStream.cpp
1/******************************************************************************
2 * @file SerialStream.cpp *
3 * @copyright (C) 2004-2018 LibSerial Development Team. All rights reserved. *
4 * crayzeewulf@gmail.com *
5 * *
6 * Redistribution and use in source and binary forms, with or without *
7 * modification, are permitted provided that the following conditions *
8 * are met: *
9 * *
10 * 1. Redistributions of source code must retain the above copyright *
11 * notice, this list of conditions and the following disclaimer. *
12 * 2. Redistributions in binary form must reproduce the above copyright *
13 * notice, this list of conditions and the following disclaimer in *
14 * the documentation and/or other materials provided with the *
15 * distribution. *
16 * 3. Neither the name PX4 nor the names of its contributors may be *
17 * used to endorse or promote products derived from this software *
18 * without specific prior written permission. *
19 * *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED *
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
31 * POSSIBILITY OF SUCH DAMAGE. *
32 *****************************************************************************/
33#include "libserial/SerialStream.h"
34
35#include <cassert>
36
37namespace LibSerial
38{
39 SerialStream::SerialStream() : std::iostream(nullptr)
40 {
41 this->flush() ;
42 }
43
44 SerialStream::SerialStream(const std::string& fileName,
45 const BaudRate& baudRate,
46 const CharacterSize& characterSize,
47 const FlowControl& flowControlType,
48 const Parity& parityType,
49 const StopBits& stopBits,
50 bool exclusive) :
51 std::iostream(nullptr)
52 {
53 this->Open(fileName, std::ios_base::in | std::ios_base::out, exclusive) ; // NOLINT (fuchsia-default-arguments)
54 this->SetBaudRate(baudRate) ;
55 this->SetCharacterSize(characterSize) ;
56 this->SetFlowControl(flowControlType) ;
57 this->SetParity(parityType) ;
58 this->SetStopBits(stopBits) ;
59 this->FlushIOBuffers() ;
60 }
61
63 try
64 {
65 // Close the serial stream if it is open.
66 if (this->IsOpen())
67 {
68 this->FlushIOBuffers() ;
69 this->Close() ;
70 }
71 }
72 catch(...)
73 {
74 //
75 // :IMPORTANT: We do not let any exceptions escape the destructor.
76 // (see https://isocpp.org/wiki/faq/exceptions#dtors-shouldnt-throw)
77 //
78 // :TODO: Once we add logging to LibSerial, we should issue a warning
79 // if we reach here.
80 //
81 }
82
83 void
84 SerialStream::Open(const std::string& fileName,
85 const std::ios_base::openmode& openMode,
86 bool exclusive)
87 try
88 {
89 // Create a new SerialStreamBuf if one does not exist.
90 if (mIOBuffer == nullptr)
91 {
92 mIOBuffer = std::make_unique<SerialStreamBuf>() ;
93 assert(mIOBuffer != nullptr) ; // NOLINT (cppcoreguidelines-pro-bounds-array-to-pointer-decay)
94 this->rdbuf(mIOBuffer.get()) ;
95 }
96
97 // Open the serial port.
98 mIOBuffer->Open(fileName, openMode, exclusive) ;
99 }
100 catch (const std::exception&)
101 {
102 setstate(std::ios_base::failbit) ;
103 throw ;
104 }
105
106 void
108 {
109 // If a SerialStreamBuf is associated with this SerialStream
110 // we need to destroy it.
111 mIOBuffer = nullptr ;
112 }
113
114 void
116 try
117 {
118 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
119
120 // Make sure that we are dealing with a SerialStreamBuf before
121 // proceeding. This check also makes sure that we have a non-NULL
122 // buffer associated with this stream.
123 if (my_buffer != nullptr)
124 {
125 // Try to flush the input buffers the serial port with the correspoding
126 // function of the SerialStreamBuf class.
127 my_buffer->DrainWriteBuffer() ;
128 }
129 else
130 {
131 // If the dynamic_cast above failed then we either have a NULL
132 // streambuf associated with this stream or we have a buffer
133 // of class other than SerialStreamBuf. In either case, we
134 // have a problem and we should stop all I/O using this stream.
135 setstate(badbit) ;
136 }
137 }
138 catch (const std::exception&)
139 {
140 setstate(std::ios_base::failbit) ;
141 throw ;
142 }
143
144 void
146 try
147 {
148 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
149
150 // Make sure that we are dealing with a SerialStreamBuf before
151 // proceeding. This check also makes sure that we have a non-NULL
152 // buffer associated with this stream.
153 if (my_buffer != nullptr)
154 {
155 // Try to flush the input buffers the serial port with the correspoding
156 // function of the SerialStreamBuf class.
157 my_buffer->FlushInputBuffer() ;
158 }
159 else
160 {
161 // If the dynamic_cast above failed then we either have a NULL
162 // streambuf associated with this stream or we have a buffer
163 // of class other than SerialStreamBuf. In either case, we
164 // have a problem and we should stop all I/O using this stream.
165 setstate(badbit) ;
166 }
167 }
168 catch (const std::exception&)
169 {
170 setstate(std::ios_base::failbit) ;
171 throw ;
172 }
173
174 void
176 try
177 {
178 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
179
180 // Make sure that we are dealing with a SerialStreamBuf before
181 // proceeding. This check also makes sure that we have a non-NULL
182 // buffer associated with this stream.
183 if (my_buffer != nullptr)
184 {
185 // Try to flush the output buffers the serial port with the correspoding
186 // function of the SerialStreamBuf class.
187 my_buffer->FlushOutputBuffer() ;
188 }
189 else
190 {
191 // If the dynamic_cast above failed then we either have a NULL
192 // streambuf associated with this stream or we have a buffer
193 // of class other than SerialStreamBuf. In either case, we
194 // have a problem and we should stop all I/O using this stream.
195 setstate(badbit) ;
196 }
197 }
198 catch (const std::exception&)
199 {
200 setstate(std::ios_base::failbit) ;
201 throw ;
202 }
203
204 void
206 try
207 {
208 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
209
210 // Make sure that we are dealing with a SerialStreamBuf before
211 // proceeding. This check also makes sure that we have a non-NULL
212 // buffer associated with this stream.
213 if (my_buffer != nullptr)
214 {
215 // Try to flush the I/O buffers the serial port with the correspoding
216 // function of the SerialStreamBuf class.
217 my_buffer->FlushIOBuffers() ;
218 }
219 else
220 {
221 // If the dynamic_cast above failed then we either have a NULL
222 // streambuf associated with this stream or we have a buffer
223 // of class other than SerialStreamBuf. In either case, we
224 // have a problem and we should stop all I/O using this stream.
225 setstate(badbit) ;
226 }
227 }
228 catch (const std::exception&)
229 {
230 setstate(std::ios_base::failbit) ;
231 throw ;
232 }
233
234 bool
236 try
237 {
238 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
239
240 // Make sure that we are dealing with a SerialStreamBuf before
241 // proceeding. This check also makes sure that we have a non-NULL
242 // buffer associated with this stream.
243 if (my_buffer != nullptr)
244 {
245 // Try to determine if data is available with the correspoding
246 // function of the SerialStreamBuf class.
247 return my_buffer->IsDataAvailable() ;
248 }
249 // If the dynamic_cast above failed then we either have a NULL
250 // streambuf associated with this stream or we have a buffer
251 // of class other than SerialStreamBuf. In either case, we
252 // have a problem and we should stop all I/O using this stream.
253 setstate(badbit) ;
254 return false ;
255 }
256 catch (const std::exception&)
257 {
258 setstate(std::ios_base::failbit) ;
259 throw ;
260 }
261
262 bool
264 try
265 {
266 // Checks to see if mIOBuffer is a null buffer, if not, calls
267 // the IsOpen() function on this stream's SerialStreamBuf mIOBuffer
268 if (mIOBuffer == nullptr)
269 {
270 return false;
271 }
272 return mIOBuffer->IsOpen() ;
273 }
274 catch (const std::exception&)
275 {
276 setstate(std::ios_base::failbit) ;
277 throw ;
278 }
279
280 void
281 SerialStream::SetBaudRate(const BaudRate& baudRate)
282 try
283 {
284 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
285
286 // Make sure that we are dealing with a SerialStreamBuf before
287 // proceeding. This check also makes sure that we have a non-NULL
288 // buffer associated with this stream.
289 if (my_buffer != nullptr)
290 {
291 // Try to set the baud rate with the corresponding function of
292 // the SerialStreamBuf class.
293 my_buffer->SetBaudRate(baudRate) ;
294 }
295 else
296 {
297 // If the dynamic_cast above failed then we either have a NULL
298 // streambuf associated with this stream or we have a buffer
299 // of class other than SerialStreamBuf. In either case, we
300 // have a problem and we should stop all I/O using this stream.
301 setstate(badbit) ;
302 }
303 }
304 catch (const std::exception&)
305 {
306 setstate(std::ios_base::failbit) ;
307 throw ;
308 }
309
310 BaudRate
312 try
313 {
314 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
315
316 // Make sure that we are dealing with a SerialStreamBuf before
317 // proceeding. This check also makes sure that we have a non-NULL
318 // buffer associated with this stream.
319 if (my_buffer != nullptr)
320 {
321 // Try to get the baud rate. If the corresponding function of the
322 // SerialStreamBuf class returns BAUD_INVALID, then we have a
323 // problem and the stream is no longer valid for I/O.
324 return my_buffer->GetBaudRate() ;
325 }
326 // If the dynamic_cast above failed then we either have a NULL
327 // streambuf associated with this stream or we have a buffer of
328 // class other than SerialStreamBuf. In either case, we have a
329 // problem and we should stop all I/O using this stream.
330 setstate(badbit) ;
331 return BaudRate::BAUD_INVALID;
332 }
333 catch (const std::exception&)
334 {
335 setstate(std::ios_base::failbit) ;
336 throw ;
337 }
338
339 void
340 SerialStream::SetCharacterSize(const CharacterSize& characterSize)
341 try
342 {
343 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
344
345 // Make sure that we are dealing with a SerialStreamBuf before
346 // proceeding. This check also makes sure that we have a non-NULL
347 // buffer associated with this stream.
348 if (my_buffer != nullptr)
349 {
350 // Try to set the character size with the corresponding function of
351 // the SerialStreamBuf class.
352 my_buffer->SetCharacterSize(characterSize) ;
353 }
354 else
355 {
356 // If the dynamic_cast above failed then we either have a NULL
357 // streambuf associated with this stream or we have a buffer of
358 // class other than SerialStreamBuf. In either case, we have a
359 // problem and we should stop all I/O using this stream.
360 setstate(badbit) ;
361 }
362 }
363 catch (const std::exception&)
364 {
365 setstate(std::ios_base::failbit) ;
366 throw ;
367 }
368
369 CharacterSize
371 try
372 {
373 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
374
375 // Make sure that we are dealing with a SerialStreamBuf before
376 // proceeding. This check also makes sure that we have a non-NULL
377 // buffer associated with this stream.
378 if (my_buffer != nullptr)
379 {
380 // Try to get the character size. If the corresponding function of the
381 // SerialStreamBuf class returns CHAR_SIZE_INVALID, then we have a
382 // problem and the stream is no longer valid for I/O.
383 return my_buffer->GetCharacterSize() ;
384 }
385 // If the dynamic_cast above failed then we either have a NULL
386 // streambuf associated with this stream or we have a buffer of
387 // class other than SerialStreamBuf. In either case, we have a
388 // problem and we should stop all I/O using this stream.
389 setstate(badbit) ;
390 return CharacterSize::CHAR_SIZE_INVALID;
391 }
392 catch (const std::exception&)
393 {
394 setstate(std::ios_base::failbit) ;
395 throw ;
396 }
397
398 void
399 SerialStream::SetFlowControl(const FlowControl& flowControlType)
400 try
401 {
402 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
403
404 // Make sure that we are dealing with a SerialStreamBuf before
405 // proceeding. This check also makes sure that we have a non-NULL
406 // buffer associated with this stream.
407 if (my_buffer != nullptr)
408 {
409 // Try to set the flow control. If the corresponding function of the
410 // SerialStreamBuf class returns FLOW_CONTROL_INVALID, then we have a
411 // problem and the stream is no longer valid for I/O.
412 my_buffer->SetFlowControl(flowControlType) ;
413 }
414 else
415 {
416 // If the dynamic_cast above failed then we either have a NULL
417 // streambuf associated with this stream or we have a buffer of
418 // class other than SerialStreamBuf. In either case, we have a
419 // problem and we should stop all I/O using this stream.
420 setstate(badbit) ;
421 }
422 }
423 catch (const std::exception&)
424 {
425 setstate(std::ios_base::failbit) ;
426 throw ;
427 }
428
429 FlowControl
431 try
432 {
433 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
434
435 // Make sure that we are dealing with a SerialStreamBuf before
436 // proceeding. This check also makes sure that we have a non-NULL
437 // buffer associated with this stream.
438 if (my_buffer != nullptr)
439 {
440 // Try to get the flow control. If the corresponding function of the
441 // SerialStreamBuf class returns FLOW_CONTROL_INVALID, then we have a
442 // problem and the stream is no longer valid for I/O.
443 return my_buffer->GetFlowControl() ;
444 }
445 // If the dynamic_cast above failed then we either have a NULL
446 // streambuf associated with this stream or we have a buffer of
447 // class other than SerialStreamBuf. In either case, we have a
448 // problem and we should stop all I/O using this stream.
449 setstate(badbit) ;
450 return FlowControl::FLOW_CONTROL_INVALID;
451 }
452 catch (const std::exception&)
453 {
454 setstate(std::ios_base::failbit) ;
455 throw ;
456 }
457
458 void
459 SerialStream::SetParity(const Parity& parityType)
460 try
461 {
462 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
463
464 // Make sure that we are dealing with a SerialStreamBuf before
465 // proceeding. This check also makes sure that we have a non-NULL
466 // buffer associated with this stream.
467 if (my_buffer != nullptr)
468 {
469 // Try to set the parity type. If the corresponding function of the
470 // SerialStreamBuf class returns PARITY_INVALID, then we have a
471 // problem and the stream is no longer valid for I/O.
472 my_buffer->SetParity(parityType) ;
473 }
474 else
475 {
476 // If the dynamic_cast above failed then we either have a NULL
477 // streambuf associated with this stream or we have a buffer of
478 // class other than SerialStreamBuf. In either case, we have a
479 // problem and we should stop all I/O using this stream.
480 setstate(badbit) ;
481 }
482 }
483 catch (const std::exception&)
484 {
485 setstate(std::ios_base::failbit) ;
486 throw ;
487 }
488
489 Parity
491 try
492 {
493 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
494
495 // Make sure that we are dealing with a SerialStreamBuf before
496 // proceeding. This check also makes sure that we have a non-NULL
497 // buffer associated with this stream.
498 if (my_buffer != nullptr)
499 {
500 // Try to get the parity type. If the corresponding function of the
501 // SerialStreamBuf class returns PARITY_INVALID, then we have a
502 // problem and the stream is no longer valid for I/O.
503 return my_buffer->GetParity() ;
504 }
505 // If the dynamic_cast above failed then we either have a NULL
506 // streambuf associated with this stream or we have a buffer of
507 // class other than SerialStreamBuf. In either case, we have a
508 // problem and we should stop all I/O using this stream.
509 setstate(badbit) ;
510 return Parity::PARITY_INVALID;
511 }
512 catch (const std::exception&)
513 {
514 setstate(std::ios_base::failbit) ;
515 throw ;
516 }
517
518 void
519 SerialStream::SetStopBits(const StopBits& stopBits)
520 try
521 {
522 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
523
524 // Make sure that we are dealing with a SerialStreamBuf before
525 // proceeding. This check also makes sure that we have a non-NULL
526 // buffer associated with this stream.
527 if (my_buffer != nullptr)
528 {
529 // Try to set the number of stop bits. If the corresponding function of the
530 // SerialStreamBuf class returns STOP_BITS_INVALID, then we have a
531 // problem and the stream is no longer valid for I/O.
532 my_buffer->SetStopBits(stopBits) ;
533 }
534 else
535 {
536 // If the dynamic_cast above failed then we either have a NULL
537 // streambuf associated with this stream or we have a buffer of
538 // class other than SerialStreamBuf. In either case, we have a
539 // problem and we should stop all I/O using this stream.
540 setstate(badbit) ;
541 }
542 }
543 catch (const std::exception&)
544 {
545 setstate(std::ios_base::failbit) ;
546 throw ;
547 }
548
549 StopBits
551 try
552 {
553 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
554
555 // Make sure that we are dealing with a SerialStreamBuf before
556 // proceeding. This check also makes sure that we have a non-NULL
557 // buffer associated with this stream.
558 if (my_buffer != nullptr)
559 {
560 // Try to get the number of stop bits. If the corresponding function of the
561 // SerialStreamBuf class returns STOP_BITS_INVALID, then we have a
562 // problem and the stream is no longer valid for I/O.
563 return my_buffer->GetStopBits() ;
564 }
565 // If the dynamic_cast above failed then we either have a NULL
566 // streambuf associated with this stream or we have a buffer of
567 // class other than SerialStreamBuf. In either case, we have a
568 // problem and we should stop all I/O using this stream.
569 setstate(badbit) ;
570 return StopBits::STOP_BITS_INVALID;
571 }
572 catch (const std::exception&)
573 {
574 setstate(std::ios_base::failbit) ;
575 throw ;
576 }
577
578 void
579 SerialStream::SetVMin(const short vmin)
580 try
581 {
582 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
583
584 // Make sure that we are dealing with a SerialStreamBuf before
585 // proceeding. This check also makes sure that we have a non-NULL
586 // buffer associated with this stream.
587 if (my_buffer != nullptr)
588 {
589 // Try to set the vMin number of characters.
590 my_buffer->SetVMin(vmin) ;
591 }
592 else
593 {
594 // If the dynamic_cast above failed then we either have a NULL
595 // streambuf associated with this stream or we have a buffer of
596 // class other than SerialStreamBuf. In either case, we have a
597 // problem and we should stop all I/O using this stream.
598 setstate(badbit) ;
599 }
600 }
601 catch (const std::exception&)
602 {
603 setstate(std::ios_base::failbit) ;
604 throw ;
605 }
606
607 short
609 try
610 {
611 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
612
613 // Make sure that we are dealing with a SerialStreamBuf before
614 // proceeding. This check also makes sure that we have a non-NULL
615 // buffer associated with this stream.
616 if (my_buffer != nullptr)
617 {
618 // Try to get the vMin number of characters.
619 return my_buffer->GetVMin() ;
620 }
621 // If the dynamic_cast above failed then we either have a NULL
622 // streambuf associated with this stream or we have a buffer of
623 // class other than SerialStreamBuf. In either case, we have a
624 // problem and we should stop all I/O using this stream.
625 setstate(badbit) ;
626 return -1;
627 }
628 catch (const std::exception&)
629 {
630 setstate(std::ios_base::failbit) ;
631 throw ;
632 }
633
634 void
635 SerialStream::SetVTime(const short vtime)
636 try
637 {
638 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
639
640 // Make sure that we are dealing with a SerialStreamBuf before
641 // proceeding. This check also makes sure that we have a non-NULL
642 // buffer associated with this stream.
643 if (my_buffer != nullptr)
644 {
645 // Try to set the vTime duration in deciseconds.
646 my_buffer->SetVTime(vtime) ;
647 }
648 else
649 {
650 // If the dynamic_cast above failed then we either have a NULL
651 // streambuf associated with this stream or we have a buffer of
652 // class other than SerialStreamBuf. In either case, we have a
653 // problem and we should stop all I/O using this stream.
654 setstate(badbit) ;
655 }
656 }
657 catch (const std::exception&)
658 {
659 setstate(std::ios_base::failbit) ;
660 throw ;
661 }
662
663 short
665 try
666 {
667 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
668
669 // Make sure that we are dealing with a SerialStreamBuf before
670 // proceeding. This check also makes sure that we have a non-NULL
671 // buffer associated with this stream.
672 if (my_buffer != nullptr)
673 {
674 // Try to get the vTime duration in deciseconds.
675 return my_buffer->GetVTime() ;
676 }
677 // If the dynamic_cast above failed then we either have a NULL
678 // streambuf associated with this stream or we have a buffer of
679 // class other than SerialStreamBuf. In either case, we have a
680 // problem and we should stop all I/O using this stream.
681 setstate(badbit) ;
682 return -1;
683 }
684 catch (const std::exception&)
685 {
686 setstate(std::ios_base::failbit) ;
687 throw ;
688 }
689
690 void
691 SerialStream::SetDTR(const bool dtrState)
692 try
693 {
694 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
695
696 // Make sure that we are dealing with a SerialStreamBuf before
697 // proceeding. This check also makes sure that we have a non-NULL
698 // buffer associated with this stream.
699 if (my_buffer != nullptr)
700 {
701 // Try to set the dtr line state.
702 my_buffer->SetDTR(dtrState) ;
703 }
704 else
705 {
706 // If the dynamic_cast above failed then we either have a NULL
707 // streambuf associated with this stream or we have a buffer of
708 // class other than SerialStreamBuf. In either case, we have a
709 // problem and we should stop all I/O using this stream.
710 setstate(badbit) ;
711 }
712 }
713 catch (const std::exception&)
714 {
715 setstate(std::ios_base::failbit) ;
716 throw ;
717 }
718
719 bool
721 try
722 {
723 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
724
725 // Make sure that we are dealing with a SerialStreamBuf before
726 // proceeding. This check also makes sure that we have a non-NULL
727 // buffer associated with this stream.
728 if (my_buffer != nullptr)
729 {
730 // Try to get the vTime duration in deciseconds.
731 return my_buffer->GetDTR() ;
732 }
733 // If the dynamic_cast above failed then we either have a NULL
734 // streambuf associated with this stream or we have a buffer of
735 // class other than SerialStreamBuf. In either case, we have a
736 // problem and we should stop all I/O using this stream.
737 setstate(badbit) ;
738 return false ;
739 }
740 catch (const std::exception&)
741 {
742 setstate(std::ios_base::failbit) ;
743 throw ;
744 }
745
746 void
747 SerialStream::SetRTS(const bool rtsState)
748 try
749 {
750 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
751
752 // Make sure that we are dealing with a SerialStreamBuf before
753 // proceeding. This check also makes sure that we have a non-NULL
754 // buffer associated with this stream.
755 if (my_buffer != nullptr)
756 {
757 // Try to set the RTS line state.
758 my_buffer->SetRTS(rtsState) ;
759 }
760 else
761 {
762 // If the dynamic_cast above failed then we either have a NULL
763 // streambuf associated with this stream or we have a buffer of
764 // class other than SerialStreamBuf. In either case, we have a
765 // problem and we should stop all I/O using this stream.
766 setstate(badbit) ;
767 }
768 }
769 catch (const std::exception&)
770 {
771 setstate(std::ios_base::failbit) ;
772 throw ;
773 }
774
775 bool
777 try
778 {
779 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
780
781 // Make sure that we are dealing with a SerialStreamBuf before
782 // proceeding. This check also makes sure that we have a non-NULL
783 // buffer associated with this stream.
784 if (my_buffer != nullptr)
785 {
786 // Try to get the RTS line state.
787 return my_buffer->GetRTS() ;
788 }
789 // If the dynamic_cast above failed then we either have a NULL
790 // streambuf associated with this stream or we have a buffer of
791 // class other than SerialStreamBuf. In either case, we have a
792 // problem and we should stop all I/O using this stream.
793 setstate(badbit) ;
794 return false ;
795 }
796 catch (const std::exception&)
797 {
798 setstate(std::ios_base::failbit) ;
799 throw ;
800 }
801
802 bool
804 try
805 {
806 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
807
808 // Make sure that we are dealing with a SerialStreamBuf before
809 // proceeding. This check also makes sure that we have a non-NULL
810 // buffer associated with this stream.
811 if (my_buffer != nullptr)
812 {
813 // Try to get the CTS line state.
814 return my_buffer->GetCTS() ;
815 }
816 // If the dynamic_cast above failed then we either have a NULL
817 // streambuf associated with this stream or we have a buffer of
818 // class other than SerialStreamBuf. In either case, we have a
819 // problem and we should stop all I/O using this stream.
820 setstate(badbit) ;
821 return false ;
822 }
823 catch (const std::exception&)
824 {
825 setstate(std::ios_base::failbit) ;
826 throw ;
827 }
828
829 bool
831 try
832 {
833 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
834
835 // Make sure that we are dealing with a SerialStreamBuf before
836 // proceeding. This check also makes sure that we have a non-NULL
837 // buffer associated with this stream.
838 if (my_buffer != nullptr)
839 {
840 // Try to get the DSR line state.
841 return my_buffer->GetDSR() ;
842 }
843 // If the dynamic_cast above failed then we either have a NULL
844 // streambuf associated with this stream or we have a buffer of
845 // class other than SerialStreamBuf. In either case, we have a
846 // problem and we should stop all I/O using this stream.
847 setstate(badbit) ;
848 return false ;
849 }
850 catch (const std::exception&)
851 {
852 setstate(std::ios_base::failbit) ;
853 throw ;
854 }
855
856 int
858 try
859 {
860 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
861
862 // Make sure that we are dealing with a SerialStreamBuf before
863 // proceeding. This check also makes sure that we have a non-NULL
864 // buffer associated with this stream.
865 if (my_buffer != nullptr)
866 {
867 // Try to get the file descriptor.
868 return my_buffer->GetFileDescriptor() ;
869 }
870 // If the dynamic_cast above failed then we either have a NULL
871 // streambuf associated with this stream or we have a buffer of
872 // class other than SerialStreamBuf. In either case, we have a
873 // problem and we should stop all I/O using this stream.
874 setstate(badbit) ;
875 return -1;
876 }
877 catch (const std::exception&)
878 {
879 setstate(std::ios_base::failbit) ;
880 throw ;
881 }
882
883 int
885 try
886 {
887 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
888
889 // Make sure that we are dealing with a SerialStreamBuf before
890 // proceeding. This check also makes sure that we have a non-NULL
891 // buffer associated with this stream.
892 if (my_buffer != nullptr)
893 {
894 // Try to determine if data is available with the correspoding
895 // function of the SerialStreamBuf class.
896 return my_buffer->GetNumberOfBytesAvailable() ;
897 }
898 // If the dynamic_cast above failed then we either have a NULL
899 // streambuf associated with this stream or we have a buffer
900 // of class other than SerialStreamBuf. In either case, we
901 // have a problem and we should stop all I/O using this stream.
902 setstate(badbit) ;
903 return -1 ;
904 }
905 catch (const std::exception&)
906 {
907 setstate(std::ios_base::failbit) ;
908 throw ;
909 }
910
911#ifdef __linux__
912 std::vector<std::string>
914 try
915 {
916 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
917
918 // Make sure that we are dealing with a SerialStreamBuf before
919 // proceeding. This check also makes sure that we have a non-NULL
920 // buffer associated with this stream.
921 if (my_buffer != nullptr)
922 {
923 // Try to get the file descriptor.
924 return my_buffer->GetAvailableSerialPorts() ;
925 }
926 // If the dynamic_cast above failed then we either have a NULL
927 // streambuf associated with this stream or we have a buffer of
928 // class other than SerialStreamBuf. In either case, we have a
929 // problem and we should stop all I/O using this stream.
930 setstate(badbit) ;
931 return {} ;
932 }
933 catch (const std::exception&)
934 {
935 setstate(std::ios_base::failbit) ;
936 throw ;
937 }
938#endif
939} // namespace LibSerial
SerialStreamBuf is the streambuf subclass used by SerialStream. This subclass takes care of opening t...
CharacterSize GetCharacterSize() const
Gets the character size being used for serial communication.
bool GetCTS()
Get the status of the CTS line.
int GetNumberOfBytesAvailable()
Gets the number of bytes available in the read buffer.
bool IsDataAvailable()
Checks if data is available at the input of the serial port.
void FlushOutputBuffer()
Flushes the serial port output buffer.
StopBits GetStopBits() const
Gets the number of stop bits currently being used by the serial.
void SetDTR(const bool dtrState=true)
Sets the DTR line to the specified value.
short GetVMin() const
Gets the VMIN value for the device, which represents the minimum number of characters for non-canonic...
bool GetDSR()
Get the status of the DSR line.
void SetVTime(const short vtime)
Sets character buffer timeout for non-canonical reads in deciseconds.
bool GetRTS() const
Get the status of the RTS line.
short GetVTime() const
Gets the current timeout value for non-canonical reads in deciseconds.
bool GetDTR() const
Gets the status of the DTR line.
void SetCharacterSize(const CharacterSize &characterSize)
Sets the character size for the serial port.
void SetVMin(const short vmin)
Sets the minimum number of characters for non-canonical reads.
FlowControl GetFlowControl() const
Gets the current flow control setting.
void DrainWriteBuffer()
Waits until the write buffer is drained and then returns.
BaudRate GetBaudRate() const
Gets the current baud rate for the serial port.
void SetParity(const Parity &parityType)
Sets the parity type for the serial port.
void SetBaudRate(const BaudRate &baudRate)
Sets the baud rate for the serial port to the specified value.
Parity GetParity() const
Gets the parity type for the serial port.
void FlushIOBuffers()
Flushes the serial port input and output buffers.
void SetFlowControl(const FlowControl &flowControlType)
Sets flow control for the serial port.
void FlushInputBuffer()
Flushes the serial port input buffer.
int GetFileDescriptor() const
Gets the serial port file descriptor.
void SetStopBits(const StopBits &stopBits)
Sets the number of stop bits to be used with the serial port.
void SetRTS(const bool rtsState=true)
Set the RTS line to the specified value.
void FlushIOBuffers()
Flushes the serial port input and output buffers.
void DrainWriteBuffer()
Waits until the write buffer is drained and then returns.
short GetVMin()
Gets the VMIN value for the device, which represents the minimum number of characters for non-canonic...
BaudRate GetBaudRate()
Gets the current baud rate for the serial port.
bool GetDSR()
Get the status of the DSR line.
void SetCharacterSize(const CharacterSize &characterSize)
Sets the character size for the serial port.
bool GetCTS()
Get the status of the CTS line.
void SetBaudRate(const BaudRate &baudRate)
Sets the baud rate for the serial port to the specified value.
int GetNumberOfBytesAvailable()
Gets the number of bytes available in the read buffer.
bool IsDataAvailable()
Checks if data is available at the input of the serial port.
void FlushInputBuffer()
Flushes the serial port input buffer.
short GetVTime()
Gets the current timeout value for non-canonical reads in deciseconds.
void Close()
Closes the serial port. All settings of the serial port will be lost and no more I/O can be performed...
virtual ~SerialStream()
Default Destructor for a SerialStream object Closes the stream associated with mFileDescriptor,...
StopBits GetStopBits()
Gets the number of stop bits currently being used by the serial.
void SetDTR(const bool dtrState=true)
Sets the DTR line to the specified value.
void SetFlowControl(const FlowControl &flowControlType)
Sets flow control for the serial port.
int GetFileDescriptor()
Gets the serial port file descriptor.
SerialStream()
Default Contructor. Creates a new SerialStream object but does not open it. The Open() method will ne...
FlowControl GetFlowControl()
Gets the current flow control setting.
void SetVMin(const short vmin)
Sets the minimum number of characters for non-canonical reads.
void SetStopBits(const StopBits &stopBits)
Sets the number of stop bits to be used with the serial port.
void SetVTime(const short vtime)
Sets character buffer timeout for non-canonical reads in deciseconds.
bool IsOpen()
Determines if the serial port is open for I/O.
void Open(const std::string &fileName, const std::ios_base::openmode &openMode=std::ios_base::in|std::ios_base::out, bool exclusive=true)
Opens the serial port associated with the specified file name and the specified mode.
bool GetDTR()
Gets the status of the DTR line.
CharacterSize GetCharacterSize()
Gets the character size being used for serial communication.
void SetRTS(const bool rtsState=true)
Set the RTS line to the specified value.
std::vector< std::string > GetAvailableSerialPorts()
Gets a list of available serial ports.
void FlushOutputBuffer()
Flushes the serial port output buffer.
Parity GetParity()
Gets the parity type for the serial port.
bool GetRTS()
Get the status of the RTS line.
void SetParity(const Parity &parityType)
Sets the parity type for the serial port.