Skip to content

Commit

Permalink
Merge pull request #54 from eProsima/feature/baudrate
Browse files Browse the repository at this point in the history
Improved baud rate support [4465]
  • Loading branch information
lemunozm committed Jan 30, 2019
2 parents f46ea3c + 40356bb commit a495c65
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 64 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ if(EPROSIMA_BUILD_TESTS AND IS_TOP_LEVEL)
add_subdirectory(test/unittest/root)
add_subdirectory(test/unittest/util)
add_subdirectory(test/unittest/xrce)
add_subdirectory(test/unittest/transport/serial)
add_subdirectory(test/blackbox/tree)
endif()
add_subdirectory(test/integration/cross_serialization)
Expand Down
160 changes: 160 additions & 0 deletions include/uxr/agent/transport/serial/baud_rate_table_linux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef UXR_AGENT_TRANSPORT_SERIAL_BAUD_RATE_TABLE_H
#define UXR_AGENT_TRANSPORT_SERIAL_BAUD_RATE_TABLE_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>

speed_t getBaudRate(const char* baudrate_str)
{
speed_t rv;
if (0 == strcmp(baudrate_str, "0"))
{
rv = B0;
}
else if (0 == strcmp(baudrate_str, "50"))
{
rv = B50;
}
else if (0 == strcmp(baudrate_str, "75"))
{
rv = B75;
}
else if (0 == strcmp(baudrate_str, "110"))
{
rv = B110;
}
else if (0 == strcmp(baudrate_str, "134"))
{
rv = B134;
}
else if (0 == strcmp(baudrate_str, "150"))
{
rv = B150;
}
else if (0 == strcmp(baudrate_str, "200"))
{
rv = B200;
}
else if (0 == strcmp(baudrate_str, "300"))
{
rv = B300;
}
else if (0 == strcmp(baudrate_str, "600"))
{
rv = B600;
}
else if (0 == strcmp(baudrate_str, "1200"))
{
rv = B1200;
}
else if (0 == strcmp(baudrate_str, "1800"))
{
rv = B1800;
}
else if (0 == strcmp(baudrate_str, "2400"))
{
rv = B2400;
}
else if (0 == strcmp(baudrate_str, "4800"))
{
rv = B4800;
}
else if (0 == strcmp(baudrate_str, "9600"))
{
rv = B9600;
}
else if (0 == strcmp(baudrate_str, "19200"))
{
rv = B19200;
}
else if (0 == strcmp(baudrate_str, "38400"))
{
rv = B38400;
}
else if (0 == strcmp(baudrate_str, "57600"))
{
rv = B57600;
}
else if (0 == strcmp(baudrate_str, "115200"))
{
rv = B115200;
}
else if (0 == strcmp(baudrate_str, "230400"))
{
rv = B230400;
}
else if (0 == strcmp(baudrate_str, "460800"))
{
rv = B460800;
}
else if (0 == strcmp(baudrate_str, "500000"))
{
rv = B500000;
}
else if (0 == strcmp(baudrate_str, "576000"))
{
rv = B576000;
}
else if (0 == strcmp(baudrate_str, "921600"))
{
rv = B921600;
}
else if (0 == strcmp(baudrate_str, "1000000"))
{
rv = B1000000;
}
else if (0 == strcmp(baudrate_str, "1152000"))
{
rv = B1152000;
}
else if (0 == strcmp(baudrate_str, "1500000"))
{
rv = B1500000;
}
else if (0 == strcmp(baudrate_str, "2000000"))
{
rv = B2000000;
}
else if (0 == strcmp(baudrate_str, "2500000"))
{
rv = B2500000;
}
else if (0 == strcmp(baudrate_str, "3000000"))
{
rv = B3000000;
}
else if (0 == strcmp(baudrate_str, "3500000"))
{
rv = B3500000;
}
else if (0 == strcmp(baudrate_str, "4000000"))
{
rv = B4000000;
}
else
{
speed_t custom_baud_rate = (speed_t)atoi(baudrate_str);
printf("Warning: Custom baud rate set to: %d\n", custom_baud_rate);
rv = custom_baud_rate;
}
return rv;
}

#endif // UXR_AGENT_TRANSPORT_SERIAL_BAUD_RATE_TABLE_H

84 changes: 20 additions & 64 deletions microxrce_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <uxr/agent/transport/tcp/TCPServerWindows.hpp>
#else
#include <uxr/agent/transport/serial/SerialServerLinux.hpp>
#include <uxr/agent/transport/serial/baud_rate_table_linux.h>
#include <uxr/agent/transport/udp/UDPServerLinux.hpp>
#include <uxr/agent/transport/tcp/TCPServerLinux.hpp>
#include <termios.h>
Expand All @@ -36,58 +37,14 @@ void showHelp()
std::cout << " udp <local_port>" << std::endl;
std::cout << " tcp <local_port>" << std::endl;
#else
std::cout << " serial <device_name> [baudrate=<1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200>]" << std::endl;
std::cout << " pseudo-serial [baudrate=<1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200>]" << std::endl;
std::cout << " serial <device_name> [<baudrate>]" << std::endl;
std::cout << " pseudo-serial [<baudrate>]" << std::endl;
std::cout << " udp <local_port> [<discovery_port>]" << std::endl;
std::cout << " tcp <local_port> [<discovery_port>]" << std::endl;
#endif
}

#ifndef _WIN32
speed_t getBaudRate(const char* baudrate_str)
{
speed_t rv;
if (0 == strcmp(baudrate_str, "1200"))
{
rv = B1200;
}
else if (0 == strcmp(baudrate_str, "2400"))
{
rv = B2400;
}
else if (0 == strcmp(baudrate_str, "4800"))
{
rv = B4800;
}
else if (0 == strcmp(baudrate_str, "9600"))
{
rv = B9600;
}
else if (0 == strcmp(baudrate_str, "19200"))
{
rv = B19200;
}
else if (0 == strcmp(baudrate_str, "38400"))
{
rv = B38400;
}
else if (0 == strcmp(baudrate_str, "57600"))
{
rv = B57600;
}
else if (0 == strcmp(baudrate_str, "115200"))
{
rv = B115200;
}
else
{
rv = 0;
}
return rv;
}
#endif

void initializationError()
[[ noreturn ]] void initializationError()
{
std::cout << "Error: Invalid arguments." << std::endl;
showHelp();
Expand Down Expand Up @@ -183,30 +140,30 @@ int main(int argc, char** argv)
/* Setting CONTROL OPTIONS. */
tty_config.c_cflag |= CREAD; // Enable read.
tty_config.c_cflag |= CLOCAL; // Set local mode.
tty_config.c_cflag &= ~PARENB; // Disable parity.
tty_config.c_cflag &= ~CSTOPB; // Set one stop bit.
tty_config.c_cflag &= ~CSIZE; // Mask the character size bits.
tty_config.c_cflag &= tcflag_t(~PARENB); // Disable parity.
tty_config.c_cflag &= tcflag_t(~CSTOPB); // Set one stop bit.
tty_config.c_cflag &= tcflag_t(~CSIZE); // Mask the character size bits.
tty_config.c_cflag |= CS8; // Set 8 data bits.
tty_config.c_cflag &= ~CRTSCTS; // Disable hardware flow control.

/* Setting LOCAL OPTIONS. */
tty_config.c_lflag &= ~ICANON; // Set non-canonical input.
tty_config.c_lflag &= ~ECHO; // Disable echoing of input characters.
tty_config.c_lflag &= ~ECHOE; // Disable echoing the erase character.
tty_config.c_lflag &= ~ISIG; // Disable SIGINTR, SIGSUSP, SIGDSUSP and SIGQUIT signals.
tty_config.c_lflag &= tcflag_t(~ICANON); // Set non-canonical input.
tty_config.c_lflag &= tcflag_t(~ECHO); // Disable echoing of input characters.
tty_config.c_lflag &= tcflag_t(~ECHOE); // Disable echoing the erase character.
tty_config.c_lflag &= tcflag_t(~ISIG); // Disable SIGINTR, SIGSUSP, SIGDSUSP and SIGQUIT signals.

/* Setting INPUT OPTIONS. */
tty_config.c_iflag &= ~IXON; // Disable output software flow control.
tty_config.c_iflag &= ~IXOFF; // Disable input software flow control.
tty_config.c_iflag &= ~INPCK; // Disable parity check.
tty_config.c_iflag &= ~ISTRIP; // Disable strip parity bits.
tty_config.c_iflag &= ~IGNBRK; // No ignore break condition.
tty_config.c_iflag &= ~IGNCR; // No ignore carrier return.
tty_config.c_iflag &= ~INLCR; // No map NL to CR.
tty_config.c_iflag &= ~ICRNL; // No map CR to NL.
tty_config.c_iflag &= tcflag_t(~IXON); // Disable output software flow control.
tty_config.c_iflag &= tcflag_t(~IXOFF); // Disable input software flow control.
tty_config.c_iflag &= tcflag_t(~INPCK); // Disable parity check.
tty_config.c_iflag &= tcflag_t(~ISTRIP); // Disable strip parity bits.
tty_config.c_iflag &= tcflag_t(~IGNBRK); // No ignore break condition.
tty_config.c_iflag &= tcflag_t(~IGNCR); // No ignore carrier return.
tty_config.c_iflag &= tcflag_t(~INLCR); // No map NL to CR.
tty_config.c_iflag &= tcflag_t(~ICRNL); // No map CR to NL.

/* Setting OUTPUT OPTIONS. */
tty_config.c_oflag &= ~OPOST; // Set raw output.
tty_config.c_oflag &= tcflag_t(~OPOST); // Set raw output.

/* Setting OUTPUT CHARACTERS. */
tty_config.c_cc[VMIN] = 10;
Expand Down Expand Up @@ -288,4 +245,3 @@ int main(int argc, char** argv)

return 0;
}

85 changes: 85 additions & 0 deletions test/unittest/transport/serial/BaudRateTableTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <uxr/agent/transport/serial/baud_rate_table_linux.h>

#include <gtest/gtest.h>

namespace eprosima {
namespace uxr {
namespace testing {


class BaudRateTableUnitTests : public ::testing::Test
{
public:
BaudRateTableUnitTests() : table{}
{
table.push_back(std::make_tuple("0", B0));
table.push_back(std::make_tuple("50", B50));
table.push_back(std::make_tuple("75", B75));
table.push_back(std::make_tuple("110", B110));
table.push_back(std::make_tuple("134", B134));
table.push_back(std::make_tuple("150", B150));
table.push_back(std::make_tuple("200", B200));
table.push_back(std::make_tuple("300", B300));
table.push_back(std::make_tuple("600", B600));
table.push_back(std::make_tuple("1200", B1200));
table.push_back(std::make_tuple("1800", B1800));
table.push_back(std::make_tuple("2400", B2400));
table.push_back(std::make_tuple("4800", B4800));
table.push_back(std::make_tuple("9600", B9600));
table.push_back(std::make_tuple("19200", B19200));
table.push_back(std::make_tuple("38400", B38400));
table.push_back(std::make_tuple("57600", B57600));
table.push_back(std::make_tuple("115200", B115200));
table.push_back(std::make_tuple("230400", B230400));
table.push_back(std::make_tuple("460800", B460800));
table.push_back(std::make_tuple("500000", B500000));
table.push_back(std::make_tuple("576000", B576000));
table.push_back(std::make_tuple("921600", B921600));
table.push_back(std::make_tuple("1000000", B1000000));
table.push_back(std::make_tuple("1152000", B1152000));
table.push_back(std::make_tuple("1500000", B1500000));
table.push_back(std::make_tuple("2000000", B2000000));
table.push_back(std::make_tuple("2500000", B2500000));
table.push_back(std::make_tuple("3000000", B3000000));
table.push_back(std::make_tuple("3500000", B3500000));
table.push_back(std::make_tuple("4000000", B4000000));
table.push_back(std::make_tuple("11", speed_t(11)));
}

virtual ~BaudRateTableUnitTests() = default;

public:
std::vector<std::tuple<const char*, speed_t>> table;
};

TEST_F(BaudRateTableUnitTests, CreateClientOk)
{
for (auto& b : table)
{
ASSERT_EQ(getBaudRate(std::get<0>(b)), std::get<1>(b));
}
}

} // namespace testing
} // namespace uxr
} // namespace eprosima

int main(int args, char** argv)
{
::testing::InitGoogleTest(&args, argv);
return RUN_ALL_TESTS();
}
Loading

0 comments on commit a495c65

Please sign in to comment.