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 std::iostream(nullptr)
51 {
52 this->Open(fileName) ; // NOLINT (fuchsia-default-arguments)
53 this->SetBaudRate(baudRate) ;
54 this->SetCharacterSize(characterSize) ;
55 this->SetFlowControl(flowControlType) ;
56 this->SetParity(parityType) ;
57 this->SetStopBits(stopBits) ;
58 this->FlushIOBuffers() ;
59 }
60
62 try
63 {
64 // Close the serial stream if it is open.
65 if (this->IsOpen())
66 {
67 this->FlushIOBuffers() ;
68 this->Close() ;
69 }
70 }
71 catch(...)
72 {
73 //
74 // :IMPORTANT: We do not let any exceptions escape the destructor.
75 // (see https://isocpp.org/wiki/faq/exceptions#dtors-shouldnt-throw)
76 //
77 // :TODO: Once we add logging to LibSerial, we should issue a warning
78 // if we reach here.
79 //
80 }
81
82 void
83 SerialStream::Open(const std::string& fileName,
84 const std::ios_base::openmode& openMode)
85 try
86 {
87 // Create a new SerialStreamBuf if one does not exist.
88 if (mIOBuffer == nullptr)
89 {
90 mIOBuffer = std::make_unique<SerialStreamBuf>() ;
91 assert(mIOBuffer != nullptr) ; // NOLINT (cppcoreguidelines-pro-bounds-array-to-pointer-decay)
92 this->rdbuf(mIOBuffer.get()) ;
93 }
94
95 // Open the serial port.
96 mIOBuffer->Open(fileName, openMode) ;
97 }
98 catch (const std::exception&)
99 {
100 setstate(std::ios_base::failbit) ;
101 throw ;
102 }
103
104 void
106 {
107 // If a SerialStreamBuf is associated with this SerialStream
108 // we need to destroy it.
109 mIOBuffer = nullptr ;
110 }
111
112 void
114 try
115 {
116 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
117
118 // Make sure that we are dealing with a SerialStreamBuf before
119 // proceeding. This check also makes sure that we have a non-NULL
120 // buffer associated with this stream.
121 if (my_buffer != nullptr)
122 {
123 // Try to flush the input buffers the serial port with the correspoding
124 // function of the SerialStreamBuf class.
125 my_buffer->DrainWriteBuffer() ;
126 }
127 else
128 {
129 // If the dynamic_cast above failed then we either have a NULL
130 // streambuf associated with this stream or we have a buffer
131 // of class other than SerialStreamBuf. In either case, we
132 // have a problem and we should stop all I/O using this stream.
133 setstate(badbit) ;
134 }
135 }
136 catch (const std::exception&)
137 {
138 setstate(std::ios_base::failbit) ;
139 throw ;
140 }
141
142 void
144 try
145 {
146 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
147
148 // Make sure that we are dealing with a SerialStreamBuf before
149 // proceeding. This check also makes sure that we have a non-NULL
150 // buffer associated with this stream.
151 if (my_buffer != nullptr)
152 {
153 // Try to flush the input buffers the serial port with the correspoding
154 // function of the SerialStreamBuf class.
155 my_buffer->FlushInputBuffer() ;
156 }
157 else
158 {
159 // If the dynamic_cast above failed then we either have a NULL
160 // streambuf associated with this stream or we have a buffer
161 // of class other than SerialStreamBuf. In either case, we
162 // have a problem and we should stop all I/O using this stream.
163 setstate(badbit) ;
164 }
165 }
166 catch (const std::exception&)
167 {
168 setstate(std::ios_base::failbit) ;
169 throw ;
170 }
171
172 void
174 try
175 {
176 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
177
178 // Make sure that we are dealing with a SerialStreamBuf before
179 // proceeding. This check also makes sure that we have a non-NULL
180 // buffer associated with this stream.
181 if (my_buffer != nullptr)
182 {
183 // Try to flush the output buffers the serial port with the correspoding
184 // function of the SerialStreamBuf class.
185 my_buffer->FlushOutputBuffer() ;
186 }
187 else
188 {
189 // If the dynamic_cast above failed then we either have a NULL
190 // streambuf associated with this stream or we have a buffer
191 // of class other than SerialStreamBuf. In either case, we
192 // have a problem and we should stop all I/O using this stream.
193 setstate(badbit) ;
194 }
195 }
196 catch (const std::exception&)
197 {
198 setstate(std::ios_base::failbit) ;
199 throw ;
200 }
201
202 void
204 try
205 {
206 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
207
208 // Make sure that we are dealing with a SerialStreamBuf before
209 // proceeding. This check also makes sure that we have a non-NULL
210 // buffer associated with this stream.
211 if (my_buffer != nullptr)
212 {
213 // Try to flush the I/O buffers the serial port with the correspoding
214 // function of the SerialStreamBuf class.
215 my_buffer->FlushIOBuffers() ;
216 }
217 else
218 {
219 // If the dynamic_cast above failed then we either have a NULL
220 // streambuf associated with this stream or we have a buffer
221 // of class other than SerialStreamBuf. In either case, we
222 // have a problem and we should stop all I/O using this stream.
223 setstate(badbit) ;
224 }
225 }
226 catch (const std::exception&)
227 {
228 setstate(std::ios_base::failbit) ;
229 throw ;
230 }
231
232 bool
234 try
235 {
236 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
237
238 // Make sure that we are dealing with a SerialStreamBuf before
239 // proceeding. This check also makes sure that we have a non-NULL
240 // buffer associated with this stream.
241 if (my_buffer != nullptr)
242 {
243 // Try to determine if data is available with the correspoding
244 // function of the SerialStreamBuf class.
245 return my_buffer->IsDataAvailable() ;
246 }
247 // If the dynamic_cast above failed then we either have a NULL
248 // streambuf associated with this stream or we have a buffer
249 // of class other than SerialStreamBuf. In either case, we
250 // have a problem and we should stop all I/O using this stream.
251 setstate(badbit) ;
252 return false ;
253 }
254 catch (const std::exception&)
255 {
256 setstate(std::ios_base::failbit) ;
257 throw ;
258 }
259
260 bool
262 try
263 {
264 // Checks to see if mIOBuffer is a null buffer, if not, calls
265 // the IsOpen() function on this stream's SerialStreamBuf mIOBuffer
266 if (mIOBuffer == nullptr)
267 {
268 return false;
269 }
270 return mIOBuffer->IsOpen() ;
271 }
272 catch (const std::exception&)
273 {
274 setstate(std::ios_base::failbit) ;
275 throw ;
276 }
277
278 void
279 SerialStream::SetBaudRate(const BaudRate& baudRate)
280 try
281 {
282 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
283
284 // Make sure that we are dealing with a SerialStreamBuf before
285 // proceeding. This check also makes sure that we have a non-NULL
286 // buffer associated with this stream.
287 if (my_buffer != nullptr)
288 {
289 // Try to set the baud rate with the corresponding function of
290 // the SerialStreamBuf class.
291 my_buffer->SetBaudRate(baudRate) ;
292 }
293 else
294 {
295 // If the dynamic_cast above failed then we either have a NULL
296 // streambuf associated with this stream or we have a buffer
297 // of class other than SerialStreamBuf. In either case, we
298 // have a problem and we should stop all I/O using this stream.
299 setstate(badbit) ;
300 }
301 }
302 catch (const std::exception&)
303 {
304 setstate(std::ios_base::failbit) ;
305 throw ;
306 }
307
308 BaudRate
310 try
311 {
312 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
313
314 // Make sure that we are dealing with a SerialStreamBuf before
315 // proceeding. This check also makes sure that we have a non-NULL
316 // buffer associated with this stream.
317 if (my_buffer != nullptr)
318 {
319 // Try to get the baud rate. If the corresponding function of the
320 // SerialStreamBuf class returns BAUD_INVALID, then we have a
321 // problem and the stream is no longer valid for I/O.
322 return my_buffer->GetBaudRate() ;
323 }
324 // If the dynamic_cast above failed then we either have a NULL
325 // streambuf associated with this stream or we have a buffer of
326 // class other than SerialStreamBuf. In either case, we have a
327 // problem and we should stop all I/O using this stream.
328 setstate(badbit) ;
329 return BaudRate::BAUD_INVALID;
330 }
331 catch (const std::exception&)
332 {
333 setstate(std::ios_base::failbit) ;
334 throw ;
335 }
336
337 void
338 SerialStream::SetCharacterSize(const CharacterSize& characterSize)
339 try
340 {
341 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
342
343 // Make sure that we are dealing with a SerialStreamBuf before
344 // proceeding. This check also makes sure that we have a non-NULL
345 // buffer associated with this stream.
346 if (my_buffer != nullptr)
347 {
348 // Try to set the character size with the corresponding function of
349 // the SerialStreamBuf class.
350 my_buffer->SetCharacterSize(characterSize) ;
351 }
352 else
353 {
354 // If the dynamic_cast above failed then we either have a NULL
355 // streambuf associated with this stream or we have a buffer of
356 // class other than SerialStreamBuf. In either case, we have a
357 // problem and we should stop all I/O using this stream.
358 setstate(badbit) ;
359 }
360 }
361 catch (const std::exception&)
362 {
363 setstate(std::ios_base::failbit) ;
364 throw ;
365 }
366
367 CharacterSize
369 try
370 {
371 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
372
373 // Make sure that we are dealing with a SerialStreamBuf before
374 // proceeding. This check also makes sure that we have a non-NULL
375 // buffer associated with this stream.
376 if (my_buffer != nullptr)
377 {
378 // Try to get the character size. If the corresponding function of the
379 // SerialStreamBuf class returns CHAR_SIZE_INVALID, then we have a
380 // problem and the stream is no longer valid for I/O.
381 return my_buffer->GetCharacterSize() ;
382 }
383 // If the dynamic_cast above failed then we either have a NULL
384 // streambuf associated with this stream or we have a buffer of
385 // class other than SerialStreamBuf. In either case, we have a
386 // problem and we should stop all I/O using this stream.
387 setstate(badbit) ;
388 return CharacterSize::CHAR_SIZE_INVALID;
389 }
390 catch (const std::exception&)
391 {
392 setstate(std::ios_base::failbit) ;
393 throw ;
394 }
395
396 void
397 SerialStream::SetFlowControl(const FlowControl& flowControlType)
398 try
399 {
400 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
401
402 // Make sure that we are dealing with a SerialStreamBuf before
403 // proceeding. This check also makes sure that we have a non-NULL
404 // buffer associated with this stream.
405 if (my_buffer != nullptr)
406 {
407 // Try to set the flow control. If the corresponding function of the
408 // SerialStreamBuf class returns FLOW_CONTROL_INVALID, then we have a
409 // problem and the stream is no longer valid for I/O.
410 my_buffer->SetFlowControl(flowControlType) ;
411 }
412 else
413 {
414 // If the dynamic_cast above failed then we either have a NULL
415 // streambuf associated with this stream or we have a buffer of
416 // class other than SerialStreamBuf. In either case, we have a
417 // problem and we should stop all I/O using this stream.
418 setstate(badbit) ;
419 }
420 }
421 catch (const std::exception&)
422 {
423 setstate(std::ios_base::failbit) ;
424 throw ;
425 }
426
427 FlowControl
429 try
430 {
431 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
432
433 // Make sure that we are dealing with a SerialStreamBuf before
434 // proceeding. This check also makes sure that we have a non-NULL
435 // buffer associated with this stream.
436 if (my_buffer != nullptr)
437 {
438 // Try to get the flow control. If the corresponding function of the
439 // SerialStreamBuf class returns FLOW_CONTROL_INVALID, then we have a
440 // problem and the stream is no longer valid for I/O.
441 return my_buffer->GetFlowControl() ;
442 }
443 // If the dynamic_cast above failed then we either have a NULL
444 // streambuf associated with this stream or we have a buffer of
445 // class other than SerialStreamBuf. In either case, we have a
446 // problem and we should stop all I/O using this stream.
447 setstate(badbit) ;
448 return FlowControl::FLOW_CONTROL_INVALID;
449 }
450 catch (const std::exception&)
451 {
452 setstate(std::ios_base::failbit) ;
453 throw ;
454 }
455
456 void
457 SerialStream::SetParity(const Parity& parityType)
458 try
459 {
460 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
461
462 // Make sure that we are dealing with a SerialStreamBuf before
463 // proceeding. This check also makes sure that we have a non-NULL
464 // buffer associated with this stream.
465 if (my_buffer != nullptr)
466 {
467 // Try to set the parity type. If the corresponding function of the
468 // SerialStreamBuf class returns PARITY_INVALID, then we have a
469 // problem and the stream is no longer valid for I/O.
470 my_buffer->SetParity(parityType) ;
471 }
472 else
473 {
474 // If the dynamic_cast above failed then we either have a NULL
475 // streambuf associated with this stream or we have a buffer of
476 // class other than SerialStreamBuf. In either case, we have a
477 // problem and we should stop all I/O using this stream.
478 setstate(badbit) ;
479 }
480 }
481 catch (const std::exception&)
482 {
483 setstate(std::ios_base::failbit) ;
484 throw ;
485 }
486
487 Parity
489 try
490 {
491 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
492
493 // Make sure that we are dealing with a SerialStreamBuf before
494 // proceeding. This check also makes sure that we have a non-NULL
495 // buffer associated with this stream.
496 if (my_buffer != nullptr)
497 {
498 // Try to get the parity type. If the corresponding function of the
499 // SerialStreamBuf class returns PARITY_INVALID, then we have a
500 // problem and the stream is no longer valid for I/O.
501 return my_buffer->GetParity() ;
502 }
503 // If the dynamic_cast above failed then we either have a NULL
504 // streambuf associated with this stream or we have a buffer of
505 // class other than SerialStreamBuf. In either case, we have a
506 // problem and we should stop all I/O using this stream.
507 setstate(badbit) ;
508 return Parity::PARITY_INVALID;
509 }
510 catch (const std::exception&)
511 {
512 setstate(std::ios_base::failbit) ;
513 throw ;
514 }
515
516 void
517 SerialStream::SetStopBits(const StopBits& stopBits)
518 try
519 {
520 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
521
522 // Make sure that we are dealing with a SerialStreamBuf before
523 // proceeding. This check also makes sure that we have a non-NULL
524 // buffer associated with this stream.
525 if (my_buffer != nullptr)
526 {
527 // Try to set the number of stop bits. If the corresponding function of the
528 // SerialStreamBuf class returns STOP_BITS_INVALID, then we have a
529 // problem and the stream is no longer valid for I/O.
530 my_buffer->SetStopBits(stopBits) ;
531 }
532 else
533 {
534 // If the dynamic_cast above failed then we either have a NULL
535 // streambuf associated with this stream or we have a buffer of
536 // class other than SerialStreamBuf. In either case, we have a
537 // problem and we should stop all I/O using this stream.
538 setstate(badbit) ;
539 }
540 }
541 catch (const std::exception&)
542 {
543 setstate(std::ios_base::failbit) ;
544 throw ;
545 }
546
547 StopBits
549 try
550 {
551 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
552
553 // Make sure that we are dealing with a SerialStreamBuf before
554 // proceeding. This check also makes sure that we have a non-NULL
555 // buffer associated with this stream.
556 if (my_buffer != nullptr)
557 {
558 // Try to get the number of stop bits. If the corresponding function of the
559 // SerialStreamBuf class returns STOP_BITS_INVALID, then we have a
560 // problem and the stream is no longer valid for I/O.
561 return my_buffer->GetStopBits() ;
562 }
563 // If the dynamic_cast above failed then we either have a NULL
564 // streambuf associated with this stream or we have a buffer of
565 // class other than SerialStreamBuf. In either case, we have a
566 // problem and we should stop all I/O using this stream.
567 setstate(badbit) ;
568 return StopBits::STOP_BITS_INVALID;
569 }
570 catch (const std::exception&)
571 {
572 setstate(std::ios_base::failbit) ;
573 throw ;
574 }
575
576 void
577 SerialStream::SetVMin(const short vmin)
578 try
579 {
580 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
581
582 // Make sure that we are dealing with a SerialStreamBuf before
583 // proceeding. This check also makes sure that we have a non-NULL
584 // buffer associated with this stream.
585 if (my_buffer != nullptr)
586 {
587 // Try to set the vMin number of characters.
588 my_buffer->SetVMin(vmin) ;
589 }
590 else
591 {
592 // If the dynamic_cast above failed then we either have a NULL
593 // streambuf associated with this stream or we have a buffer of
594 // class other than SerialStreamBuf. In either case, we have a
595 // problem and we should stop all I/O using this stream.
596 setstate(badbit) ;
597 }
598 }
599 catch (const std::exception&)
600 {
601 setstate(std::ios_base::failbit) ;
602 throw ;
603 }
604
605 short
607 try
608 {
609 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
610
611 // Make sure that we are dealing with a SerialStreamBuf before
612 // proceeding. This check also makes sure that we have a non-NULL
613 // buffer associated with this stream.
614 if (my_buffer != nullptr)
615 {
616 // Try to get the vMin number of characters.
617 return my_buffer->GetVMin() ;
618 }
619 // If the dynamic_cast above failed then we either have a NULL
620 // streambuf associated with this stream or we have a buffer of
621 // class other than SerialStreamBuf. In either case, we have a
622 // problem and we should stop all I/O using this stream.
623 setstate(badbit) ;
624 return -1;
625 }
626 catch (const std::exception&)
627 {
628 setstate(std::ios_base::failbit) ;
629 throw ;
630 }
631
632 void
633 SerialStream::SetVTime(const short vtime)
634 try
635 {
636 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
637
638 // Make sure that we are dealing with a SerialStreamBuf before
639 // proceeding. This check also makes sure that we have a non-NULL
640 // buffer associated with this stream.
641 if (my_buffer != nullptr)
642 {
643 // Try to set the vTime duration in deciseconds.
644 my_buffer->SetVTime(vtime) ;
645 }
646 else
647 {
648 // If the dynamic_cast above failed then we either have a NULL
649 // streambuf associated with this stream or we have a buffer of
650 // class other than SerialStreamBuf. In either case, we have a
651 // problem and we should stop all I/O using this stream.
652 setstate(badbit) ;
653 }
654 }
655 catch (const std::exception&)
656 {
657 setstate(std::ios_base::failbit) ;
658 throw ;
659 }
660
661 short
663 try
664 {
665 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
666
667 // Make sure that we are dealing with a SerialStreamBuf before
668 // proceeding. This check also makes sure that we have a non-NULL
669 // buffer associated with this stream.
670 if (my_buffer != nullptr)
671 {
672 // Try to get the vTime duration in deciseconds.
673 return my_buffer->GetVTime() ;
674 }
675 // If the dynamic_cast above failed then we either have a NULL
676 // streambuf associated with this stream or we have a buffer of
677 // class other than SerialStreamBuf. In either case, we have a
678 // problem and we should stop all I/O using this stream.
679 setstate(badbit) ;
680 return -1;
681 }
682 catch (const std::exception&)
683 {
684 setstate(std::ios_base::failbit) ;
685 throw ;
686 }
687
688 void
689 SerialStream::SetDTR(const bool dtrState)
690 try
691 {
692 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
693
694 // Make sure that we are dealing with a SerialStreamBuf before
695 // proceeding. This check also makes sure that we have a non-NULL
696 // buffer associated with this stream.
697 if (my_buffer != nullptr)
698 {
699 // Try to set the dtr line state.
700 my_buffer->SetDTR(dtrState) ;
701 }
702 else
703 {
704 // If the dynamic_cast above failed then we either have a NULL
705 // streambuf associated with this stream or we have a buffer of
706 // class other than SerialStreamBuf. In either case, we have a
707 // problem and we should stop all I/O using this stream.
708 setstate(badbit) ;
709 }
710 }
711 catch (const std::exception&)
712 {
713 setstate(std::ios_base::failbit) ;
714 throw ;
715 }
716
717 bool
719 try
720 {
721 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
722
723 // Make sure that we are dealing with a SerialStreamBuf before
724 // proceeding. This check also makes sure that we have a non-NULL
725 // buffer associated with this stream.
726 if (my_buffer != nullptr)
727 {
728 // Try to get the vTime duration in deciseconds.
729 return my_buffer->GetDTR() ;
730 }
731 // If the dynamic_cast above failed then we either have a NULL
732 // streambuf associated with this stream or we have a buffer of
733 // class other than SerialStreamBuf. In either case, we have a
734 // problem and we should stop all I/O using this stream.
735 setstate(badbit) ;
736 return false ;
737 }
738 catch (const std::exception&)
739 {
740 setstate(std::ios_base::failbit) ;
741 throw ;
742 }
743
744 void
745 SerialStream::SetRTS(const bool rtsState)
746 try
747 {
748 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
749
750 // Make sure that we are dealing with a SerialStreamBuf before
751 // proceeding. This check also makes sure that we have a non-NULL
752 // buffer associated with this stream.
753 if (my_buffer != nullptr)
754 {
755 // Try to set the RTS line state.
756 my_buffer->SetRTS(rtsState) ;
757 }
758 else
759 {
760 // If the dynamic_cast above failed then we either have a NULL
761 // streambuf associated with this stream or we have a buffer of
762 // class other than SerialStreamBuf. In either case, we have a
763 // problem and we should stop all I/O using this stream.
764 setstate(badbit) ;
765 }
766 }
767 catch (const std::exception&)
768 {
769 setstate(std::ios_base::failbit) ;
770 throw ;
771 }
772
773 bool
775 try
776 {
777 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
778
779 // Make sure that we are dealing with a SerialStreamBuf before
780 // proceeding. This check also makes sure that we have a non-NULL
781 // buffer associated with this stream.
782 if (my_buffer != nullptr)
783 {
784 // Try to get the RTS line state.
785 return my_buffer->GetRTS() ;
786 }
787 // If the dynamic_cast above failed then we either have a NULL
788 // streambuf associated with this stream or we have a buffer of
789 // class other than SerialStreamBuf. In either case, we have a
790 // problem and we should stop all I/O using this stream.
791 setstate(badbit) ;
792 return false ;
793 }
794 catch (const std::exception&)
795 {
796 setstate(std::ios_base::failbit) ;
797 throw ;
798 }
799
800 bool
802 try
803 {
804 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
805
806 // Make sure that we are dealing with a SerialStreamBuf before
807 // proceeding. This check also makes sure that we have a non-NULL
808 // buffer associated with this stream.
809 if (my_buffer != nullptr)
810 {
811 // Try to get the CTS line state.
812 return my_buffer->GetCTS() ;
813 }
814 // If the dynamic_cast above failed then we either have a NULL
815 // streambuf associated with this stream or we have a buffer of
816 // class other than SerialStreamBuf. In either case, we have a
817 // problem and we should stop all I/O using this stream.
818 setstate(badbit) ;
819 return false ;
820 }
821 catch (const std::exception&)
822 {
823 setstate(std::ios_base::failbit) ;
824 throw ;
825 }
826
827 bool
829 try
830 {
831 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
832
833 // Make sure that we are dealing with a SerialStreamBuf before
834 // proceeding. This check also makes sure that we have a non-NULL
835 // buffer associated with this stream.
836 if (my_buffer != nullptr)
837 {
838 // Try to get the DSR line state.
839 return my_buffer->GetDSR() ;
840 }
841 // If the dynamic_cast above failed then we either have a NULL
842 // streambuf associated with this stream or we have a buffer of
843 // class other than SerialStreamBuf. In either case, we have a
844 // problem and we should stop all I/O using this stream.
845 setstate(badbit) ;
846 return false ;
847 }
848 catch (const std::exception&)
849 {
850 setstate(std::ios_base::failbit) ;
851 throw ;
852 }
853
854 int
856 try
857 {
858 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
859
860 // Make sure that we are dealing with a SerialStreamBuf before
861 // proceeding. This check also makes sure that we have a non-NULL
862 // buffer associated with this stream.
863 if (my_buffer != nullptr)
864 {
865 // Try to get the file descriptor.
866 return my_buffer->GetFileDescriptor() ;
867 }
868 // If the dynamic_cast above failed then we either have a NULL
869 // streambuf associated with this stream or we have a buffer of
870 // class other than SerialStreamBuf. In either case, we have a
871 // problem and we should stop all I/O using this stream.
872 setstate(badbit) ;
873 return -1;
874 }
875 catch (const std::exception&)
876 {
877 setstate(std::ios_base::failbit) ;
878 throw ;
879 }
880
881 int
883 try
884 {
885 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
886
887 // Make sure that we are dealing with a SerialStreamBuf before
888 // proceeding. This check also makes sure that we have a non-NULL
889 // buffer associated with this stream.
890 if (my_buffer != nullptr)
891 {
892 // Try to determine if data is available with the correspoding
893 // function of the SerialStreamBuf class.
894 return my_buffer->GetNumberOfBytesAvailable() ;
895 }
896 // If the dynamic_cast above failed then we either have a NULL
897 // streambuf associated with this stream or we have a buffer
898 // of class other than SerialStreamBuf. In either case, we
899 // have a problem and we should stop all I/O using this stream.
900 setstate(badbit) ;
901 return -1 ;
902 }
903 catch (const std::exception&)
904 {
905 setstate(std::ios_base::failbit) ;
906 throw ;
907 }
908
909#ifdef __linux__
910 std::vector<std::string>
912 try
913 {
914 auto my_buffer = dynamic_cast<SerialStreamBuf *>(this->rdbuf()) ;
915
916 // Make sure that we are dealing with a SerialStreamBuf before
917 // proceeding. This check also makes sure that we have a non-NULL
918 // buffer associated with this stream.
919 if (my_buffer != nullptr)
920 {
921 // Try to get the file descriptor.
922 return my_buffer->GetAvailableSerialPorts() ;
923 }
924 // If the dynamic_cast above failed then we either have a NULL
925 // streambuf associated with this stream or we have a buffer of
926 // class other than SerialStreamBuf. In either case, we have a
927 // problem and we should stop all I/O using this stream.
928 setstate(badbit) ;
929 return {} ;
930 }
931 catch (const std::exception&)
932 {
933 setstate(std::ios_base::failbit) ;
934 throw ;
935 }
936#endif
937} // 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.
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.
void Open(const std::string &fileName, const std::ios_base::openmode &openMode=std::ios_base::in|std::ios_base::out)
Opens the serial port associated with the specified file name and the specified mode.
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.