socket.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2022, Autonics Co.,Ltd.
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 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 *
17 * * Neither the name of the Autonics Co.,Ltd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34 
35 
36 #include <sys/poll.h>
37 #include <stdio.h>
38 
39 #include "socket.hpp"
40 
42 {
43  m_server_sock_ = 0;
44  m_connected_ = 0;
45 
46  rcv_timeout_ = false;
47  rcv_error_ = false;
48 
49  pthread_running_ = false;
50  pthrd_id_ = 0;
51 }
52 
54 {
55  pthread_running_ = false;
56 
57  if(pthrd_id_)
58  {
59  pthread_join(pthrd_id_, NULL);
60  }
61 
62  if(m_connected_ == true)
63  {
64  close(m_server_sock_);
65 
66  m_connected_ = false;
67 
68  std::cout << "disconnect server" << std::endl;
69  }
70 }
71 
73 {
74  return m_server_sock_;
75 }
76 
78 {
79  return m_connected_;
80 }
81 
83 {
84  return pthread_running_;
85 }
86 
87 
89 {
90  return rcv_timeout_;
91 }
92 
94 {
95  return rcv_error_;
96 }
97 
98 void Socket::setRcvTimeout(bool flag)
99 {
100  rcv_timeout_ = flag;
101 }
102 
103 void Socket::setRcvError(bool flag)
104 {
105  rcv_error_ = flag;
106 }
107 
108 
109 
111 {
112  int ret = 0;
113  pthread_running_ = false;
114 
115  if(pthrd_id_)
116  {
117  pthread_join(pthrd_id_, NULL);
118  pthrd_id_ = 0;
119  }
120 
121  m_connected_ = false;
122  close(m_server_sock_);
123 
124  usleep(1000*1000);
125 
127 
128  if(ret < 0)
129  {
130  std::cout << "reconnection failed" << std::endl;
131  return ret;
132  }
133 
134  return ret;
135 }
136 
137 void Socket::putBufToMsg(unsigned char* buf, uint16_t size)
138 {
139  std::vector<unsigned char> vec;
140 
141  for(int i = 0; i < size; i++)
142  {
143  vec.push_back(*(buf+i));
144  }
145 
146  recvQueue.push(vec);
147 }
148 
149 
150 void* readCallback(void* arg)
151 {
152  int32_t read_cnt = 0;
153  uint16_t packet_size = 0, total_byte = 0, offset = 0, recv_byte = 0, \
154  buf_size = 16384;
155  int ret = 0;
156  unsigned char r_buffer[buf_size] = {0, }, \
157  buffer[buf_size] = {0, }, \
158  cp_temp[16] = {0, };
159  Socket* sock = (Socket*) arg;
160  struct pollfd fd;
161  ssize_t chk_connection = 0;
162 
163  fd.fd = sock->getServerSocket();
164  fd.events = POLLIN;
165 
166  while(sock->getPthreadRunning())
167  {
168  read_cnt = 0;
169  offset = 0;
170 
171  ret = poll(&fd, 1, 1000);
172 
173  if(ret < 0)
174  {
175  sock->setRcvError(true);
176  std::cout << "polling error" << std::endl;
177  }
178  else if(ret == 0)
179  {
180  read_cnt = recv(sock->m_server_sock_, r_buffer, sizeof(r_buffer), 0);
181  if(read_cnt < 0)
182  {
183  *r_buffer = 'a';
184  chk_connection = write(sock->m_server_sock_, r_buffer, sizeof(r_buffer));
185 
186  if(chk_connection == -1)
187  {
188  sock->setRcvTimeout(true);
189  std::cout << "server disconnected" << std::endl;
190  }
191  }
192  }
193  else // ret > 0
194  {
195  sock->setRcvError(false);
196 
197  read_cnt = sock->clientRead(r_buffer, sizeof(r_buffer));
198  if(read_cnt > 0)
199  {
200  sock->setRcvTimeout(false);
201  // Search packet size
202  if(packet_size == 0)
203  {
204  for(uint16_t i = 0; i < read_cnt; i++)
205  {
206  if(r_buffer[i] == 0x02)
207  {
208  for(int j = 0; j < 4; j++)
209  {
210  cp_temp[j] = r_buffer[i+1+j];
211  }
212  packet_size = strtoul((const char*) cp_temp, NULL, 16);
213  break;
214  }
215  }
216  }
217 
218  // Search ETX
219  for(uint16_t i = 0; i < read_cnt - 1; i++)
220  {
221  if(r_buffer[read_cnt - 1 - i] == 0x03)
222  {
223  read_cnt -= i;
224  break;
225  }
226  }
227 
228  if(packet_size > total_byte)
229  {
230  memcpy(buffer + total_byte, r_buffer + offset, read_cnt - offset);
231  total_byte += read_cnt - offset;
232  }
233  else if(packet_size < total_byte)
234  {
235  if(buffer[0] == 0x02 && buffer[packet_size] == 0x03)
236  {
237  total_byte = packet_size;
238  }
239  else
240  {
241  memset(buffer, 0x00, sizeof(buffer));
242  packet_size = 0;
243  total_byte = 0;
244  offset = 0;
245  }
246  }
247  else
248  {
249 
250  }
251 
252  if(packet_size !=0 && total_byte != 0 && packet_size == total_byte)
253  {
254  if(buffer[total_byte - 1] == 0x03)
255  {
256  // push in the queue
257  sock->putBufToMsg(buffer, total_byte);
258 
259  memset(buffer, 0x00, sizeof(buffer));
260  packet_size = 0;
261  total_byte = 0;
262  }
263  }
264  else
265  {
266 
267  }
268  memset(r_buffer, 0x00, sizeof(r_buffer));
269  }
270  else
271  {
272  sock->setRcvTimeout(true);
273  std::cout << "server response timeout" << std::endl;
274  }
275  }
276  }
277 
278  return 0;
279 }
280 
281 
282 int Socket::clientOpen(std::string addr, std::string port)
283 {
284  int m_server_addr_size = 0;
285  uint16_t port_num = 0;
286 
287  timeval tv;
288 
289 
290  addr_st_ = addr;
291  port_num_st_ = port;
292 
293  m_server_sock_ = socket(PF_INET, SOCK_STREAM, 0);
294 
295  if(m_server_sock_ < 0)
296  {
297  std::cout << "faild to create client socket" << std::endl;
298  return -1;
299  }
300 
301  tv.tv_sec = 0;;
302  tv.tv_usec = 500*1000;
303 
304  if(setsockopt(m_server_sock_, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)) < 0)
305  {
306  std::cout << "failed rcvtimeo setsockopt" << std::endl;
307  }
308  if(setsockopt(m_server_sock_, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)) < 0)
309  {
310  std::cout << "failed sndtimeo setsockopt" << std::endl;
311  }
312 
313  sscanf(port.c_str(), "%u", (unsigned int*)&port_num);
314 
315  memset(&m_server_addr_, 0x00, sizeof(m_server_addr_));
316 
317  m_server_addr_.sin_family = AF_INET;
318  m_server_addr_.sin_addr.s_addr = inet_addr(addr.begin().base());
319  m_server_addr_.sin_port = htons(port_num);
320 
321  m_server_addr_size = sizeof(m_server_addr_);
322 
323  if(connect(m_server_sock_, (const sockaddr*)&m_server_addr_, m_server_addr_size) < 0)
324  {
325  std::cout << "failed client connect, " << strerror(errno) << std::endl;
326  return -1;
327  }
328  else
329  {
330  m_connected_ = true;
331  }
332 
333  if(pthread_create(&pthrd_id_, NULL, readCallback, this) < 0)
334  {
335  std::cout << "pthread create failed" << std::endl;
336  return -1;
337  }
338  else
339  {
340  pthread_running_ = true;
341  }
342 
343  return 0;
344 }
345 
346 int32_t Socket::clientRead(unsigned char* buffer, uint16_t buf_size)
347 {
348  int32_t read_size = 0;
349 
350  if(m_connected_ == true)
351  {
352  read_size = recv(m_server_sock_, buffer, buf_size, 0);
353 
354  if(read_size < 0)
355  {
356  std::cout << "client read failed" << std::endl;
357  }
358 
359  return read_size;
360  }
361  else
362  {
363  std::cout << "server is disconnected" << std::endl;
364  return -1;
365  }
366 }
367 
368 int32_t Socket::clientWrite(unsigned char* buffer, uint16_t buf_size)
369 {
370  int32_t write_size = 0;
371 
372  if(m_connected_ == true)
373  {
374  write_size = send(m_server_sock_, buffer, buf_size, 0);
375  if(write_size < 0)
376  {
377  std::cout << "client write failed" << std::endl;
378 
379  try
380  {
381 
382  }
383  catch(const std::exception& e)
384  {
385  std::cerr << e.what() << '\n';
386  }
387 
388  }
389  return write_size;
390  }
391  else
392  {
393  std::cout << "server is disconnected" << std::endl;
394  return -1;
395  }
396 
397 
398 }
399 
Socket::rcv_timeout_
bool rcv_timeout_
Definition: socket.hpp:92
readCallback
void * readCallback(void *arg)
Definition: socket.cpp:150
Socket::m_connected_
bool m_connected_
Definition: socket.hpp:91
Socket::tryReconnection
int tryReconnection(void)
Definition: socket.cpp:110
Socket::setRcvError
void setRcvError(bool flag)
Definition: socket.cpp:103
Socket::getPthreadRunning
bool getPthreadRunning(void)
Definition: socket.cpp:82
Socket
Definition: socket.hpp:53
Socket::Socket
Socket()
Definition: socket.cpp:41
Socket::m_server_sock_
int m_server_sock_
Definition: socket.hpp:89
Socket::addr_st_
std::string addr_st_
Definition: socket.hpp:86
Socket::pthrd_id_
pthread_t pthrd_id_
Definition: socket.hpp:85
Socket::clientOpen
int clientOpen(void)
Socket::getRcvTimeout
bool getRcvTimeout(void)
Definition: socket.cpp:88
Socket::getRcvError
bool getRcvError(void)
Definition: socket.cpp:93
Socket::clientRead
int32_t clientRead(unsigned char *buffer, uint16_t buf_size)
Definition: socket.cpp:346
socket.hpp
Socket::clientWrite
int32_t clientWrite(unsigned char *buffer, uint16_t buf_size)
Definition: socket.cpp:368
Socket::getServerSocket
int getServerSocket(void)
Definition: socket.cpp:72
Socket::m_server_addr_
sockaddr_in m_server_addr_
Definition: socket.hpp:84
Socket::putBufToMsg
void putBufToMsg(unsigned char *buf, uint16_t size)
Definition: socket.cpp:137
Socket::rcv_error_
bool rcv_error_
Definition: socket.hpp:93
Socket::readCallback
friend void * readCallback(void *arg)
Definition: socket.cpp:150
Socket::pthread_running_
bool pthread_running_
Definition: socket.hpp:90
Socket::setRcvTimeout
void setRcvTimeout(bool flag)
Definition: socket.cpp:98
Socket::port_num_st_
std::string port_num_st_
Definition: socket.hpp:87
Socket::recvQueue
std::queue< std::vector< unsigned char > > recvQueue
Definition: socket.hpp:79
Socket::~Socket
~Socket()
Definition: socket.cpp:53
Socket::getConnected
bool getConnected(void)
Definition: socket.cpp:77


lsc_ros_driver
Author(s): Autonics-lidar
autogenerated on Sat Jan 14 2023 03:18:24