DESERT 3.5.1
Loading...
Searching...
No Matches
uwsocket.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2018 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 <uwsocket.h>
30
31#include <sys/socket.h>
32#include <sys/types.h>
33#include <cerrno>
34
35#include <algorithm>
36#include <cstring>
37#include <iostream>
38#include <unistd.h>
39
41 : UwConnector()
42 , socketfd(-1)
43 , proto(Transport::TCP)
44 , isClient(true)
45{
46 local_errno = 0;
47}
48
52
53const bool
55{
56 return (socketfd >= 0);
57}
58
59bool
60UwSocket::openConnection(const std::string &path)
61{
62
63 std::string sep(":");
64 std::string address;
65 int port;
66 int sockfd;
67 socklen_t len_addr;
68 struct sockaddr_in s_address;
69 int sockoptval = 1;
70 struct sockaddr_in cl_address;
71
72 // find the position of the colon
73 size_t pos = path.find(sep);
74
75 if (isClient) {
76 if (pos == std::string::npos) {
77 address = "127.0.0.1";
78 port = std::stoi(path);
79 } else {
80 address = path.substr(0, pos);
81 port = std::stoi(path.substr(pos + 1));
82 }
83 } else {
84 port = std::stoi(path);
85 }
86
87 if (proto == Transport::TCP) {
88
89 if(isClient) {
90 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
91 local_errno = errno;
92 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
93 << std::endl;
94 return (false);
95 }
96
97 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockoptval,
98 sizeof(int)) == -1) {
99 local_errno = errno;
100 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
101 << std::endl;
102 return (false);
103 }
104
105 std::memset(&s_address, 0, sizeof(s_address));
106 s_address.sin_family = AF_INET;
107 s_address.sin_port = htons(port);
108
109 if (inet_pton(AF_INET, address.c_str(), &s_address.sin_addr) <= 0) {
110 local_errno = errno;
111 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
112 << std::endl;
113 return (false);
114 }
115
116 if (connect(sockfd, (struct sockaddr *) &s_address, sizeof(s_address)) <
117 0) {
118 local_errno = errno;
119 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
120 << std::endl;
121 return (false);
122 }
123
124 socketfd = sockfd;
125
126 return (true);
127
128 } else { //server TCP
129 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
130 local_errno = errno;
131 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
132 << std::endl;
133 return (false);
134 }
135
136 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockoptval,
137 sizeof(int)) == -1) {
138 local_errno = errno;
139 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
140 << std::endl;
141 return (false);
142 }
143
144 std::memset(&s_address, 0, sizeof(s_address));
145 s_address.sin_family = AF_INET;
146 s_address.sin_addr.s_addr = htonl(INADDR_ANY);
147 s_address.sin_port = htons(port);
148 // s_address.sin_port = htons((u_short) port);
149
150
151 if (bind(sockfd, (struct sockaddr *) &s_address,
152 sizeof(s_address)) == -1) {
153 local_errno = errno;
154 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
155 << std::endl;
156 return (false);
157 }
158
159 if (listen(sockfd, 1) < 0) {
160 local_errno = errno;
161 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
162 << std::endl;
163 return (false);
164 }
165
166 // while(1) {
167 len_addr = sizeof(cl_address);
168 socketfd = accept(sockfd, (struct sockaddr *) &cl_address,
169 &len_addr);
170 if (socketfd < 0) {
171 local_errno = errno;
172 std::cerr << "UWSOCKET::ERROR::" +
173 std::to_string(local_errno) << std::endl;
174 }
175
176 close(sockfd);
177 // }
178 }
179
180 } else { // proto == Transport::UDP
181
182
183 if (isClient) {
184
185 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
186 local_errno = errno;
187 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
188 << std::endl;
189 return (false);
190 }
191
192 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockoptval,
193 sizeof(int)) == -1) {
194 local_errno = errno;
195 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
196 << std::endl;
197 return (false);
198 }
199
200 struct sockaddr_in dest_addr;
201
202 // only port provided
203 std::memset(&dest_addr, 0, sizeof(dest_addr));
204 dest_addr.sin_family = AF_INET;
205 dest_addr.sin_port = htons(port);
206 dest_addr.sin_addr.s_addr = inet_addr(address.c_str());
207
208 if (sockfd > 0) {
209 int s_bytes = sendto(sockfd, &udp_init_string,
210 sizeof(udp_init_string), 0,
211 (const struct sockaddr *) &dest_addr,
212 sizeof(dest_addr));
213 }
214
215 cl_addr = dest_addr;
216 socketfd = sockfd;
217
218 return (true);
219
220 } else {
221
222 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
223 local_errno = errno;
224 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
225 << std::endl;
226 return (false);
227 }
228
229 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockoptval,
230 sizeof(int)) == -1) {
231 local_errno = errno;
232 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
233 << std::endl;
234 return (false);
235 }
236
237 struct sockaddr_in my_addr;
238
239 // only port provided
240 std::memset(&my_addr, 0, sizeof(my_addr));
241 my_addr.sin_family = AF_INET;
242 my_addr.sin_port = htons(port);
243 my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
244
245 if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(my_addr)) <
246 0) {
247 std::cerr << "UWSOCKET::ERROR::" + std::to_string(local_errno)
248 << std::endl;
249 return (false);
250 }
251
252
253 socklen_t addrlen = sizeof(cl_addr);
254 char tmp_listen[] = {0};
255
256 int n_bytes = recvfrom(sockfd, &tmp_listen, sizeof(tmp_listen), 0,
257 (struct sockaddr *)&cl_addr, &addrlen);
258 if(n_bytes > 0)
259 std::cout << "Server connected to client." << std::endl;
260
261 socketfd = sockfd;
262
263 return (true);
264
265 }
266
267 } // Transport::UDP
268
269 return (true);
270}
271
272bool
274{
275 if (socketfd >= 0) {
276 shutdown(socketfd, SHUT_RDWR);
277 close(socketfd);
278 socketfd = -1;
279 return (true);
280 } else {
281 return (false);
282 }
283}
284
285int
286UwSocket::writeToDevice(const std::string& msg)
287{
288 if (proto == Transport::TCP) {
289
290 if (socketfd > 0) {
291 int s_bytes =
292 send(socketfd, msg.c_str(), static_cast<int>(msg.length()), 0);
293 if (s_bytes >= static_cast<int>(msg.length())) {
294 return (s_bytes);
295 }
296 }
297 return 0;
298
299 } else { //UDP protocol
300
301 socklen_t claddr_len = sizeof(cl_addr);
302
303 if (socketfd > 0) {
304 int s_bytes = sendto(socketfd, msg.c_str(),
305 static_cast<int>(msg.length()), 0,
306 (const struct sockaddr *) &cl_addr, claddr_len);
307
308 if (s_bytes >= static_cast<int>(msg.length())) {
309 return (s_bytes);
310 }
311 }
312 return 0;
313 }
314}
315
316int
317UwSocket::readFromDevice(void *wpos, int maxlen)
318{
319 if (proto == Transport::TCP) {
320
321 if (socketfd == -1) {
322 return -1;
323 }
324
325 int n_bytes = read(socketfd, wpos, maxlen);
326 return n_bytes;
327
328 } else { //UDP protocol
329
330 if (socketfd == -1)
331 return -1;
332
333 socklen_t addrlen = sizeof(cl_addr);
334
335 int n_bytes = recvfrom(socketfd, wpos, maxlen, 0,
336 (struct sockaddr *)&cl_addr, &addrlen);
337 return n_bytes;
338 }
339
340 return -1;
341
342}
Class UwConnector allows to specify an interface between the UwDriver object and the device.
Definition uwconnector.h:52
bool isClient
Bool value that defines the role of the socket.
Definition uwsocket.h:157
UwSocket()
Constructor of the UwSocket class.
Definition uwsocket.cpp:40
virtual int writeToDevice(const std::string &msg)
Method that writes a command to the modem interface.
Definition uwsocket.cpp:286
virtual bool openConnection(const std::string &path)
Method that opens a TCP or UDP connection, accordinto to UwSocket::proto variable: the behavior depen...
Definition uwsocket.cpp:60
int socketfd
Integer value that stores the socket descriptor as generated by the function UwSocket::openConnection...
Definition uwsocket.h:149
Transport
Enum structure thet represents the transport protocol being used.
Definition uwsocket.h:66
virtual const bool isConnected()
Returns true if socket fd differs from -1, that means the connection is up.
Definition uwsocket.cpp:54
Transport proto
Transport protocol to be used: either Transport::TCP or Transport::UDP.
Definition uwsocket.h:153
virtual int readFromDevice(void *wpos, int maxlen)
Function that dumps data from the device's memory to a backup buffer.
Definition uwsocket.cpp:317
virtual ~UwSocket()
Destructor of the UwSocket class.
Definition uwsocket.cpp:49
virtual bool closeConnection()
Method that closes an active connection to a device.
Definition uwsocket.cpp:273
struct sockaddr_in cl_addr
Definition uwsocket.h:162
const std::string sep
Class that implements a connector and, specifically, the socket connector. BSD sockets are used,...
constexpr char udp_init_string[]
Definition uwsocket.h:50