GNU Radio 3.6.3 C++ API
gr_socket_pdu.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_GR_SOCKET_PDU_H
24 #define INCLUDED_GR_SOCKET_PDU_H
25 
26 #include <gr_core_api.h>
27 #include <gr_sync_block.h>
28 #include <gr_message.h>
29 #include <gr_msg_queue.h>
30 #include <gr_stream_pdu_base.h>
31 #include <boost/array.hpp>
32 #include <boost/asio.hpp>
33 
34 class gr_socket_pdu;
36 
37 GR_CORE_API gr_socket_pdu_sptr gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
38 
40  : public boost::enable_shared_from_this<tcp_connection>
41 {
42 public:
45  boost::array<char, 10000> buf;
46 
47  static pointer create(boost::asio::io_service& io_service)
48  {
49  return pointer(new tcp_connection(io_service));
50  }
51 
52  boost::asio::ip::tcp::socket& socket()
53  {
54  return socket_;
55  }
56 
57  void start(gr_socket_pdu* parent)
58  {
59  d_block = parent;
60 // message_ = "connected to gr_socket_pdu\n";
61 // boost::asio::async_write(socket_, boost::asio::buffer(message_),
62 // boost::bind(&tcp_connection::handle_write, shared_from_this(),
63 // boost::asio::placeholders::error,
64 // boost::asio::placeholders::bytes_transferred));
65 
66  socket_.async_read_some(
67  boost::asio::buffer(buf),
68  boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
69  }
70  void send(pmt::pmt_t vector){
71  size_t len = pmt::pmt_length(vector);
72  size_t offset(0);
73  boost::array<char, 10000> txbuf;
74  memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
75  boost::asio::async_write(socket_, boost::asio::buffer(txbuf, len),
76  boost::bind(&tcp_connection::handle_write, shared_from_this(),
77  boost::asio::placeholders::error,
78  boost::asio::placeholders::bytes_transferred));
79  }
80 
82 // std::cout << "tcp_connection destroyed\n";
83  }
84 
85 private:
86  tcp_connection(boost::asio::io_service& io_service)
87  : socket_(io_service)
88  {
89  }
90 
91  void handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred);
92 
93  void handle_write(const boost::system::error_code& /*error*/,
94  size_t /*bytes_transferred*/)
95  {
96  }
97 
98  boost::asio::ip::tcp::socket socket_;
99  std::string message_;
100 };
101 
102 
103 /*!
104  * \brief Gather received items into messages and insert into msgq
105  * \ingroup sink_blk
106  */
108 {
109  private:
111  gr_make_socket_pdu(std::string type, std::string addr, std::string port, int MTU);
112 
113  boost::asio::io_service _io_service;
114 
115  boost::array<char, 10000> rxbuf;
116 
117  // tcp specific
118  boost::asio::ip::tcp::endpoint _tcp_endpoint;
119 
120  // specific to tcp server
122  std::vector<tcp_connection::pointer> d_tcp_connections;
123  void tcp_server_send(pmt::pmt_t msg);
124  void tcp_client_send(pmt::pmt_t msg);
125  void udp_send(pmt::pmt_t msg);
126 
127  // specific to tcp client
129 
130  // specific to udp client/server
131  boost::asio::ip::udp::endpoint _udp_endpoint;
132  boost::asio::ip::udp::endpoint _udp_endpoint_other;
134 
135  void handle_receive(const boost::system::error_code& error, std::size_t ){
136  }
137 
138  void start_tcp_accept(){
139  tcp_connection::pointer new_connection =
140  tcp_connection::create(_acceptor_tcp->get_io_service());
141 
142  _acceptor_tcp->async_accept(new_connection->socket(),
143  boost::bind(&gr_socket_pdu::handle_tcp_accept, this, new_connection,
144  boost::asio::placeholders::error));
145  }
146 
147  void handle_tcp_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error){
148  if (!error)
149  {
150  new_connection->start(this);
151  d_tcp_connections.push_back(new_connection);
152  start_tcp_accept();
153  } else {
154  std::cout << error << std::endl;
155  }
156  }
157 
158  void run_io_service(){
159  _io_service.run();
160  }
161 
162  void handle_udp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
163  if(!error){
164  pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
165  pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
166 
167  message_port_pub( pmt::mp("pdus"), pdu );
168 
169  _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
170  boost::bind(&gr_socket_pdu::handle_udp_read, this,
171  boost::asio::placeholders::error,
172  boost::asio::placeholders::bytes_transferred));
173  } else {
174  throw boost::system::system_error(error);
175 // std::cout << "error occurred\n";
176  }
177  }
178  void handle_tcp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
179  if(!error)
180  {
181  pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
182  pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
183 
184  message_port_pub( pmt::mp("pdus"), pdu );
185 
186  _tcp_socket->async_read_some(
187  boost::asio::buffer(rxbuf),
188  boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
189 
190  } else {
191  //std::cout << "error occurred\n";
192  throw boost::system::system_error(error);
193  }
194  }
195 
196  protected:
197  gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
198  public:
200 };
201 
202 #endif /* INCLUDED_GR_TUNTAP_PDU_H */