Full ZigBee SDR Receiver in the Browser

2022-03-02

Some months ago, we showed a complete SDR waterfall plot running in the browser. It interfaced an RTL-SDR from within the browser, using cross-compiled drivers. In short, this requires compiling the driver to WebAssembly (Wasm) using Emscripten and a shim that maps libusb to WebUSB calls.

Signal processing was implemented with FutureSDR. It even supported wgpu custom buffers for platform-independent GPU acceleration. Wgpu is really awesome. It supports all major platforms, using their native backends: Linux/Android (→ Vulkan), Windows (→ DX12), macOS/iOS (→ Metal), and Wasm (→ WebGPU).

What was missing was a real, non-trivial SDR application. We were curious what is possible, so we developed a ZigBee receiver and cross-compiled it to Wasm. Furthermore, since the RTL-SDR doesn’t work in the 2.4GHz band and doesn’t provide the required bandwidth, we cross-compiled the driver of the HackRF in a similar fashion.

To test the receiver, we generated ZigBee frames with Scapy and sent them using an ATUSB IEEE 802.15.4 USB Adapter.

import time
from scapy.all import *

# linux: include/uapi/linux/if_ether.h
ETH_P_IEEE802154 = 0x00f6

i = 0
while True:
    fcf = Dot15d4FCS()
    data = Dot15d4Data(dest_panid=0x47d0, dest_addr=0x0000, src_panid=0x47d0, src_addr=0xee64)
    frame_data = fcf/data/f"FutureSDR {i}"
    frame_data.show()
    sendp(frame_data, iface='monitor0', type=ETH_P_IEEE802154)
    time.sleep(0.4)
    i += 1

Turns out, this actually works and the 4Msps of the ZigBee receiver can be processed in real-time in the browser. We host a demo on our website, which is hard-coded to ZigBee channel 26 @ 2.48GHz. The receiver is, however, also part of the examples. It works just as well as native binary outside the browser, using SoapySDR to interface the hardware.

At the moment, the FutureSDR receiver only uses one thread that is, however, separate from the HackRF RX thread, spawned by the driver. Compiling in release mode, FutureSDR uses around 20% CPU on an Intel i7-8700K. See the demo video here:

And as usual, everything just works on the phone. This is not an Android application with cross-compiled drivers. It runs the whole ZigBee receiver in the Google Chrome browser that is shipped with my phone. Really fascinating what is possible in the browser these days…

Phone Setup

If you have ideas for cool applications, feel free to reply to one of the Twitter threads :-)