libcyberradio  22.01.24
VitaIqUdpPort.cpp
1 /***************************************************************************
2  * \file VitaIqUdpPort.cpp
3  *
4  * \brief UDP port for handling incoming VITA 49 or I/Q data.
5  *
6  * \author DA
7  * \copyright 2016-2021 CyberRadio Solutions, Inc.
8  */
9 
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13 
14 #include <LibCyberRadio/Common/VitaIqUdpPort.h>
15 #include <stdarg.h>
16 #include <sstream>
17 
18 
19 namespace LibCyberRadio
20 {
21 
22  VitaIqUdpPort::VitaIqUdpPort(const std::string& host,
23  int port,
24  int packet_size,
25  bool debug) :
26  Debuggable(debug, ""),
27  host(host),
28  port(port),
29  packet_size(packet_size),
30  connected(false),
31  socket(NULL),
32  recv_buffer(NULL),
33  bytes_recvd(0)
34  {
35  // Set the object debug name
36  std::ostringstream oss;
37  oss << "VitaIqUdpPort " << port;
38  _debugName = oss.str();
39  // Allocate the receive buffer
40  recv_buffer = new unsigned char[packet_size];
41  memset(recv_buffer, 0, packet_size);
42  // Connect to the UDP port
43  boost::system::error_code error = boost::asio::error::host_not_found;
44  std::string s_port = (boost::format("%d") % port).str();
45  if (host.size() > 0)
46  {
47  boost::asio::ip::udp::resolver resolver(io_service);
48  auto query = resolver.resolve(boost::asio::ip::udp::v4(),host, s_port, boost::asio::ip::resolver_base::passive);
49  // boost::asio::ip::udp::resolver::resolve_query query(boost::asio::ip::udp::v4(),
50  // host, s_port,
51  // boost::asio::ip::resolver_query_base::passive);
52  io_service.run();
53  endpoint = *query.begin();
54  if (errno > 0)
55  {
56  printf("cannot resolve host IP %s error: %s\n", host.c_str(),
57  strerror(errno));
58  }
59  else
60  {
61  socket = new boost::asio::ip::udp::socket(io_service);
62  socket->open(endpoint.protocol());
63  boost::asio::socket_base::linger loption(true, 0);
64  socket->set_option(loption);
65  boost::asio::socket_base::reuse_address roption(true);
66  socket->set_option(roption);
67  boost::asio::socket_base::receive_buffer_size boption(33554432);
68  socket->set_option(boption);
69  boost::asio::socket_base::receive_buffer_size boption2;
70  socket->get_option(boption2);
71  if (boption2.value()!=33554432) {
72  printf("\nCould not set UDP buffer size!\n");
73  printf("Please run 'sudo sysctl net.core.rmem_max=50000000'.\n\n");
74  }
75  socket->bind(endpoint);
76  connected = true;
77  }
78  }
79  }
80 
81  VitaIqUdpPort::~VitaIqUdpPort()
82  {
83  connected = false;
84  io_service.restart();
85  io_service.stop();
86  if (socket != NULL)
87  {
88  socket->close();
89  delete socket;
90  }
91  // Deallocate the receive buffer
92  if (recv_buffer != NULL)
93  delete [] recv_buffer;
94  }
95 
96  void VitaIqUdpPort::read_data()
97  {
98  int socket_fd, result, num_received;
99  fd_set readset;
100  struct timeval timeout;
101  timeout.tv_sec = 0;
102  timeout.tv_usec = 100;
103 
104  socket_fd = socket->native_handle();
105  /* Socket has been created and connected to the other party */
106  do
107  {
108  FD_ZERO(&readset);
109  FD_SET(socket_fd, &readset);
110  result = select(socket_fd + 1, &readset, NULL, NULL, &timeout);
111  } while (result == -1 && errno == EINTR);
112 
113  if (result > 0)
114  {
115  if (FD_ISSET(socket_fd, &readset))
116  {
117  /* The socket_fd has data available to be read */
118  do
119  {
120  num_received = socket->receive(
121  boost::asio::buffer(
122  (void*)(recv_buffer + bytes_recvd),
123  packet_size - bytes_recvd
124  )
125  );
126  bytes_recvd += num_received;
127  }
128  while ( (num_received != 0) && (bytes_recvd < packet_size));
129  }
130  }
131  else if (result < 0)
132  {
133  /* An error ocurred, just print it to stdout */
134  }
135 
136  }
137 
138  void VitaIqUdpPort::clear_buffer()
139  {
140  memset(recv_buffer, 0, packet_size);
141  bytes_recvd = 0;
142  }
143 
144  bool VitaIqUdpPort::is_packet_ready() const
145  {
146  return (bytes_recvd == packet_size);
147  }
148 
149 } /* namespace LibCyberRadio */
150 
Defines functionality for LibCyberRadio applications.
Definition: App.h:23