Skip to content

Instantly share code, notes, and snippets.

@jackthepanisher
Created January 23, 2022 09:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackthepanisher/78d1d004ae5bc780ffdd68d8e096c612 to your computer and use it in GitHub Desktop.
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
'''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