diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b5e810..28ec6ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ include_directories(include) install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} ) ## Install headers diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bd087f8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2012 William Woodall, John Harrison + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 3f99507..c5d8d0b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Serial is a class that provides the basic interface common to serial libraries ( ### Documentation -Website: http://wjwwood.github.com/serial/ +Website: http://wjwwood.github.io/serial/ -API Documentation: http://wjwwood.github.com/serial/doc/1.1.0/index.html +API Documentation: http://wjwwood.github.io/serial/doc/1.1.0/index.html ### Dependencies @@ -23,9 +23,6 @@ Required: * [empy](http://www.alcyone.com/pyos/empy/) - Python templating library * [catkin_pkg](http://pypi.python.org/pypi/catkin_pkg/) - Runtime Python library for catkin -Optional (for tests): -* [Boost](http://www.boost.org/) - Boost C++ librairies - Optional (for documentation): * [Doxygen](http://www.doxygen.org/) - Documentation generation tool * [graphviz](http://www.graphviz.org/) - Graph visualization software @@ -54,15 +51,7 @@ Install: ### License -The MIT License - -Copyright (c) 2012 William Woodall, John Harrison - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +[The MIT License](LICENSE) ### Authors diff --git a/package.xml b/package.xml index 27781e1..959f9b8 100644 --- a/package.xml +++ b/package.xml @@ -21,6 +21,4 @@ catkin - boost - diff --git a/src/impl/list_ports/list_ports_linux.cc b/src/impl/list_ports/list_ports_linux.cc index 9779d5e..db2afb2 100644 --- a/src/impl/list_ports/list_ports_linux.cc +++ b/src/impl/list_ports/list_ports_linux.cc @@ -305,6 +305,7 @@ serial::list_ports() search_globs.push_back("/dev/ttyUSB*"); search_globs.push_back("/dev/tty.*"); search_globs.push_back("/dev/cu.*"); + search_globs.push_back("/dev/rfcomm*"); vector devices_found = glob( search_globs ); diff --git a/src/impl/unix.cc b/src/impl/unix.cc index 4309aa6..a40b0fa 100755 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -304,36 +304,6 @@ Serial::SerialImpl::reconfigurePort () #endif default: custom_baud = true; - // OS X support -#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) - // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates - // other than those specified by POSIX. The driver for the underlying serial hardware - // ultimately determines which baud rates can be used. This ioctl sets both the input - // and output speed. - speed_t new_baud = static_cast (baudrate_); - if (-1 == ioctl (fd_, IOSSIOSPEED, &new_baud, 1)) { - THROW (IOException, errno); - } - // Linux Support -#elif defined(__linux__) && defined (TIOCSSERIAL) - struct serial_struct ser; - - if (-1 == ioctl (fd_, TIOCGSERIAL, &ser)) { - THROW (IOException, errno); - } - - // set custom divisor - ser.custom_divisor = ser.baud_base / static_cast (baudrate_); - // update flags - ser.flags &= ~ASYNC_SPD_MASK; - ser.flags |= ASYNC_SPD_CUST; - - if (-1 == ioctl (fd_, TIOCSSERIAL, &ser)) { - THROW (IOException, errno); - } -#else - throw invalid_argument ("OS does not currently support custom bauds"); -#endif } if (custom_baud == false) { #ifdef _BSD_SOURCE @@ -443,6 +413,41 @@ Serial::SerialImpl::reconfigurePort () // activate settings ::tcsetattr (fd_, TCSANOW, &options); + // apply custom baud rate, if any + if (custom_baud == true) { + // OS X support +#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) + // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates + // other than those specified by POSIX. The driver for the underlying serial hardware + // ultimately determines which baud rates can be used. This ioctl sets both the input + // and output speed. + speed_t new_baud = static_cast (baudrate_); + // PySerial uses IOSSIOSPEED=0x80045402 + if (-1 == ioctl (fd_, IOSSIOSPEED, &new_baud, 1)) { + THROW (IOException, errno); + } + // Linux Support +#elif defined(__linux__) && defined (TIOCSSERIAL) + struct serial_struct ser; + + if (-1 == ioctl (fd_, TIOCGSERIAL, &ser)) { + THROW (IOException, errno); + } + + // set custom divisor + ser.custom_divisor = ser.baud_base / static_cast (baudrate_); + // update flags + ser.flags &= ~ASYNC_SPD_MASK; + ser.flags |= ASYNC_SPD_CUST; + + if (-1 == ioctl (fd_, TIOCSSERIAL, &ser)) { + THROW (IOException, errno); + } +#else + throw invalid_argument ("OS does not currently support custom bauds"); +#endif + } + // Update byte_time_ based on the new settings. uint32_t bit_time_ns = 1e9 / baudrate_; byte_time_ns_ = bit_time_ns * (1 + bytesize_ + parity_ + stopbits_); @@ -660,14 +665,27 @@ Serial::SerialImpl::write (const uint8_t *data, size_t length) // This will write some ssize_t bytes_written_now = ::write (fd_, data + bytes_written, length - bytes_written); + + // even though pselect returned readiness the call might still be + // interrupted. In that case simply retry. + if (bytes_written_now == -1 && errno == EINTR) { + continue; + } + // write should always return some data as select reported it was // ready to write when we get to this point. if (bytes_written_now < 1) { // Disconnected devices, at least on Linux, show the // behavior that they are always ready to write immediately // but writing returns nothing. - throw SerialException ("device reports readiness to write but " - "returned no data (device disconnected?)"); + std::stringstream strs; + strs << "device reports readiness to write but " + "returned no data (device disconnected?)"; + strs << " errno=" << errno; + strs << " bytes_written_now= " << bytes_written_now; + strs << " bytes_written=" << bytes_written; + strs << " length=" << length; + throw SerialException(strs.str().c_str()); } // Update bytes_written bytes_written += static_cast (bytes_written_now); diff --git a/src/impl/win.cc b/src/impl/win.cc index 786f4f6..889e06f 100644 --- a/src/impl/win.cc +++ b/src/impl/win.cc @@ -24,7 +24,7 @@ inline wstring _prefix_port_if_needed(const wstring &input) { static wstring windows_com_port_prefix = L"\\\\.\\"; - if (input.compare(windows_com_port_prefix) != 0) + if (input.compare(0, windows_com_port_prefix.size(), windows_com_port_prefix) != 0) { return windows_com_port_prefix + input; } diff --git a/src/serial.cc b/src/serial.cc index 37b5d70..a9e6f84 100755 --- a/src/serial.cc +++ b/src/serial.cc @@ -188,6 +188,7 @@ Serial::readline (string &buffer, size_t size, string eol) if (bytes_read == 0) { break; // Timeout occured on reading 1 byte } + if(read_so_far < eol_len) continue; if (string (reinterpret_cast (buffer_ + read_so_far - eol_len), eol_len) == eol) { break; // EOL found @@ -229,6 +230,7 @@ Serial::readlines (size_t size, string eol) } break; // Timeout occured on reading 1 byte } + if(read_so_far < eol_len) continue; if (string (reinterpret_cast (buffer_ + read_so_far - eol_len), eol_len) == eol) { // EOL found diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e52a4d3..ac9a421 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,6 @@ if(UNIX) catkin_add_gtest(${PROJECT_NAME}-test unix_serial_tests.cc) - target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME} ${Boost_LIBRARIES}) + target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) if(NOT APPLE) target_link_libraries(${PROJECT_NAME}-test util) endif() diff --git a/tests/unix_serial_tests.cc b/tests/unix_serial_tests.cc index 26ffde2..c34868a 100644 --- a/tests/unix_serial_tests.cc +++ b/tests/unix_serial_tests.cc @@ -20,8 +20,6 @@ void loop() #include #include "gtest/gtest.h" -#include - // Use FRIEND_TEST... its not as nasty, thats what friends are for // // OMG this is so nasty... // #define private public