Skip to content

Commit 0f115c4

Browse files
Added support for SERIAL transport on Windows
Signed-off-by: THOMAS Sebastien <sebastien.thomas@inria.fr>
1 parent 2cbbc4a commit 0f115c4

File tree

9 files changed

+605
-22
lines changed

9 files changed

+605
-22
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
178178
src/cpp/transport/udp/UDPv6AgentWindows.cpp
179179
src/cpp/transport/tcp/TCPv4AgentWindows.cpp
180180
src/cpp/transport/tcp/TCPv6AgentWindows.cpp
181+
src/cpp/transport/serial/SerialAgentWindows.cpp
182+
src/cpp/transport/serial/TermiosAgentWindows.cpp
181183
$<$<BOOL:${UAGENT_DISCOVERY_PROFILE}>:src/cpp/transport/discovery/DiscoveryServerWindows.cpp>
182184
)
183185
endif()
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef UXR_AGENT_TRANSPORT_SERIAL_SERIALAGENTWINDOWS_HPP_
16+
#define UXR_AGENT_TRANSPORT_SERIAL_SERIALAGENTWINDOWS_HPP_
17+
18+
#include <uxr/agent/transport/Server.hpp>
19+
#include <uxr/agent/transport/endpoint/SerialEndPoint.hpp>
20+
#include <uxr/agent/transport/stream_framing/StreamFramingProtocol.hpp>
21+
22+
#include <cstdint>
23+
#include <cstddef>
24+
#include <WinSock2.h>
25+
26+
namespace eprosima {
27+
namespace uxr {
28+
29+
class SerialAgent : public Server<SerialEndPoint>
30+
{
31+
public:
32+
SerialAgent(
33+
uint8_t addr,
34+
Middleware::Kind middleware_kind);
35+
36+
#ifdef UAGENT_DISCOVERY_PROFILE
37+
bool has_discovery() final { return false; }
38+
#endif
39+
40+
#ifdef UAGENT_P2P_PROFILE
41+
bool has_p2p() final { return false; }
42+
#endif
43+
44+
private:
45+
virtual bool init() = 0;
46+
47+
virtual bool fini() = 0;
48+
49+
bool recv_message(
50+
InputPacket<SerialEndPoint>& input_packet,
51+
int timeout,
52+
TransportRc& transport_rc) final;
53+
54+
bool send_message(
55+
OutputPacket<SerialEndPoint> output_packet,
56+
TransportRc& transport_rc) final;
57+
58+
ssize_t write_data(
59+
uint8_t* buf,
60+
size_t len,
61+
TransportRc& transport_rc);
62+
63+
ssize_t read_data(
64+
uint8_t* buf,
65+
size_t len,
66+
int timeout,
67+
TransportRc& transport_rc);
68+
69+
protected:
70+
const uint8_t addr_;
71+
HANDLE serial_handle;
72+
uint8_t buffer_[SERVER_BUFFER_SIZE];
73+
FramingIO framing_io_;
74+
};
75+
76+
} // namespace uxr
77+
} // namespace eprosima
78+
79+
#endif // UXR_AGENT_TRANSPORT_SERIAL_SERIALAGENTWINDOWS_HPP_
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef UXR_AGENT_TRANSPORT_SERIAL_TERMIOSAGENTWINDOWS_HPP_
16+
#define UXR_AGENT_TRANSPORT_SERIAL_TERMIOSAGENTWINDOWS_HPP_
17+
18+
#include <uxr/agent/transport/serial/SerialAgentWindows.hpp>
19+
namespace eprosima {
20+
namespace uxr {
21+
22+
class TermiosAgent : public SerialAgent
23+
{
24+
public:
25+
TermiosAgent(
26+
char const * dev,
27+
DCB const & termios_attrs,
28+
uint8_t addr,
29+
Middleware::Kind middleware_kind);
30+
31+
~TermiosAgent();
32+
33+
HANDLE getfd() { return serial_handle; };
34+
35+
private:
36+
bool init() final;
37+
bool fini() final;
38+
bool handle_error(
39+
TransportRc transport_rc) final;
40+
41+
private:
42+
const std::string dev_;
43+
const DCB termios_attrs_;
44+
};
45+
46+
} // namespace uxr
47+
} // namespace eprosima
48+
49+
#endif // UXR_AGENT_TRANSPORT_SERIAL_TERMIOSAGENTWINDOWS_HPP_
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef UXR_AGENT_TRANSPORT_SERIAL_BAUD_RATE_TABLE_H
16+
#define UXR_AGENT_TRANSPORT_SERIAL_BAUD_RATE_TABLE_H
17+
18+
#include <stdio.h>
19+
#include <stdlib.h>
20+
#include <string.h>
21+
22+
inline
23+
DWORD getBaudRate(const char* baudrate_str)
24+
{
25+
DWORD rv;
26+
if (0 == strcmp(baudrate_str, "0"))
27+
{
28+
rv = 0;
29+
}
30+
else if (0 == strcmp(baudrate_str, "110"))
31+
{
32+
rv = CBR_110;
33+
}
34+
else if (0 == strcmp(baudrate_str, "300")) {
35+
rv = CBR_300;
36+
}
37+
else if (0 == strcmp(baudrate_str, "600")) {
38+
rv = CBR_600;
39+
}
40+
else if (0 == strcmp(baudrate_str, "1200")) {
41+
rv = CBR_1200;
42+
}
43+
else if (0 == strcmp(baudrate_str, "2400")) {
44+
rv = CBR_2400;
45+
}
46+
else if (0 == strcmp(baudrate_str, "4800")) {
47+
rv = CBR_4800;
48+
}
49+
else if (0 == strcmp(baudrate_str, "9600")) {
50+
rv = CBR_9600;
51+
}
52+
else if (0 == strcmp(baudrate_str, "14400")) {
53+
rv = CBR_14400;
54+
}
55+
else if (0 == strcmp(baudrate_str, "19200")) {
56+
rv = CBR_19200;
57+
}
58+
else if (0 == strcmp(baudrate_str, "38400")) {
59+
rv = CBR_38400;
60+
}
61+
else if (0 == strcmp(baudrate_str, "56000")) {
62+
rv = CBR_56000;
63+
}
64+
else if (0 == strcmp(baudrate_str, "57600")) {
65+
rv = CBR_57600;
66+
}
67+
else if (0 == strcmp(baudrate_str, "115200")) {
68+
rv = CBR_115200;
69+
}
70+
else if (0 == strcmp(baudrate_str, "128000")) {
71+
rv = CBR_128000;
72+
}
73+
else if (0 == strcmp(baudrate_str, "256000")) {
74+
rv = CBR_256000;
75+
}
76+
else
77+
{
78+
DWORD custom_baud_rate = (DWORD)atoi(baudrate_str);
79+
printf("Warning: Custom baud rate set to: %d\n", custom_baud_rate);
80+
rv = custom_baud_rate;
81+
}
82+
return rv;
83+
}
84+
85+
#endif // UXR_AGENT_TRANSPORT_SERIAL_BAUD_RATE_TABLE_H
86+

include/uxr/agent/utils/ArgumentParser.hpp

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <uxr/agent/transport/udp/UDPv6AgentWindows.hpp>
3030
#include <uxr/agent/transport/tcp/TCPv4AgentWindows.hpp>
3131
#include <uxr/agent/transport/tcp/TCPv6AgentWindows.hpp>
32+
#include <uxr/agent/transport/serial/TermiosAgentWindows.hpp>
33+
#include <uxr/agent/transport/serial/baud_rate_table_windows.h>
3234
#else
3335
#include <uxr/agent/transport/udp/UDPv4AgentLinux.hpp>
3436
#include <uxr/agent/transport/udp/UDPv6AgentLinux.hpp>
@@ -64,11 +66,11 @@ enum class TransportKind
6466
UDP6,
6567
TCP4,
6668
TCP6,
69+
SERIAL,
6770
#ifndef _WIN32
6871
#ifdef UAGENT_SOCKETCAN_PROFILE
6972
CAN,
7073
#endif // UAGENT_SOCKETCAN_PROFILE
71-
SERIAL,
7274
MULTISERIAL,
7375
PSEUDOTERMINAL,
7476
#endif // _WIN32
@@ -659,7 +661,6 @@ class IPvXArgs
659661
Argument<uint16_t> port_;
660662
};
661663

662-
#ifndef _WIN32
663664
/*************************************************************************************************
664665
* Specific arguments for pseudoterminal transports
665666
*************************************************************************************************/
@@ -782,6 +783,8 @@ class SerialArgs : public PseudoTerminalArgs<AgentType>
782783
Argument<std::string> file_;
783784
};
784785

786+
787+
#ifndef _WIN32
785788
/*************************************************************************************************
786789
* Specific arguments for multi serial termios transports
787790
*************************************************************************************************/
@@ -943,11 +946,11 @@ class ArgumentParser
943946
, argv_(argv)
944947
, common_args_()
945948
, ip_args_()
949+
, serial_args_()
946950
#ifndef _WIN32
947951
#ifdef UAGENT_SOCKETCAN_PROFILE
948952
, can_args_()
949953
#endif // UAGENT_SOCKETCAN_PROFILE
950-
, serial_args_()
951954
, multiserial_args_()
952955
, pseudoterminal_args_()
953956
#endif // _WIN32
@@ -979,6 +982,11 @@ class ArgumentParser
979982
result &= ip_args_.parse(argc_, argv_);
980983
break;
981984
}
985+
case TransportKind::SERIAL:
986+
{
987+
result &= serial_args_.parse(argc_, argv_);
988+
break;
989+
}
982990
#ifndef _WIN32
983991
#ifdef UAGENT_SOCKETCAN_PROFILE
984992
case TransportKind::CAN:
@@ -987,11 +995,6 @@ class ArgumentParser
987995
break;
988996
}
989997
#endif // UAGENT_SOCKETCAN_PROFILE
990-
case TransportKind::SERIAL:
991-
{
992-
result &= serial_args_.parse(argc_, argv_);
993-
break;
994-
}
995998
case TransportKind::MULTISERIAL:
996999
{
9971000
result &= multiserial_args_.parse(argc_, argv_);
@@ -1075,6 +1078,29 @@ class ArgumentParser
10751078
attr.c_ospeed = baudrate;
10761079
#endif
10771080

1081+
return attr;
1082+
}
1083+
#else
1084+
DCB init_termios(const char* baudrate_str) {
1085+
DCB attr = {};
1086+
1087+
/* Setting baudrate. */
1088+
attr.Parity = NOPARITY;
1089+
attr.StopBits = ONESTOPBIT;
1090+
attr.ByteSize = 8;
1091+
attr.BaudRate = getBaudRate(baudrate_str);
1092+
1093+
attr.fBinary = FALSE;
1094+
attr.fParity = FALSE;
1095+
attr.fOutxCtsFlow = FALSE;
1096+
attr.fOutxDsrFlow = FALSE;
1097+
attr.fDtrControl = DTR_CONTROL_ENABLE;
1098+
attr.fRtsControl = RTS_CONTROL_ENABLE;
1099+
attr.fInX = FALSE;
1100+
attr.fOutX = FALSE;
1101+
attr.fDsrSensitivity = FALSE;
1102+
attr.fErrorChar = FALSE;
1103+
10781104
return attr;
10791105
}
10801106
#endif // _WIN32
@@ -1107,25 +1133,32 @@ class ArgumentParser
11071133
char** argv_;
11081134
CommonArgs<AgentType> common_args_;
11091135
IPvXArgs<AgentType> ip_args_;
1136+
SerialArgs<AgentType> serial_args_;
11101137
#ifndef _WIN32
11111138
#ifdef UAGENT_SOCKETCAN_PROFILE
11121139
CanArgs<AgentType> can_args_;
11131140
#endif // UAGENT_SOCKETCAN_PROFILE
1114-
SerialArgs<AgentType> serial_args_;
11151141
MultiSerialArgs<AgentType> multiserial_args_;
11161142
PseudoTerminalArgs<AgentType> pseudoterminal_args_;
11171143
#endif // _WIN32
11181144
TransportKind transport_kind_;
11191145
std::unique_ptr<AgentType> agent_server_;
11201146
};
11211147

1148+
template<> inline bool ArgumentParser<TermiosAgent>::launch_agent() {
11221149
#ifndef _WIN32
1123-
template<> inline bool ArgumentParser<TermiosAgent>::launch_agent()
1124-
{
1125-
struct termios attr = init_termios(serial_args_.baud_rate().c_str());
1126-
1150+
termios
1151+
#else
1152+
DCB
1153+
#endif
1154+
attr = init_termios(serial_args_.baud_rate().c_str());
1155+
11271156
agent_server_.reset(new TermiosAgent(
1128-
serial_args_.dev().c_str(), O_RDWR | O_NOCTTY, attr, 0, utils::get_mw_kind(common_args_.middleware())));
1157+
#ifndef _WIN32
1158+
serial_args_.dev().c_str(), O_RDWR | O_NOCTTY, attr, 0, utils::get_mw_kind(common_args_.middleware())));
1159+
#else
1160+
serial_args_.dev().c_str(), attr, 0, utils::get_mw_kind(common_args_.middleware())));
1161+
#endif
11291162

11301163
if (agent_server_->start())
11311164
{
@@ -1140,6 +1173,8 @@ template<> inline bool ArgumentParser<TermiosAgent>::launch_agent()
11401173
return false;
11411174
}
11421175

1176+
1177+
#ifndef _WIN32
11431178
template<> inline bool ArgumentParser<MultiTermiosAgent>::launch_agent()
11441179
{
11451180
struct termios attr = init_termios(multiserial_args_.baud_rate().c_str());

0 commit comments

Comments
 (0)