DESERT 3.5.1
Loading...
Searching...
No Matches
uwserial.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2019 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#include <uwserial.h>
30
31#include <cerrno>
32#include <algorithm>
33#include <iostream>
34
36 : UwConnector()
37 , serialfd(-1)
38{
39 local_errno = 0;
40}
41
45
46const bool
48{
49 return (serialfd >= 0);
50}
51
52bool
53UwSerial::openConnection(const std::string &path)
54{
55 std::string device_port;
56 std::string sub_path;
57 device_port = "/dev/";
58 sub_path = path.substr(0, path.find(":"));
59 device_port += sub_path;
60 serialfd = open(device_port.c_str(), O_RDWR);
61
62 if (serialfd < 0) {
63 local_errno = errno;
64 std::cout << "Port not open. Unable to open port " << device_port
65 << std::endl;
66 std::cout << "Error " << local_errno
67 << " from open: " << strerror(local_errno)
68 << std::endl;
69 return (false);
70
71 } else {
72 fcntl(serialfd, F_SETFL, 0);
73 std::cout << "Port " << device_port << " is open.\n";
74 }
75
76 if (configurePort(path) != 0) {
77 std::cout << "Error configuring port, check specific output."
78 << std::endl;
79 return (false);
80 }
81
82 return (true);
83}
84
85bool
87{
88 if (serialfd >= 0) {
89 close(serialfd);
90 serialfd = -1;
91 return (true);
92 }
93 return (false);
94}
95
96int
97UwSerial::writeToDevice(const std::string& msg)
98{
99 if (serialfd > 0) {
100 int s_bytes = write(serialfd, msg.c_str(), msg.size());
101 if (s_bytes >= static_cast<int>(msg.size())) {
102 return (s_bytes);
103 }
104 }
105 return 0;
106}
107
108int
109UwSerial::readFromDevice(void *wpos, int maxlen)
110{
111 if (serialfd > 0) {
112 int n_bytes = read(serialfd, wpos, maxlen);
113 if (n_bytes >= 1) {
114 return n_bytes;
115 }
116
117 local_errno = errno;
118 }
119 return -1;
120}
121
122int
123UwSerial::configurePort(const std::string &path)
124{
125 std::string sub;
126 int baud;
127 int num_param = 0;
128 std::size_t curs = 0, curs_d = 0;
129
130 memset(&tty, 0, sizeof(tty));
131
132 if (tcgetattr(serialfd, &tty) != 0) {
133 local_errno = errno;
134 std::cout << "Error " << local_errno
135 << "from tcgetattr: " << strerror(local_errno)
136 << std::endl;
137 }
138
139 while ((curs = path.find(":", curs)) != std::string::npos) {
140 ++num_param;
141 curs++;
142 }
143
144 if (num_param < 4) {
145 std::cout << "ERROR: too few number of parameters for serial port."
146 << std::endl;
147 std::cout << "num_param: " << num_param << std::endl;
148 return -1;
149 } else if (num_param > 4) {
150 std::cout << "ERROR: too many params for serial port. Check path or "
151 "add options in code."
152 << std::endl;
153 std::cout << "num_param: " << num_param << std::endl;
154 return -1;
155 }
156
157 curs_d = path.find(":");
158 curs = path.find(":") + 1;
159
160 while ((curs_d = path.find(":", curs_d)) != std::string::npos) {
161 if (path.at(curs) == 'p') {
162 if (path.at(curs + 2) == '0') {
163 tty.c_cflag &= ~PARENB;
164 } else if (path.at(curs + 2) == '1') {
165 tty.c_cflag |= PARENB;
166 }
167 } else if (path.at(curs) == 's') {
168 if (path.at(curs + 2) == '0') {
169 tty.c_cflag &= ~CSTOPB;
170 } else if (path.at(curs + 2) == '1') {
171 tty.c_cflag |= CSTOPB;
172 }
173 } else if (path.at(curs) == 'f') {
174 if (path.at(curs + 2) == '0') {
175 tty.c_cflag &= ~CRTSCTS;
176 } else if (path.at(curs + 2) == '1') {
177 tty.c_cflag |= CRTSCTS;
178 }
179 } else if (path.at(curs) == 'b') {
180 sub = path.substr(curs + 2, (path.find(":", curs) - (curs + 2)));
181 baud = std::stoi(sub);
182
183 if (baud == 115200) {
184 if ((cfsetispeed(&tty, B115200)) != 0 &&
185 (cfsetospeed(&tty, B115200) != 0)) {
186 std::cout << "Baud(" << baud << ") is not a valid speed."
187 << std::endl;
188 }
189 } else if (baud == 1200) {
190 if ((cfsetispeed(&tty, B1200)) != 0 &&
191 (cfsetospeed(&tty, B1200) != 0)) {
192 std::cout << "Baud(" << baud << ") is not a valid speed."
193 << std::endl;
194 }
195 } else if (baud == 2400) {
196 if ((cfsetispeed(&tty, B2400)) != 0 &&
197 (cfsetospeed(&tty, B2400) != 0)) {
198 std::cout << "Baud(" << baud << ") is not a valid speed."
199 << std::endl;
200 }
201 } else if (baud == 4800) {
202 if ((cfsetispeed(&tty, B4800)) != 0 &&
203 (cfsetospeed(&tty, B4800) != 0)) {
204 std::cout << "Baud(" << baud << ") is not a valid speed."
205 << std::endl;
206 }
207 } else if (baud == 19200) {
208 if ((cfsetispeed(&tty, B19200)) != 0 &&
209 (cfsetospeed(&tty, B19200) != 0)) {
210 std::cout << "Baud(" << baud << ") is not a valid speed."
211 << std::endl;
212 }
213 } else if (baud == 38400) {
214 if ((cfsetispeed(&tty, B38400)) != 0 &&
215 (cfsetospeed(&tty, B38400) != 0)) {
216 std::cout << "Baud(" << baud << ") is not a valid speed."
217 << std::endl;
218 }
219 } else if (baud == 57600) {
220 if ((cfsetispeed(&tty, B57600)) != 0 &&
221 (cfsetospeed(&tty, B57600) != 0)) {
222 std::cout << "Baud(" << baud << ") is not a valid speed."
223 << std::endl;
224 }
225 } else {
226 std::cout << "Baud rate [" << baud << "] not valid" << std::endl;
227 return -1;
228 }
229 } else {
230 std::cout << "ERROR: flag not defined." << std::endl;
231 }
232 curs = path.find(":", curs + 1) + 1;
233 curs_d++;
234 }
235
236 tty.c_cflag |= CS8; // add option if needed in future implementation
237 // e.g. CS5, CS6, CS7
238 tty.c_cflag |= CREAD | CLOCAL;
239 tty.c_lflag &= ~ICANON;
240 tty.c_lflag &= ~ECHO;
241 tty.c_lflag &= ~ECHOE;
242 tty.c_lflag &= ~ECHONL;
243 tty.c_lflag &= ~ISIG;
244 tty.c_iflag &= ~(IXON | IXOFF | IXANY);
245 tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
246 tty.c_oflag &= ~OPOST;
247 tty.c_oflag &= ~ONLCR;
248
249 tty.c_cc[VTIME] = 10;
250 tty.c_cc[VMIN] = 0;
251
252 if (tcsetattr(serialfd, TCSANOW, &tty) != 0) {
253 std::cout << "ERROR: Port configuration error." << std::endl;
254 return -1;
255 }
256
257 return 0;
258}
259
260bool
261UwSerial::refreshConnection(const std::string &path)
262{
263 if (serialfd > 0) {
265 openConnection(path);
266 return (true);
267 } else {
268 std::cout << "Connection not established, cannot refresh." << std::endl;
269 }
270 return (false);
271}
Class UwConnector allows to specify an interface between the UwDriver object and the device.
Definition uwconnector.h:52
UwSerial()
Constructor of the UwSerial class.
Definition uwserial.cpp:35
virtual int configurePort(const std::string &path)
Method that loads the termios struct with the serial port parameters.
Definition uwserial.cpp:123
virtual ~UwSerial()
Destructor of the UwSerial class.
Definition uwserial.cpp:42
virtual const bool isConnected()
Returns true if serial port fd differs from -1, that means the connection is up.
Definition uwserial.cpp:47
virtual int writeToDevice(const std::string &msg)
Method that writes a command to the port interface.
Definition uwserial.cpp:97
int serialfd
Integer value that stores the serial port descriptor as generated by the function UwSerial:openConnec...
Definition uwserial.h:119
virtual bool closeConnection()
Method that closes an active connection to a device.
Definition uwserial.cpp:86
virtual bool openConnection(const std::string &path)
Method that opens a serial connection, the input string has to be with a format like <port_name>:pari...
Definition uwserial.cpp:53
struct termios tty
Definition uwserial.h:121
virtual bool refreshConnection(const std::string &path)
Method that refreshes an existing connection creating a new file descriptor.
Definition uwserial.cpp:261
virtual int readFromDevice(void *wpos, int maxlen)
Function that receives data from the device's port to a backup buffer.
Definition uwserial.cpp:109
This implements a generic serial connector .