Commit 5a48f672c934de8e173a1de6b262f79c43eac843
1 parent
56a77f3a
Basic write/read data test between virtual serial ports is passing.
Showing
5 changed files
with
23 additions
and
118 deletions
include/CppLinuxSerial/SerialPort.hpp
| @@ -78,13 +78,13 @@ namespace mn { | @@ -78,13 +78,13 @@ namespace mn { | ||
| 78 | //! @param str Reference to an string containing the characters to write to the COM port. | 78 | //! @param str Reference to an string containing the characters to write to the COM port. |
| 79 | //! @throws {std::runtime_error} if filename has not been set. | 79 | //! @throws {std::runtime_error} if filename has not been set. |
| 80 | //! {std::system_error} if system write() operation fails. | 80 | //! {std::system_error} if system write() operation fails. |
| 81 | - void Write(std::string *str); | 81 | + void Write(const std::string& data); |
| 82 | 82 | ||
| 83 | //! @brief Use to read from the COM port. | 83 | //! @brief Use to read from the COM port. |
| 84 | //! @param str Reference to a string that the read characters from the COM port will be saved to. | 84 | //! @param str Reference to a string that the read characters from the COM port will be saved to. |
| 85 | //! @throws {std::runtime_error} if filename has not been set. | 85 | //! @throws {std::runtime_error} if filename has not been set. |
| 86 | //! {std::system_error} if system read() operation fails. | 86 | //! {std::system_error} if system read() operation fails. |
| 87 | - void Read(std::string *str); | 87 | + void Read(std::string& data); |
| 88 | 88 | ||
| 89 | private: | 89 | private: |
| 90 | 90 |
src/SerialPort.cpp
| @@ -232,21 +232,19 @@ namespace CppLinuxSerial { | @@ -232,21 +232,19 @@ namespace CppLinuxSerial { | ||
| 232 | this->SetTermios(myTermios); | 232 | this->SetTermios(myTermios); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | - void SerialPort::Write(std::string* str) | 235 | + void SerialPort::Write(const std::string& data) |
| 236 | { | 236 | { |
| 237 | - if(this->fileDesc_ == 0) | ||
| 238 | - { | 237 | + if(fileDesc_ == 0) { |
| 239 | //this->sp->PrintError(SmartPrint::Ss() << ); | 238 | //this->sp->PrintError(SmartPrint::Ss() << ); |
| 240 | //return false; | 239 | //return false; |
| 241 | 240 | ||
| 242 | throw std::runtime_error("SendMsg called but file descriptor (fileDesc) was 0, indicating file has not been opened."); | 241 | throw std::runtime_error("SendMsg called but file descriptor (fileDesc) was 0, indicating file has not been opened."); |
| 243 | } | 242 | } |
| 244 | 243 | ||
| 245 | - int writeResult = write(this->fileDesc_, str->c_str(), str->size()); | 244 | + int writeResult = write(fileDesc_, data.c_str(), data.size()); |
| 246 | 245 | ||
| 247 | // Check status | 246 | // Check status |
| 248 | - if (writeResult == -1) | ||
| 249 | - { | 247 | + if (writeResult == -1) { |
| 250 | // Could not open COM port | 248 | // Could not open COM port |
| 251 | //this->sp->PrintError(SmartPrint::Ss() << "Unable to write to \"" << this->filePath << "\" - " << strerror(errno)); | 249 | //this->sp->PrintError(SmartPrint::Ss() << "Unable to write to \"" << this->filePath << "\" - " << strerror(errno)); |
| 252 | //return false; | 250 | //return false; |
| @@ -257,10 +255,9 @@ namespace CppLinuxSerial { | @@ -257,10 +255,9 @@ namespace CppLinuxSerial { | ||
| 257 | // If code reaches here than write must of been successful | 255 | // If code reaches here than write must of been successful |
| 258 | } | 256 | } |
| 259 | 257 | ||
| 260 | - void SerialPort::Read(std::string* str) | 258 | + void SerialPort::Read(std::string& data) |
| 261 | { | 259 | { |
| 262 | - if(this->fileDesc_ == 0) | ||
| 263 | - { | 260 | + if(fileDesc_ == 0) { |
| 264 | //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); | 261 | //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); |
| 265 | //return false; | 262 | //return false; |
| 266 | throw std::runtime_error("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); | 263 | throw std::runtime_error("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); |
| @@ -271,25 +268,20 @@ namespace CppLinuxSerial { | @@ -271,25 +268,20 @@ namespace CppLinuxSerial { | ||
| 271 | memset (&buf, '\0', sizeof buf); | 268 | memset (&buf, '\0', sizeof buf); |
| 272 | 269 | ||
| 273 | // Read from file | 270 | // Read from file |
| 274 | - int n = read(this->fileDesc_, &buf, sizeof(buf)); | 271 | + int n = read(fileDesc_, &buf, sizeof(buf)); |
| 275 | 272 | ||
| 276 | // Error Handling | 273 | // Error Handling |
| 277 | - if(n < 0) | ||
| 278 | - { | ||
| 279 | - // Could not open COM port | ||
| 280 | - //this->sp->PrintError(SmartPrint::Ss() << "Unable to read from \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 281 | - //return false; | ||
| 282 | - | 274 | + if(n < 0) { |
| 275 | + // Read was unsuccessful | ||
| 283 | throw std::system_error(EFAULT, std::system_category()); | 276 | throw std::system_error(EFAULT, std::system_category()); |
| 284 | } | 277 | } |
| 285 | 278 | ||
| 286 | - if(n > 0) | ||
| 287 | - { | 279 | + if(n > 0) { |
| 288 | //this->sp->PrintDebug(SmartPrint::Ss() << "\"" << n << "\" characters have been read from \"" << this->filePath << "\""); | 280 | //this->sp->PrintDebug(SmartPrint::Ss() << "\"" << n << "\" characters have been read from \"" << this->filePath << "\""); |
| 289 | // Characters have been read | 281 | // Characters have been read |
| 290 | buf[n] = '\0'; | 282 | buf[n] = '\0'; |
| 291 | //printf("%s\r\n", buf); | 283 | //printf("%s\r\n", buf); |
| 292 | - str->append(buf); | 284 | + data.append(buf); |
| 293 | //std::cout << *str << " and size of string =" << str->size() << "\r\n"; | 285 | //std::cout << *str << " and size of string =" << str->size() << "\r\n"; |
| 294 | } | 286 | } |
| 295 | 287 |
test/unit/BasicTests.cpp
| @@ -65,6 +65,12 @@ namespace { | @@ -65,6 +65,12 @@ namespace { | ||
| 65 | SerialPort serialPort1(device1_, BaudRate::b57600); | 65 | SerialPort serialPort1(device1_, BaudRate::b57600); |
| 66 | serialPort1.Open(); | 66 | serialPort1.Open(); |
| 67 | 67 | ||
| 68 | + serialPort0.Write("Hello"); | ||
| 69 | + | ||
| 70 | + std::string readData; | ||
| 71 | + serialPort1.Read(readData); | ||
| 72 | + | ||
| 73 | + ASSERT_EQ("Hello", readData); | ||
| 68 | } | 74 | } |
| 69 | 75 | ||
| 70 | } // namespace | 76 | } // namespace |
| 71 | \ No newline at end of file | 77 | \ No newline at end of file |
test/unit/CMakeLists.txt
| @@ -19,7 +19,7 @@ file(GLOB_RECURSE CppLinuxSerialUnitTests_SRC | @@ -19,7 +19,7 @@ file(GLOB_RECURSE CppLinuxSerialUnitTests_SRC | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | -add_executable(CppLinuxSerialUnitTests ${CppLinuxSerialUnitTests_SRC} "run.sh") | 22 | +add_executable(CppLinuxSerialUnitTests ${CppLinuxSerialUnitTests_SRC}) |
| 23 | 23 | ||
| 24 | target_link_libraries(CppLinuxSerialUnitTests LINK_PUBLIC CppLinuxSerial ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) | 24 | target_link_libraries(CppLinuxSerialUnitTests LINK_PUBLIC CppLinuxSerial ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) |
| 25 | 25 | ||
| @@ -32,10 +32,4 @@ add_custom_target( | @@ -32,10 +32,4 @@ add_custom_target( | ||
| 32 | 32 | ||
| 33 | add_custom_command( | 33 | add_custom_command( |
| 34 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CppLinuxSerialUnitTests.touch | 34 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CppLinuxSerialUnitTests.touch |
| 35 | - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/CppLinuxSerialUnitTests) | ||
| 36 | - | ||
| 37 | -add_custom_command(TARGET CppLinuxSerialUnitTests POST_BUILD | ||
| 38 | - COMMAND ${CMAKE_COMMAND} -E copy_if_different | ||
| 39 | - ${CMAKE_CURRENT_SOURCE_DIR}/run.sh | ||
| 40 | - $<TARGET_FILE_DIR:CppLinuxSerialUnitTests> | ||
| 41 | - ) | ||
| 42 | \ No newline at end of file | 35 | \ No newline at end of file |
| 36 | + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/CppLinuxSerialUnitTests) | ||
| 43 | \ No newline at end of file | 37 | \ No newline at end of file |
test/unit/TestUtil.hpp
| @@ -23,82 +23,6 @@ | @@ -23,82 +23,6 @@ | ||
| 23 | 23 | ||
| 24 | using namespace std::literals; | 24 | using namespace std::literals; |
| 25 | 25 | ||
| 26 | -#define READ 0 | ||
| 27 | -#define WRITE 1 | ||
| 28 | -FILE * popen2(std::string command, std::string type, int & pid) | ||
| 29 | -{ | ||
| 30 | - pid_t child_pid; | ||
| 31 | - int fd[2]; | ||
| 32 | - pipe(fd); | ||
| 33 | - | ||
| 34 | - if((child_pid = fork()) == -1) | ||
| 35 | - { | ||
| 36 | - perror("fork"); | ||
| 37 | - exit(1); | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - /* child process */ | ||
| 41 | - if (child_pid == 0) | ||
| 42 | - { | ||
| 43 | - if (type == "r") | ||
| 44 | - { | ||
| 45 | - close(fd[READ]); //Close the READ end of the pipe since the child's fd is write-only | ||
| 46 | - dup2(fd[WRITE], 1); //Redirect stdout to pipe | ||
| 47 | - } | ||
| 48 | - else | ||
| 49 | - { | ||
| 50 | - close(fd[WRITE]); //Close the WRITE end of the pipe since the child's fd is read-only | ||
| 51 | - dup2(fd[READ], 0); //Redirect stdin to pipe | ||
| 52 | - } | ||
| 53 | - | ||
| 54 | - setpgid(child_pid, child_pid); //Needed so negative PIDs can kill children of /bin/sh | ||
| 55 | - execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL); | ||
| 56 | - exit(0); | ||
| 57 | - } | ||
| 58 | - else | ||
| 59 | - { | ||
| 60 | - if (type == "r") | ||
| 61 | - { | ||
| 62 | - close(fd[WRITE]); //Close the WRITE end of the pipe since parent's fd is read-only | ||
| 63 | - } | ||
| 64 | - else | ||
| 65 | - { | ||
| 66 | - close(fd[READ]); //Close the READ end of the pipe since parent's fd is write-only | ||
| 67 | - } | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - pid = child_pid; | ||
| 71 | - | ||
| 72 | - if (type == "r") | ||
| 73 | - { | ||
| 74 | - return fdopen(fd[READ], "r"); | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - return fdopen(fd[WRITE], "w"); | ||
| 78 | -} | ||
| 79 | - | ||
| 80 | -int pclose2(FILE * fp, pid_t pid) | ||
| 81 | -{ | ||
| 82 | - int stat; | ||
| 83 | - | ||
| 84 | - fclose(fp); | ||
| 85 | - while (waitpid(pid, &stat, 0) == -1) | ||
| 86 | - { | ||
| 87 | - if (errno != EINTR) | ||
| 88 | - { | ||
| 89 | - stat = -1; | ||
| 90 | - break; | ||
| 91 | - } | ||
| 92 | - } | ||
| 93 | - | ||
| 94 | - return stat; | ||
| 95 | -} | ||
| 96 | - | ||
| 97 | -struct ProcessInfo { | ||
| 98 | - FILE* fp; | ||
| 99 | - pid_t pid; | ||
| 100 | -}; | ||
| 101 | - | ||
| 102 | 26 | ||
| 103 | namespace mn { | 27 | namespace mn { |
| 104 | namespace CppLinuxSerial { | 28 | namespace CppLinuxSerial { |
| @@ -123,17 +47,6 @@ namespace mn { | @@ -123,17 +47,6 @@ namespace mn { | ||
| 123 | return result; | 47 | return result; |
| 124 | } | 48 | } |
| 125 | 49 | ||
| 126 | - void StartProcess(const std::string &cmd) { | ||
| 127 | - std::array<char, 128> buffer; | ||
| 128 | - std::string result; | ||
| 129 | - int pid; | ||
| 130 | - FILE * fp = popen2(cmd, "r", pid); | ||
| 131 | - ProcessInfo processInfo; | ||
| 132 | - processInfo.fp = fp; | ||
| 133 | - processInfo.pid = pid; | ||
| 134 | - processes_.push_back(processInfo); | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | void CreateVirtualSerialPortPair() { | 50 | void CreateVirtualSerialPortPair() { |
| 138 | std::cout << "Creating virtual serial port pair..." << std::endl; | 51 | std::cout << "Creating virtual serial port pair..." << std::endl; |
| 139 | // StartProcess("sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11"); | 52 | // StartProcess("sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11"); |
| @@ -144,6 +57,8 @@ namespace mn { | @@ -144,6 +57,8 @@ namespace mn { | ||
| 144 | // std::cout << "Finished creating virtual serial port pair." << std::endl; | 57 | // std::cout << "Finished creating virtual serial port pair." << std::endl; |
| 145 | // std::system("./run.sh"); | 58 | // std::system("./run.sh"); |
| 146 | std::system("nohup sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11 &"); | 59 | std::system("nohup sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11 &"); |
| 60 | + auto pid = std::system("echo $!"); | ||
| 61 | + std::cout << "pid = " << pid << std::endl; | ||
| 147 | std::this_thread::sleep_for(1s); | 62 | std::this_thread::sleep_for(1s); |
| 148 | std::system("sudo chmod a+rw /dev/ttyS10"); | 63 | std::system("sudo chmod a+rw /dev/ttyS10"); |
| 149 | std::system("sudo chmod a+rw /dev/ttyS11"); | 64 | std::system("sudo chmod a+rw /dev/ttyS11"); |
| @@ -159,8 +74,6 @@ namespace mn { | @@ -159,8 +74,6 @@ namespace mn { | ||
| 159 | std::system("sudo pkill socat"); | 74 | std::system("sudo pkill socat"); |
| 160 | } | 75 | } |
| 161 | 76 | ||
| 162 | - std::vector<ProcessInfo> processes_; | ||
| 163 | - | ||
| 164 | }; | 77 | }; |
| 165 | } // namespace CppLinuxSerial | 78 | } // namespace CppLinuxSerial |
| 166 | } // namespace mn | 79 | } // namespace mn |