Skip to main content

Remote RF

A python API to remotely access signal centric hardware.

Courtesy of Wireless Lab @ UCLA. - Ethan Ge

Prerequisites

  • Python 3.10: This package works in Python 3.10+. If you don’t have Python installed, you can download it from the official Python website.

To check your current Python version, open a terminal and run:

python --version
  • UCLA VPN: Please ensure that you are connected to the UCLA VPN. You can download and configure the VPN client from the following link: UCLA VPN Client Download. If you’re not connected to the VPN, you will not have access to the lab servers.

Installation

Use the package manager pip to install remoteRF. It is recommended that you install this package within a virtual environment.

python3 -m venv venv        # Create virtual environment
source venv/bin/activate    # Activate virtual environment

pip install remoterf        # Install remoteRF

NI USRP-2901, Ettus B205-mini, B200-family, and USRP N210

The packaged client natively includes the shared USRP schema for the qualified NI USRP-2901, Ettus Research USRP B205-mini, the broader USB/B200 family, and the Ethernet-connected N210. No custom client driver is required. The B205-mini uses the same native-style API and reports its live 1 RX/1 TX channel topology through remoterf_capabilities.

After reserving a server-local usrp inventory entry, fetch or refresh its Dynamic v2 package with the reservation token:

from remoteRF.drivers import ensure_driver

ensure_driver(token="reservation-token")

Both supported initialization forms then use the same generated runtime:

from remoteRF.drivers.usrp import uhd

with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
    print(usrp.remoterf_capabilities)
    usrp.set_rx_rate(1e6)
from remoteRF.drivers.usrp import MultiUSRP

usrp = MultiUSRP("reservation-token")
try:
    print(usrp.get_pp_string())
finally:
    usrp.close()

Streaming uses NumPy buffers and native-like UHD value objects. Only the leading region reported by native UHD is changed on a partial receive:

import numpy as np
from remoteRF.drivers.usrp import uhd

with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
    stream_args = uhd.usrp.StreamArgs("fc32", "sc16")
    stream_args.channels = [0]
    with usrp.get_rx_stream(stream_args) as rx:
        samples = np.empty(4096, dtype=np.complex64)
        metadata = uhd.types.RXMetadata()
        count = rx.recv(samples, metadata, 0.25)
        valid_samples = samples[:count]

The generated package includes native-like namespaces, aliases, overload stubs, deterministic close(), context managers, opaque session-bound handles, and typed errors in remoteRF.core.v2_errors. Streamers are never silently recreated after a disconnect; reopen a new device session and configure a new stream explicitly.

Methods marked deferred in the fetched schema remain available through generic native dispatch, but are not release-qualified as exact UHD overload parity until the server's UHD 4.10 target-introspection and hardware differential gates pass.

RTL-SDR

RTL-SDR clients are generated from the server's rtl_sdr schema. The machine running client code does not need librtlsdr or PyRtlSdr:

from remoteRF.drivers import ensure_driver

token = "reservation-token"
ensure_driver(token=token)

from remoteRF.drivers.rtl_sdr import RtlSdr

sdr = RtlSdr(token)
sdr.sample_rate = 2_048_000
sdr.center_freq = 100_000_000
sdr.gain = "auto"
sdr.agc_mode = True

samples = sdr.read_samples(16_384)  # NumPy complex64
raw_iq = sdr.read_bytes(4096)       # packed uint8 I/Q bytes

The server owns the USB handle for its lifetime, so the generated client does not close the physical radio. read_samples and read_bytes are bounded to a 4 MiB response. Call them repeatedly for longer captures. Native asynchronous callbacks are not transported remotely.

When a Tailscale address differs from the IP or DNS identity in the server certificate, keep TLS verification enabled and set the expected identity:

export REMOTERF_ADDR=rrf2.example.ts.net:61005
export REMOTERF_TLS_SERVER_NAME=certificate-name.example

TI mmWave radar

TI radar clients are generated from the server's ti_mmwave schema. Only the machine physically connected to the radar needs pyserial or a CP210x driver. The initial parser profile supports xWR68xx mmWave SDK 3 out-of-box TLV output.

from remoteRF.drivers import ensure_driver

token = "reservation-token"
ensure_driver(token=token)

from remoteRF.drivers.ti_mmwave import TiMmWave, decode_frame

radar = TiMmWave(token)
print(radar.device_info)
print(radar.query_version())

radar.apply_config(open("profile.cfg").read(), start=True)
try:
    packet = radar.read_frame(timeout=1.0)
    frame = decode_frame(packet)
    print(frame.header.frame_number, frame.points, frame.side_info)
finally:
    radar.stop()

read_frame() returns one complete binary UART packet. Decoding is client-local and retains unknown TLVs as raw bytes, allowing custom firmware to be captured before a dedicated parser profile is added. stream_stats reports dropped frames, queued frames, resynchronization bytes, invalid headers, and reader health. Remote firmware flashing is deliberately unsupported.

If pip install doesn't work, you can clone the source directly from github.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

remoterf-2.0.8.tar.gz (101.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

remoterf-2.0.8-py3-none-any.whl (95.3 kB view details)

Uploaded Python 3

File details

Details for the file remoterf-2.0.8.tar.gz.

File metadata

  • Download URL: remoterf-2.0.8.tar.gz
  • Upload date:
  • Size: 101.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.2

File hashes

Hashes for remoterf-2.0.8.tar.gz
Algorithm Hash digest
SHA256 aa39fecb3313fd2b5b774f1b3658f6f883f1845c8022e30e8273f50db813e701
MD5 df70a63ff53ef3324a115a30257f871c
BLAKE2b-256 367dcb32024525aeee01a8ba620e6d32a036c57336b166d1e8ebe05de2deef57

See more details on using hashes here.

File details

Details for the file remoterf-2.0.8-py3-none-any.whl.

File metadata

  • Download URL: remoterf-2.0.8-py3-none-any.whl
  • Upload date:
  • Size: 95.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.2

File hashes

Hashes for remoterf-2.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 cef70ff196c5bc44fa7cb82adfc0394f10a69223aeed35d1eb6c5b015aaecd4c
MD5 45f24a86afdb1579f5b7c37749e267a6
BLAKE2b-256 beabf4c3b7ed7286068ca7b37380bfe83aa886097776b8b7f8b4cc7501837e0c

See more details on using hashes here.

Release history Release notifications | RSS feed

2.0.14

2 files

2.0.13

2 files

2.0.12

2 files

2.0.11

2 files

2.0.10

2 files

2.0.9

2 files

This release

2.0.8 This release

2 files

2.0.7

2 files

2.0.4

2 files

2.0.3

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.1.8

2 files

1.1.7

2 files

1.1.6

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.10

1 file

1.0.9

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

0.1.0.3

2 files

0.1.0.2

2 files

0.1.0.1

2 files

0.1.0.0

2 files

0.0.7.54

2 files

0.0.7.53

2 files

0.0.7.52

2 files

0.0.7.50

2 files

0.0.7.48

2 files

0.0.7.47

2 files

0.0.7.46

2 files

0.0.7.45

2 files

0.0.7.44

2 files

0.0.7.43

2 files

0.0.7.41

2 files

0.0.7.40

2 files

0.0.7.39

2 files

0.0.7.38

2 files

0.0.7.37

2 files

0.0.7.36

2 files

0.0.7.35

2 files

0.0.7.34

2 files

0.0.7.33

2 files

0.0.7.32

2 files

0.0.7.31

2 files

0.0.7.30

2 files

0.0.7.29

2 files

0.0.7.28

2 files

0.0.7.27

2 files

0.0.7.26

2 files

0.0.7.25

2 files

0.0.7.24

2 files

0.0.7.23

2 files

0.0.7.22

2 files

0.0.7.21

2 files

0.0.7.20

2 files

0.0.7.19

2 files

0.0.7.18

2 files

0.0.7.17

2 files

0.0.7.16

2 files

0.0.7.15

2 files

0.0.7.14

2 files

0.0.7.13

2 files

0.0.7.11

2 files

0.0.7.10

2 files

0.0.7.9

2 files

0.0.7.8

2 files

0.0.7.7

2 files

0.0.7.6

2 files

0.0.7.5

2 files

0.0.7.4

2 files

0.0.7.3

2 files

0.0.7.2

2 files

0.0.7.1

2 files

0.0.6.14

2 files

0.0.6.13

2 files

0.0.6.12

2 files

0.0.6.11

2 files

0.0.6.10

2 files

0.0.6.9

2 files

0.0.6.8

2 files

0.0.6.7

2 files

0.0.6.6

2 files

0.0.6.5

2 files

0.0.6.4

2 files

0.0.6.3

2 files

0.0.6.2

2 files

0.0.6.1

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

0.0.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page