| /* -*- c++ -*- */ |
| /* |
| * Copyright 2013 Free Software Foundation, Inc. |
| * |
| * This file is part of GNU Radio |
| * |
| * GNU Radio is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 3, or (at your option) |
| * any later version. |
| * |
| * GNU Radio is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with GNU Radio; see the file COPYING. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <gnuradio/thread/thread.h> |
| #include <gnuradio/io_signature.h> |
| #include <gnuradio/blocks/pdu.h> |
| #include <pmt/pmt.h> |
| |
| #include <boost/lexical_cast.hpp> |
| #include "udp_socket.h" |
| |
| using boost::asio::ip::udp; |
| |
| namespace gr { |
| namespace gsm { |
| |
| udp_socket::udp_socket( |
| const std::string &remote_addr, |
| const std::string &src_port, |
| const std::string &dst_port, |
| size_t mtu) |
| { |
| // Resize receive buffer according to MTU value |
| d_rxbuf.resize(mtu); |
| |
| // Resolve remote host address |
| udp::resolver resolver(d_io_service); |
| |
| udp::resolver::query rx_query( |
| udp::v4(), remote_addr, src_port, |
| boost::asio::ip::resolver_query_base::passive); |
| udp::resolver::query tx_query( |
| udp::v4(), remote_addr, dst_port, |
| boost::asio::ip::resolver_query_base::passive); |
| |
| d_udp_endpoint_rx = *resolver.resolve(rx_query); |
| d_udp_endpoint_tx = *resolver.resolve(tx_query); |
| |
| // Create a socket |
| d_udp_socket.reset(new udp::socket(d_io_service, d_udp_endpoint_rx)); |
| |
| // Setup read handler |
| d_udp_socket->async_receive_from( |
| boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx, |
| boost::bind(&udp_socket::handle_udp_read, this, |
| boost::asio::placeholders::error, |
| boost::asio::placeholders::bytes_transferred)); |
| |
| // Start server |
| d_thread = gr::thread::thread( |
| boost::bind(&udp_socket::run_io_service, this)); |
| } |
| |
| udp_socket::~udp_socket() |
| { |
| // Stop server |
| d_io_service.stop(); |
| d_thread.interrupt(); |
| d_thread.join(); |
| } |
| |
| void |
| udp_socket::run_io_service(void) |
| { |
| d_io_service.run(); |
| } |
| |
| void |
| udp_socket::udp_send(uint8_t *data, size_t len) |
| { |
| d_udp_socket->send_to( |
| boost::asio::buffer(data, len), |
| d_udp_endpoint_tx); |
| } |
| |
| void |
| udp_socket::handle_udp_read( |
| const boost::system::error_code& error, |
| size_t bytes_transferred) |
| { |
| if (error) |
| return; |
| |
| // Call incoming data handler |
| if (udp_rx_handler != NULL) |
| udp_rx_handler((uint8_t *) &d_rxbuf[0], bytes_transferred); |
| |
| d_udp_socket->async_receive_from( |
| boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx, |
| boost::bind(&udp_socket::handle_udp_read, this, |
| boost::asio::placeholders::error, |
| boost::asio::placeholders::bytes_transferred)); |
| } |
| |
| } /* namespace gsm */ |
| }/* namespace gr */ |