2024-02-21 23:41:29 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
import struct
|
|
|
|
from socket import (AF_INET, MSG_DONTWAIT, SO_REUSEADDR, SO_SNDBUF,
|
|
|
|
SOCK_STREAM, SOL_SOCKET, socket)
|
2024-02-21 23:41:29 +01:00
|
|
|
|
|
|
|
import click
|
|
|
|
import serial
|
|
|
|
|
2024-06-06 22:04:47 +02:00
|
|
|
COMMAND_NAMES = [
|
|
|
|
"reset",
|
|
|
|
"tune_freq",
|
|
|
|
"sample_rate",
|
|
|
|
"manual_gain",
|
|
|
|
"gain",
|
|
|
|
"ppm_offset",
|
|
|
|
"if_gain",
|
|
|
|
"test_mode",
|
|
|
|
"agc",
|
|
|
|
"direct_sampling",
|
|
|
|
"offset_tuning",
|
|
|
|
"11",
|
|
|
|
"12",
|
|
|
|
"gain_index",
|
|
|
|
"bias_tee",
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def describe(cmd: int, arg: int):
|
|
|
|
try:
|
|
|
|
print("->", COMMAND_NAMES[cmd], arg)
|
|
|
|
except IndexError:
|
|
|
|
print("->", cmd, arg)
|
|
|
|
|
2024-02-21 23:41:29 +01:00
|
|
|
|
|
|
|
@click.command()
|
2024-06-06 11:24:31 +02:00
|
|
|
@click.option("-f", "--frequency", default=88200000, help="Frequency to tune to")
|
2024-06-25 18:09:56 +02:00
|
|
|
@click.option("-d", "--device", default="/dev/ttyACM0", help="Serial port device")
|
|
|
|
def bridge(frequency, device):
|
2024-02-21 23:41:29 +01:00
|
|
|
sock = socket(AF_INET, SOCK_STREAM)
|
2024-06-06 11:24:31 +02:00
|
|
|
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
2024-02-21 23:41:29 +01:00
|
|
|
sock.setsockopt(SOL_SOCKET, SO_SNDBUF, 1024 * 100)
|
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
print("Posing as rtl_tcp at tcp://127.0.0.1:1234")
|
|
|
|
sock.bind(("127.0.0.1", 1234))
|
|
|
|
sock.listen(3)
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
while True:
|
|
|
|
peer, addr = sock.accept()
|
|
|
|
print("Client connected:", addr)
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-25 18:09:56 +02:00
|
|
|
with serial.Serial(device, baudrate=10_000_000, timeout=0.1) as fp:
|
2024-06-06 11:24:31 +02:00
|
|
|
print(f"Starting RX @ {frequency}")
|
2024-06-07 10:00:10 +02:00
|
|
|
|
|
|
|
# Remove any leftovers.
|
|
|
|
while fp.read(64):
|
|
|
|
fp.write(b"\x00")
|
|
|
|
fp.flush()
|
|
|
|
|
|
|
|
fp.write(struct.pack(">BL", 1, int(frequency)))
|
2024-06-06 11:24:31 +02:00
|
|
|
fp.flush()
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
print("Begin")
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-08-04 17:32:14 +02:00
|
|
|
header = fp.read(12)
|
|
|
|
if header:
|
|
|
|
peer.send(header)
|
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
try:
|
|
|
|
cmd = b""
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
cmd += peer.recv(1, MSG_DONTWAIT)
|
|
|
|
except BlockingIOError:
|
|
|
|
pass
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
while len(cmd) >= 5:
|
|
|
|
fp.write(cmd[:5])
|
2024-06-09 13:05:52 +02:00
|
|
|
info = struct.unpack(">Bl", cmd[:6])
|
2024-06-06 22:04:47 +02:00
|
|
|
describe(*info)
|
2024-06-06 11:24:31 +02:00
|
|
|
cmd = cmd[5:]
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
data = fp.read(64)
|
|
|
|
if data:
|
|
|
|
peer.send(data)
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
except ConnectionError:
|
|
|
|
pass
|
2024-02-21 23:41:29 +01:00
|
|
|
|
2024-06-06 11:24:31 +02:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass
|
|
|
|
|
|
|
|
finally:
|
|
|
|
fp.write(b"\x00")
|
2024-06-07 10:00:10 +02:00
|
|
|
fp.flush()
|
2024-06-06 11:24:31 +02:00
|
|
|
print("Bye.")
|
2024-02-21 23:41:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
bridge()
|