3 * Copyright 2004 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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 2, or (at your option)
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.
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.
27 #include <gr_udp_sink.h>
28 #include <gr_io_signature.h>
30 #include <sys/types.h>
37 gr_udp_sink::gr_udp_sink (size_t itemsize,
38 const char *ipaddrl, unsigned short portl,
39 const char *ipaddrr, unsigned short portr,
41 : gr_sync_block ("udp_sink",
42 gr_make_io_signature (1, 1, itemsize),
43 gr_make_io_signature (0, 0, 0)),
44 d_itemsize (itemsize), d_updated(false), d_mtu(mtu)
46 // Set up the address stucture for the local address and port numbers
47 inet_aton(ipaddrl, &d_ipaddr_local); // format IP address
48 inet_aton(ipaddrr, &d_ipaddr_remote); // format IP address
49 d_port_local = htons(portl); // format port number
50 d_port_remote = htons(portr); // format port number
52 d_sockaddr_local.sin_family = AF_INET;
53 d_sockaddr_local.sin_addr = d_ipaddr_local;
54 d_sockaddr_local.sin_port = d_port_local;
56 d_sockaddr_remote.sin_family = AF_INET;
57 d_sockaddr_remote.sin_addr = d_ipaddr_remote;
58 d_sockaddr_remote.sin_port = d_port_remote;
63 // public constructor that returns a shared_ptr
66 gr_make_udp_sink (size_t itemsize,
67 const char *ipaddrl, unsigned short portl,
68 const char *ipaddrr, unsigned short portr,
71 return gr_udp_sink_sptr (new gr_udp_sink (itemsize,
77 gr_udp_sink::~gr_udp_sink ()
85 omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
88 if((d_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == NULL) {
89 perror("socket open");
90 throw std::runtime_error("can't open socket");
93 // Turn on reuse address
95 if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(int))) {
96 perror("SO_REUSEADDR");
97 throw std::runtime_error("can't set socket option SO_REUSEADDR");
100 // Don't wait when shutting down
104 if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (void*)&lngr, sizeof(linger))) {
106 throw std::runtime_error("can't set socket option SO_LINGER");
109 // bind socket to an address and port number to listen on
110 if(bind (d_socket, (sockaddr*)&d_sockaddr_local, sizeof(struct sockaddr))) {
111 perror("socket bind");
112 throw std::runtime_error("can't bind socket");
115 // Not sure if we should throw here or allow retries
116 if(connect(d_socket, (sockaddr*)&d_sockaddr_remote, sizeof(struct sockaddr))) {
117 perror("socket connect");
118 throw std::runtime_error("can't connect to socket");
122 return d_socket != 0;
128 omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
131 shutdown(d_socket, SHUT_RDWR);
138 gr_udp_sink::work (int noutput_items,
139 gr_vector_const_void_star &input_items,
140 gr_vector_void_star &output_items)
142 char *in = (char *) input_items[0];
143 socklen_t bytes=0, bytes_sent=0, bytes_to_send=0;
144 unsigned int total_size = noutput_items*d_itemsize;
146 while(bytes_sent < total_size) {
147 bytes_to_send = (bytes_sent+d_mtu < total_size ? d_mtu : total_size-bytes_sent);
148 bytes =send(d_socket, (in+bytes_sent), bytes_to_send, MSG_DONTWAIT);
153 printf("Sent: %d bytes (noutput_items: %d)\n", bytes_sent, noutput_items);
156 return noutput_items;