-
-
Save jackthepanisher/78d1d004ae5bc780ffdd68d8e096c612 to your computer and use it in GitHub Desktop.
Simple TCP server script using Python to serve IQ samples to an rtl_tcp client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''Simple TCP server implementation to serve IQ samples to an rtl_tcp client''' | |
import mmap | |
import socket | |
import time | |
TUNERS = { | |
'RTLSDR_TUNER_UNKNOWN': 0, | |
'E4000': 1, | |
'FC0012': 2, | |
'FC0013': 3, | |
'FC2580': 4, | |
'R820T': 5, | |
'R828D': 6, | |
} | |
GAINS = { | |
'RTLSDR_TUNER_UNKNOWN': 0, | |
'E4000': 14, | |
'FC0012': 5, | |
'FC0013': 23, | |
'FC2580': 1, | |
'R820T': 29, | |
'R828D': 29, | |
} | |
IQFILE = 'capture.raw' | |
MAGIC = 'RTL0' | |
TUNER = 'FC0013' | |
TUNERID = TUNERS[TUNER] | |
NUMGAINS = GAINS[TUNER] | |
HEADER = MAGIC.encode('ascii') | |
HEADER += TUNERID.to_bytes(4, 'big') | |
HEADER += NUMGAINS.to_bytes(4, 'big') | |
BLOCKSIZE = 1024 | |
DATARATE = 2048000 * 2 | |
with open(IQFILE, 'r+b') as file: | |
mm = mmap.mmap(file.fileno(), 0) | |
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: | |
sock.bind(('localhost', 1234)) | |
sock.listen() | |
print("listening...") | |
conn, addr = sock.accept() | |
with conn: | |
print(f"connection from {addr}") | |
msgs = [conn.recv(255) for _ in range(2)] | |
for msg in msgs: | |
cmd = int.from_bytes(msg[:1], byteorder='big') | |
arg = int.from_bytes(msg[1:], byteorder='big') | |
if cmd == 1: | |
print(f"received command to tune to {arg} Hz") | |
elif cmd == 2: | |
print(f"received command to set iq sample rate to {arg} sps") | |
else: | |
print(f"unknown command {cmd} with argument {arg}") | |
print(f"sending header...") | |
conn.send(HEADER) | |
bytesahead = 0 | |
prevtime = None | |
print("starting to stream samples...") | |
while True: | |
now = time.perf_counter() | |
if (prevtime != None): | |
bytesahead -= (now - prevtime) * DATARATE | |
prevtime = now | |
samples = mm.read(BLOCKSIZE) | |
if mm.tell() == mm.size(): | |
print("end of file reached, restarting") | |
mm.seek(0, 0) | |
try: | |
bytessent = conn.send(samples) | |
except ConnectionResetError: | |
print("client connection closed, exiting") | |
break | |
if (bytessent > 0): | |
bytesahead += bytessent | |
if (bytesahead > 0): | |
time.sleep(bytesahead / DATARATE) | |
else: | |
print("error sending data, exiting") | |
break | |
mm.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment