Commit 67d72d506bb6773c5e1fda13406ef83647ce8029

Authored by Roland Hughes
1 parent cf8ca480

Added ReadBinary and WriteBinary

include/CppLinuxSerial/SerialPort.hpp
... ... @@ -58,7 +58,7 @@ namespace mn {
58 58 B_115200,
59 59 B_230400,
60 60 B_460800,
61   - B_CUSTOM, // Placeholder
  61 + B_CUSTOM, // Placeholder
62 62 };
63 63  
64 64 /// \brief Represents the state of the serial port.
... ... @@ -113,18 +113,30 @@ namespace mn {
113 113 /// \brief Closes the COM port.
114 114 void Close();
115 115  
116   - /// \brief Sends a message over the com port.
  116 + /// \brief Sends a text message over the com port.
117 117 /// \param data The data that will be written to the COM port.
118 118 /// \throws CppLinuxSerial::Exception if state != OPEN.
119 119 void Write(const std::string& data);
120 120  
121   - /// \brief Use to read from the COM port.
  121 + /// \brief Sends a binary message over the com port.
  122 + /// \param data The data that will be written to the COM port.
  123 + /// \throws CppLinuxSerial::Exception if state != OPEN.
  124 + void WriteBinary(const std::vector<uint8_t>& data);
  125 +
  126 + /// \brief Use to read text from the COM port.
122 127 /// \param data The object the read characters from the COM port will be saved to.
123 128 /// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1
124 129 /// to wait indefinitely for new data.
125 130 /// \throws CppLinuxSerial::Exception if state != OPEN.
126 131 void Read(std::string& data);
127 132  
  133 + /// \brief Use to read binary data from the COM port.
  134 + /// \param data The object the read uint8_t bytes from the COM port will be saved to.
  135 + /// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1
  136 + /// to wait indefinitely for new data.
  137 + /// \throws CppLinuxSerial::Exception if state != OPEN.
  138 + void ReadBinary(std::vector<uint8_t>& data);
  139 +
128 140 private:
129 141  
130 142 /// \brief Returns a populated termios structure for the passed in file descriptor.
... ...
src/SerialPort.cpp
... ... @@ -22,6 +22,8 @@
22 22 // #include <asm/termios.h> // Terminal control definitions (struct termios)
23 23 #include <asm/ioctls.h>
24 24 #include <asm/termbits.h>
  25 +#include <algorithm>
  26 +#include <iterator>
25 27  
26 28 // User includes
27 29 #include "CppLinuxSerial/Exception.hpp"
... ... @@ -275,7 +277,7 @@ namespace CppLinuxSerial {
275 277 // This does no different than STANDARD atm, but let's keep
276 278 // them separate for now....
277 279 else if (baudRateType_ == BaudRateType::CUSTOM)
278   - {
  280 + {
279 281 tty.c_cflag &= ~CBAUD;
280 282 tty.c_cflag |= CBAUDEX;
281 283 // tty.c_cflag |= BOTHER;
... ... @@ -285,7 +287,7 @@ namespace CppLinuxSerial {
285 287  
286 288 // #include <linux/serial.h>
287 289 // // configure port to use custom speed instead of 38400
288   - // struct serial_struct ss;
  290 + // struct serial_struct ss;
289 291 // ioctl(fileDesc_, TIOCGSERIAL, &ss);
290 292 // ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
291 293 // ss.custom_divisor = (ss.baud_base + (baudRateCustom_ / 2)) / baudRateCustom_;
... ... @@ -300,7 +302,7 @@ namespace CppLinuxSerial {
300 302 // cfsetispeed(&tty, B38400);
301 303 // cfsetospeed(&tty, B38400);
302 304 }
303   - else
  305 + else
304 306 {
305 307 // Should never get here, bug in this libraries code!
306 308 assert(false);
... ... @@ -352,7 +354,7 @@ namespace CppLinuxSerial {
352 354 tty.c_lflag |= ECHO;
353 355 } else {
354 356 tty.c_lflag &= ~(ECHO);
355   - }
  357 + }
356 358 tty.c_lflag &= ~ECHOE; // Turn off echo erase (echo erase only relevant if canonical input is active)
357 359 tty.c_lflag &= ~ECHONL; //
358 360 tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters
... ... @@ -393,6 +395,23 @@ namespace CppLinuxSerial {
393 395 }
394 396 }
395 397  
  398 + void SerialPort::WriteBinary(const std::vector<uint8_t>& data) {
  399 +
  400 + if(state_ != State::OPEN)
  401 + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but state != OPEN. Please call Open() first.");
  402 +
  403 + if(fileDesc_ < 0) {
  404 + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but file descriptor < 0, indicating file has not been opened.");
  405 + }
  406 +
  407 + int writeResult = write(fileDesc_, data.data(), data.size());
  408 +
  409 + // Check status
  410 + if (writeResult == -1) {
  411 + throw std::system_error(EFAULT, std::system_category());
  412 + }
  413 + }
  414 +
396 415 void SerialPort::Read(std::string& data)
397 416 {
398 417 data.clear();
... ... @@ -431,6 +450,35 @@ namespace CppLinuxSerial {
431 450 // If code reaches here, read must of been successful
432 451 }
433 452  
  453 + void SerialPort::ReadBinary(std::vector<uint8_t>& data)
  454 + {
  455 + data.clear();
  456 +
  457 + if(fileDesc_ == 0) {
  458 + //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened.");
  459 + //return false;
  460 + THROW_EXCEPT("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened.");
  461 + }
  462 +
  463 + // Read from file
  464 + // We provide the underlying raw array from the readBuffer_ vector to this C api.
  465 + // This will work because we do not delete/resize the vector while this method
  466 + // is called
  467 + ssize_t n = read(fileDesc_, &readBuffer_[0], readBufferSize_B_);
  468 +
  469 + // Error Handling
  470 + if(n < 0) {
  471 + // Read was unsuccessful
  472 + throw std::system_error(EFAULT, std::system_category());
  473 + }
  474 +
  475 + if(n > 0) {
  476 + copy(readBuffer_.begin(), readBuffer_.begin() + n, back_inserter(data));
  477 + }
  478 +
  479 + // If code reaches here, read must of been successful
  480 + }
  481 +
434 482 // termios SerialPort::GetTermios() {
435 483 // if(fileDesc_ == -1)
436 484 // throw std::runtime_error("GetTermios() called but file descriptor was not valid.");
... ... @@ -469,16 +517,16 @@ namespace CppLinuxSerial {
469 517 termios2 SerialPort::GetTermios2()
470 518 {
471 519 struct termios2 term2;
472   -
  520 +
473 521 ioctl(fileDesc_, TCGETS2, &term2);
474 522  
475 523 return term2;
476   -
  524 +
477 525 // term2.c_cflag &= ~CBAUD; /* Remove current BAUD rate */
478 526 // term2.c_cflag |= BOTHER; /* Allow custom BAUD rate using int input */
479 527 // term2.c_ispeed = speed; /* Set the input BAUD rate */
480 528 // term2.c_ospeed = speed; /* Set the output BAUD rate */
481   -
  529 +
482 530 // ioctl(fd, TCSETS2, &term2);
483 531 }
484 532  
... ...