summaryrefslogtreecommitdiff
path: root/gr-network/python/network/tcp_source.py
diff options
context:
space:
mode:
authorghostop14 <ghostop14@gmail.com>2020-03-04 12:58:09 -0500
committerMartin Braun <martin@gnuradio.org>2020-03-29 21:59:37 -0700
commitcc37c3e8cd5eabcb5c9d919e5fffc5d938690140 (patch)
tree42654449ea975b87aa322dfef81ed21f9bcf838e /gr-network/python/network/tcp_source.py
parent046793f8d22a774107adabdce02eb65f95b53d2e (diff)
gr-network: Add grnet networking blocks to GNU Radio
This PR is to create a new gr-network structure that includes the grnet TCP and UDP source/sink blocks for inclusion into GNU Radio. This includes new modes (TCP source/sink can act as either a TCP server/listener or a client), and UDP supports multiple new header options for dropped packet detection and integration with external sources such as the Allen Telescope Array. The UDP blocks have a number of important performance and tuning comments in the block documentation to help ensure success with the blocks, and examples for each scenario are included. This PR also deprecates the old TCP/UDP blocks but keeps them in place. The new blocks and new functionality resulted in not a 1:1 drop-in replacement for the old blocks so the old blocks were moved to the deprecated UI group to avoid breaking flowgraphs going to GR 3.9. Some of the new features included in these blocks are: 1. The only TCP block is a sink that listens for inbound connections. This inherently limits the ability to transmit data to another 3rd party application listening for data in TCP server mode. A source block is included here as well. 2. The TCP sink block supports both TCP client and server modes. 3. All blocks (TCP and UDP) support IPv6. 4. UDP blocks now include a variety of header options: None, a 64-bit sequence number that can be used to track dropped packets, CHDR, and the Allen Telescope Array header format for GR-native ATA integration. 5. UDP blocks paired with headers can now notify if any data is lost in transit. 6. UDP blocks now have the option to source 0's (no signal) to allow the flowgraph to run if no incoming data is available. 7. UDP blocks now include a buffering mechanism to ensure data is not lost between different timing domains (network packets and GNU Radio scheduler). 8. Block documentation has been added to help guide users through how to properly configure addresses for IPv6 or dual-stack operations, and tuning / testing before using UDP blocks in a production environment. 9. TCP sink has enhanced work logic to remain running and continue to listen for reconnections if a client disconnects.
Diffstat (limited to 'gr-network/python/network/tcp_source.py')
-rw-r--r--gr-network/python/network/tcp_source.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/gr-network/python/network/tcp_source.py b/gr-network/python/network/tcp_source.py
new file mode 100644
index 0000000000..4e07a68497
--- /dev/null
+++ b/gr-network/python/network/tcp_source.py
@@ -0,0 +1,86 @@
+#
+# Copyright 2009,2019,2020 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.
+#
+
+import socket
+import os
+from gnuradio import gr, blocks
+
+def _get_sock_fd(addr, port, server):
+ """
+ Get the file descriptor for the socket.
+ As a client, block on connect, dup the socket descriptor.
+ As a server, block on accept, dup the client descriptor.
+
+ Args:
+ addr: the ip address string
+ port: the tcp port number
+ server: true for server mode, false for client mode
+
+ Returns:
+ the file descriptor number
+ """
+ is_ipv6 = False
+
+ if ":" in addr:
+ sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0)
+ is_ipv6 = True
+ else:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+ if server:
+ try:
+ if is_ipv6:
+ bind_addr = addr.replace("::ffff:", "")
+ sock.bind((bind_addr, port))
+ else:
+ sock.bind((addr, port))
+
+ gr.log.info('Waiting for a connection on port ' + str(port))
+
+ sock.listen(1)
+ clientsock, address = sock.accept()
+ return os.dup(clientsock.fileno())
+ except OSError as e:
+ gr.log.error('Unable to bind to port ' + str(port))
+ gr.log.error('Error: ' + e.strerror)
+
+ if is_ipv6:
+ gr.log.error('IPv6 HINT: If trying to start a local listener, '
+ 'try "::" for the address.')
+ return None
+ except:
+ gr.log.error('Unable to bind to port ' + str(port))
+ return None
+
+ else:
+ sock.connect((addr, port))
+ return os.dup(sock.fileno())
+
+class tcp_source(gr.hier_block2):
+ def __init__(self, itemsize, addr, port, server=True):
+ #init hier block
+ gr.hier_block2.__init__(
+ self, 'tcp_source',
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(1, 1, itemsize),
+ )
+ fd = _get_sock_fd(addr, port, server)
+ self.connect(blocks.file_descriptor_source(itemsize, fd), self)