gr-baz Package
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 #include <iostream>
34 
35 class gr_socket_pdu;
37 
38 GR_CORE_API gr_socket_pdu_sptr gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
39 
41  : public boost::enable_shared_from_this<tcp_connection>
42 {
43 public:
46  boost::array<char, 10000> buf;
47 
48  static pointer create(boost::asio::io_service& io_service)
49  {
50  return pointer(new tcp_connection(io_service));
51  }
52 
53  boost::asio::ip::tcp::socket& socket()
54  {
55  return socket_;
56  }
57 
58  void start(gr_socket_pdu* parent)
59  {
60  d_block = parent;
61 // message_ = "connected to gr_socket_pdu\n";
62 // boost::asio::async_write(socket_, boost::asio::buffer(message_),
63 // boost::bind(&tcp_connection::handle_write, shared_from_this(),
64 // boost::asio::placeholders::error,
65 // boost::asio::placeholders::bytes_transferred));
66 
67  socket_.async_read_some(
68  boost::asio::buffer(buf),
69  boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
70  }
71  void send(pmt::pmt_t vector){
72  size_t len = pmt::pmt_length(vector);
73  size_t offset(0);
74  boost::array<char, 10000> txbuf;
75  memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
76  boost::asio::async_write(socket_, boost::asio::buffer(txbuf, len),
77  boost::bind(&tcp_connection::handle_write, shared_from_this(),
78  boost::asio::placeholders::error,
79  boost::asio::placeholders::bytes_transferred));
80  }
81 
83 // std::cout << "tcp_connection destroyed\n";
84  }
85 
86 private:
87  tcp_connection(boost::asio::io_service& io_service)
88  : socket_(io_service)
89  {
90  }
91 
92  void handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred);
93 
94  void handle_write(const boost::system::error_code& /*error*/,
95  size_t /*bytes_transferred*/)
96  {
97  }
98 
99  boost::asio::ip::tcp::socket socket_;
100  std::string message_;
101 };
102 
103 
104 /*!
105  * \brief Gather received items into messages and insert into msgq
106  * \ingroup sink_blk
107  */
109 {
110  private:
112  gr_make_socket_pdu(std::string type, std::string addr, std::string port, int MTU);
113 
114  boost::asio::io_service _io_service;
115 
116  boost::array<char, 10000> rxbuf;
117 
118  // tcp specific
119  boost::asio::ip::tcp::endpoint _tcp_endpoint;
120 
121  // specific to tcp server
123  std::vector<tcp_connection::pointer> d_tcp_connections;
124  void tcp_server_send(pmt::pmt_t msg);
125  void tcp_client_send(pmt::pmt_t msg);
126  void udp_send(pmt::pmt_t msg);
127 
128  // specific to tcp client
130 
131  // specific to udp client/server
132  boost::asio::ip::udp::endpoint _udp_endpoint;
133  boost::asio::ip::udp::endpoint _udp_endpoint_other;
135 
136  void handle_receive(const boost::system::error_code& error, std::size_t ){
137  }
138 
139  void start_tcp_accept(){
140  tcp_connection::pointer new_connection =
141  tcp_connection::create(_acceptor_tcp->get_io_service());
142 
143  _acceptor_tcp->async_accept(new_connection->socket(),
144  boost::bind(&gr_socket_pdu::handle_tcp_accept, this, new_connection,
145  boost::asio::placeholders::error));
146  }
147 
148  void handle_tcp_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error){
149  if (!error)
150  {
151  new_connection->start(this);
152  d_tcp_connections.push_back(new_connection);
153  start_tcp_accept();
154  } else {
155  std::cout << error << std::endl;
156  }
157  }
158 
159  void run_io_service(){
160  _io_service.run();
161  }
162 
163  void handle_udp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
164  if(!error){
165  pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
166  pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
167 
168  message_port_pub( pmt::mp("pdus"), pdu );
169 
170  _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
171  boost::bind(&gr_socket_pdu::handle_udp_read, this,
172  boost::asio::placeholders::error,
173  boost::asio::placeholders::bytes_transferred));
174  } else {
175  throw boost::system::system_error(error);
176 // std::cout << "error occurred\n";
177  }
178  }
179  void handle_tcp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
180  if(!error)
181  {
182  pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
183  pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
184 
185  message_port_pub( pmt::mp("pdus"), pdu );
186 
187  _tcp_socket->async_read_some(
188  boost::asio::buffer(rxbuf),
189  boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
190 
191  } else {
192  //std::cout << "error occurred\n";
193  throw boost::system::system_error(error);
194  }
195  }
196 
197  protected:
198  gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
199  public:
201 };
202 
203 #endif /* INCLUDED_GR_TUNTAP_PDU_H */