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 | 78 | //! @param str Reference to an string containing the characters to write to the COM port. |
| 79 | 79 | //! @throws {std::runtime_error} if filename has not been set. |
| 80 | 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 | 83 | //! @brief Use to read from the COM port. |
| 84 | 84 | //! @param str Reference to a string that the read characters from the COM port will be saved to. |
| 85 | 85 | //! @throws {std::runtime_error} if filename has not been set. |
| 86 | 86 | //! {std::system_error} if system read() operation fails. |
| 87 | - void Read(std::string *str); | |
| 87 | + void Read(std::string& data); | |
| 88 | 88 | |
| 89 | 89 | private: |
| 90 | 90 | ... | ... |
src/SerialPort.cpp
| ... | ... | @@ -232,21 +232,19 @@ namespace CppLinuxSerial { |
| 232 | 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 | 238 | //this->sp->PrintError(SmartPrint::Ss() << ); |
| 240 | 239 | //return false; |
| 241 | 240 | |
| 242 | 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 | 246 | // Check status |
| 248 | - if (writeResult == -1) | |
| 249 | - { | |
| 247 | + if (writeResult == -1) { | |
| 250 | 248 | // Could not open COM port |
| 251 | 249 | //this->sp->PrintError(SmartPrint::Ss() << "Unable to write to \"" << this->filePath << "\" - " << strerror(errno)); |
| 252 | 250 | //return false; |
| ... | ... | @@ -257,10 +255,9 @@ namespace CppLinuxSerial { |
| 257 | 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 | 261 | //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); |
| 265 | 262 | //return false; |
| 266 | 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 | 268 | memset (&buf, '\0', sizeof buf); |
| 272 | 269 | |
| 273 | 270 | // Read from file |
| 274 | - int n = read(this->fileDesc_, &buf, sizeof(buf)); | |
| 271 | + int n = read(fileDesc_, &buf, sizeof(buf)); | |
| 275 | 272 | |
| 276 | 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 | 276 | throw std::system_error(EFAULT, std::system_category()); |
| 284 | 277 | } |
| 285 | 278 | |
| 286 | - if(n > 0) | |
| 287 | - { | |
| 279 | + if(n > 0) { | |
| 288 | 280 | //this->sp->PrintDebug(SmartPrint::Ss() << "\"" << n << "\" characters have been read from \"" << this->filePath << "\""); |
| 289 | 281 | // Characters have been read |
| 290 | 282 | buf[n] = '\0'; |
| 291 | 283 | //printf("%s\r\n", buf); |
| 292 | - str->append(buf); | |
| 284 | + data.append(buf); | |
| 293 | 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 | 65 | SerialPort serialPort1(device1_, BaudRate::b57600); |
| 66 | 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 | 76 | } // namespace |
| 71 | 77 | \ No newline at end of file | ... | ... |
test/unit/CMakeLists.txt
| ... | ... | @@ -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 | 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 | 32 | |
| 33 | 33 | add_custom_command( |
| 34 | 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 | 35 | \ No newline at end of file |
| 36 | + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/CppLinuxSerialUnitTests) | |
| 43 | 37 | \ No newline at end of file | ... | ... |
test/unit/TestUtil.hpp
| ... | ... | @@ -23,82 +23,6 @@ |
| 23 | 23 | |
| 24 | 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 | 27 | namespace mn { |
| 104 | 28 | namespace CppLinuxSerial { |
| ... | ... | @@ -123,17 +47,6 @@ namespace mn { |
| 123 | 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 | 50 | void CreateVirtualSerialPortPair() { |
| 138 | 51 | std::cout << "Creating virtual serial port pair..." << std::endl; |
| 139 | 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 | 57 | // std::cout << "Finished creating virtual serial port pair." << std::endl; |
| 145 | 58 | // std::system("./run.sh"); |
| 146 | 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 | 62 | std::this_thread::sleep_for(1s); |
| 148 | 63 | std::system("sudo chmod a+rw /dev/ttyS10"); |
| 149 | 64 | std::system("sudo chmod a+rw /dev/ttyS11"); |
| ... | ... | @@ -159,8 +74,6 @@ namespace mn { |
| 159 | 74 | std::system("sudo pkill socat"); |
| 160 | 75 | } |
| 161 | 76 | |
| 162 | - std::vector<ProcessInfo> processes_; | |
| 163 | - | |
| 164 | 77 | }; |
| 165 | 78 | } // namespace CppLinuxSerial |
| 166 | 79 | } // namespace mn | ... | ... |