Skip to content

Commit d9fb816

Browse files
authoredDec 2, 2021
Merge pull request #17 from RolandHughes/master
Added ReadBinary and WriteBinary
2 parents cf8ca48 + 67d72d5 commit d9fb816

File tree

2 files changed

+70
-10
lines changed

2 files changed

+70
-10
lines changed
 

‎include/CppLinuxSerial/SerialPort.hpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ namespace mn {
5858
B_115200,
5959
B_230400,
6060
B_460800,
61-
B_CUSTOM, // Placeholder
61+
B_CUSTOM, // Placeholder
6262
};
6363

6464
/// \brief Represents the state of the serial port.
@@ -113,18 +113,30 @@ namespace mn {
113113
/// \brief Closes the COM port.
114114
void Close();
115115

116-
/// \brief Sends a message over the com port.
116+
/// \brief Sends a text message over the com port.
117117
/// \param data The data that will be written to the COM port.
118118
/// \throws CppLinuxSerial::Exception if state != OPEN.
119119
void Write(const std::string& data);
120120

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.
122127
/// \param data The object the read characters from the COM port will be saved to.
123128
/// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1
124129
/// to wait indefinitely for new data.
125130
/// \throws CppLinuxSerial::Exception if state != OPEN.
126131
void Read(std::string& data);
127132

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+
128140
private:
129141

130142
/// \brief Returns a populated termios structure for the passed in file descriptor.

‎src/SerialPort.cpp

+55-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
// #include <asm/termios.h> // Terminal control definitions (struct termios)
2323
#include <asm/ioctls.h>
2424
#include <asm/termbits.h>
25+
#include <algorithm>
26+
#include <iterator>
2527

2628
// User includes
2729
#include "CppLinuxSerial/Exception.hpp"
@@ -275,7 +277,7 @@ namespace CppLinuxSerial {
275277
// This does no different than STANDARD atm, but let's keep
276278
// them separate for now....
277279
else if (baudRateType_ == BaudRateType::CUSTOM)
278-
{
280+
{
279281
tty.c_cflag &= ~CBAUD;
280282
tty.c_cflag |= CBAUDEX;
281283
// tty.c_cflag |= BOTHER;
@@ -285,7 +287,7 @@ namespace CppLinuxSerial {
285287

286288
// #include <linux/serial.h>
287289
// // configure port to use custom speed instead of 38400
288-
// struct serial_struct ss;
290+
// struct serial_struct ss;
289291
// ioctl(fileDesc_, TIOCGSERIAL, &ss);
290292
// ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
291293
// ss.custom_divisor = (ss.baud_base + (baudRateCustom_ / 2)) / baudRateCustom_;
@@ -300,7 +302,7 @@ namespace CppLinuxSerial {
300302
// cfsetispeed(&tty, B38400);
301303
// cfsetospeed(&tty, B38400);
302304
}
303-
else
305+
else
304306
{
305307
// Should never get here, bug in this libraries code!
306308
assert(false);
@@ -352,7 +354,7 @@ namespace CppLinuxSerial {
352354
tty.c_lflag |= ECHO;
353355
} else {
354356
tty.c_lflag &= ~(ECHO);
355-
}
357+
}
356358
tty.c_lflag &= ~ECHOE; // Turn off echo erase (echo erase only relevant if canonical input is active)
357359
tty.c_lflag &= ~ECHONL; //
358360
tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters
@@ -393,6 +395,23 @@ namespace CppLinuxSerial {
393395
}
394396
}
395397

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+
396415
void SerialPort::Read(std::string& data)
397416
{
398417
data.clear();
@@ -431,6 +450,35 @@ namespace CppLinuxSerial {
431450
// If code reaches here, read must of been successful
432451
}
433452

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+
434482
// termios SerialPort::GetTermios() {
435483
// if(fileDesc_ == -1)
436484
// throw std::runtime_error("GetTermios() called but file descriptor was not valid.");
@@ -469,16 +517,16 @@ namespace CppLinuxSerial {
469517
termios2 SerialPort::GetTermios2()
470518
{
471519
struct termios2 term2;
472-
520+
473521
ioctl(fileDesc_, TCGETS2, &term2);
474522

475523
return term2;
476-
524+
477525
// term2.c_cflag &= ~CBAUD; /* Remove current BAUD rate */
478526
// term2.c_cflag |= BOTHER; /* Allow custom BAUD rate using int input */
479527
// term2.c_ispeed = speed; /* Set the input BAUD rate */
480528
// term2.c_ospeed = speed; /* Set the output BAUD rate */
481-
529+
482530
// ioctl(fd, TCSETS2, &term2);
483531
}
484532

0 commit comments

Comments
 (0)
Please sign in to comment.