-
Notifications
You must be signed in to change notification settings - Fork 23
Home
Use any SoapySDR supported device transparently over a local network link. The remote support feature can turn any SDR into a network peripheral.
Potential use-cases for Soapy Remote:
- share the SDR device over a network
- use the device in multiple processes
- or use the device on multiple hosts
- a multi-threaded abstraction layer
- aid in embedded-device development
- or a work-around for software issues
- adapt an IPv4 SDR for an IPv6 network
SoapyRemote table of contents
Pre-built installers for various systems are available through the Pothos SDR environment.
The remote device support has no additional dependencies other than SoapySDR itself:
- Install SoapySDR: https://github.com/pothosware/SoapySDR/wiki
Recommend installing avahi on Ubuntu (used for device discovery):
sudo apt-get install avahi-daemon libavahi-client-dev
The CMake build system will locate SoapySDR development files on your system. The plugin module and SoapySDRServer application will be built and installed into the SoapySDR modules directory and bin/ directory (respectively). The SoapyRemote project must be installed on both the remote and local system.
git clone https://github.com/pothosware/SoapyRemote.git cd SoapyRemote mkdir build cd build cmake .. make sudo make install
Run the server on the remote machine (the machine with the SDR hardware):
SoapySDRServer --bind
Or specify a custom bind address and port:
SoapySDRServer --bind="0.0.0.0:1234"
IPv6 address URLs are also supported:
SoapySDRServer --bind="[::]:1234"
Start the server in the background:
sudo systemctl start SoapySDRServer #is it running? journalctl -u SoapySDRServer
Start the server automatically on startup:
sudo systemctl enable SoapySDRServer
The device should be supported transparently over the network using the standard SoapySDR API, SoapySDRUtil, and any applications built on top of the SoapySDR API. However, users will need to specify an additional device argument to engage the remote support module:
By default, the remote module will attempt to automatically discover and enumerate servers on the local network. Specify the "remote" key to engage the support module at a specific address. The value of the "remote" key should be the remote server's hostname or IP address. If a custom port was selected, the value should be specified as "myServer:portNum":
SoapySDRUtil --find="remote=myServer"
Filter out local devices with the "driver" key set to "remote". When the "driver" key specifies the "remote" plugin module, all other plugin modules will be ignored by the device enumeration routine:
SoapySDRUtil --find="remote=myServer, driver=remote"
Specify the "remote:driver" key to filter plugins on the remote system. The args will be rewritten to strip out the "remote:" key prefix. Use the "remote:" prefix to apply keys to the remote device only that would otherwise conflict with local keys:
SoapySDRUtil --find="remote=myServer, remote:driver=bladerf"
The default connection timeout is 50 milliseconds. In rare cases it may be useful to modify this timeout. Specify a new timeout value in units of microseconds using the "remote:timeout" device argument:
SoapySDRUtil --find="remote=myServer, remote:timeout=1000000"
Use UHD with a remote device when SoapyUHD is installed. The same instructions for "driver" and "remote" keys apply. We can even use SoapyRemote to share the device locally to several processes:
uhd_find_devices --args="driver=remote,remote=myServer" #use only SoapyRemote when UHD devices are available locally uhd_find_devices --args="driver=remote,remote=myServer,type=soapy" #example use of explicit type filter on remote server uhd_find_devices --args="driver=remote,remote=myServer,remote:type=b200"
Using the Soapy SDR support included in the GrOsmoSDR project, most devices can be used remotely through the GrOsmoSDR blocks and API.
First make sure that "Soapy" is one of the configured components when building GrOsmoSDR. Next, with the SoapySDRServer running, the following args may be used with the gr-osmosdr source or sink block to work with a remote device.
Key | Value | Required? | Description |
---|---|---|---|
remote | <myServer> | required | Specifies the server's hostname or address to SoapyRemote. |
soapy | 0 | optional | Instructs GrOsmoSDR to use the Soapy support. Required if GrOsmoSDR might find other devices on the local machine. |
driver | remote | optional | Instructs SoapySDR to use the remote module. Required if SoapySDR might find other devices on the local machine. |
remote:driver | <driverKey> | optional | Required if SoapySDR might find other devices on the remote machine. Example: "remote:driver=rtlsdr" |
Putting it all together:
#No devices locally, only one desired device on the remote server remoteArgs="remote=myServer" #One or more local devices, and multiple devices on the remote server remoteArgs="remote=myServer,soapy=0,driver=remote,remote:driver=rtlsdr"
SoapyRemote streams can use either udp or tcp (udp is default). The "remote:prot" key is typically a stream-specific argument, however it can also be passed in as a device argument to set the default for all streams when "remote:prot" is not specified. See the Remote stream args section for more information...
Advanced use: By default, the Soapy SDR server will bind to both IPv4 and IPv6 by default. When a remote address is not specified, the client will be able to discover both IPv4 and IPv6 services. When both services are discovered, IPv4 will be the preference. Use the "remote:ipver" key to selected the desired IP protocol version:
SoapySDRUtil --find="remote:ipver=6"
- Notice that the resulting remote addresses field will be in IPv6 format.
- If only one protocol is discovered, a result is yielded regardless of ipver.
There are several optional stream arguments for setupStream() that can be used to tweak the performance of the remote stream forwarding. Regardless, we recommend that linux users follow the instructions for sysctrl and limits.conf, as SoapyRemote can automatically take advantage of these reconfigured settings.
The remote format key specifies the stream format that should be used on the remote device. The default behaviour uses the device's native format over the link when the conversion to the local format is supported. Otherwise the remote and local endpoints use the same data format.
However, users can manually override the remote format setting:
Specify {"remote:format":"CS16"}
to use complex 16-bit integers over the link,
or specify {"remote:format":"CS8"}
to use complex 8-bit integers over the link;
and the remote stream driver will perform the conversion to/from floating point.
The remote scale specifies the floating point scale factor used
to convert between local and remote formats specified above.
By default, the device's native full-scale value is used
to convert between floats locally and integers over the link.
Users can manually override this scaling by specifying the remote scale.
For example: {"remote:format":"CS16", "remote:scale":"2048"}
Example with Python bindings:
sdr_device.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0], {"remote:scale": "2048"})
The remote MTU specifies the maximum datagram transfer size in bytes. By default the MTU is just under 1500 bytes (the default ethernet MTU). Users may increase the MTU to improve throughput. Not all hardware supports jumbo-frames. Check your ethernet configuration and hardware support before using this option.
On linux, use ifconfig to set the ethernet MTU:
sudo ifconfig eth0 mtu 4096
The remote window specifies the size of the kernel socket buffer in bytes. For applications that can tolerate large queues of samples, a large socket buffer (10s of megabytes) is recommended. The operating system may limit the upper bounds of the socket buffer size. The driver will print a warning if the buffer limit is exceeded.
On linux, use sysctrl to set the maximum socket buffer size:
#I like big buffers and I can not lie #You other developers can't deny #That when a socket walks in with an itty bitty SO_RCVBUF #And a sysctl limit in your face #You must run, sudo sysctl -w net.core.rmem_max=104857600 sudo sysctl -w net.core.wmem_max=104857600
The remote priority specifies the scheduling priority of the server forwarding threads. Its recommended to use an elevated priority for the forwarding threads to reduce latency and to avoid potential hiccups like overflows and underflows. The priority is a floating point value between -1.0 (low), 0.0 (normal), and 1.0 (high). By default, the server will try to elevate the priority for the forwarder threads. Users may need to tweak their system configuration to allow elevated thread priority. The driver will print a warning if the thread priority setting is not possible.
To allow elevated priority on linux, edit /etc/security/limits.conf and add the following line for your username:
<username> hard rtprio 99
The remote protocol specifies using the tcp or udp protocol for streams.
By default SoapyRemote streams are based around udp to preference throughput over reliability.
However, some applications will require reliability and cannot afford the chance of packet loss.
Example: {"remote:prot":"udp"}
or {"remote:prot":"tcp"}
SoapyRemote is composed of two major pieces: The server, which is an executable that runs on the remote machine. And the client, which is just a regular SoapySDR plugin module that knows how to communicate with the server.
The server operates a simple RPC protocol over the reliable TCP socket layer. The client connects to the server to perform device discovery, creation, and configuration settings. Stream configuration and controls are also implemented through the RPC, however the streams themselves use a separate protocol for high bandwidth.
Streaming operates through a windowed-datagram protcol over the unreliable UDP socket layer (although it can be switched to TCP for reliability at the expense of maximum throughput). A stream receiver endpoint socket is responsible for buffering the incoming stream data, and sending out flow control messages to the sender endpoint. The sender endpoint waits on flow control messages and forwards the stream data to the receiver. The goal of the flow control is to never send more data into the link, than there is space within the socket buffers.
- FAQ
- Build guide
- Driver guide
- SoapySDR header files
- Doxygen documentation
- Python binding support
- LuaJIT binding support
- .NET binding support
- GO binding support
- Rust binding support
- Julia binding support
- Pothos SDR Tutorial
- Help and support
- Pothos users' group
- Twitter @pothosware
- IRC chat #pothos
- Slack workspace
- Contract services
- Developer blog
- Contributing
- Donate
- Example support
- Remote access
- Multi device
- Device sharing
- SIMD converters
- Audio devices
- Osmo support
- NovenaRF support
- EVB7 support
- UHD support
- Blade RF support
- Hack RF support
- RTL-SDR support
- SDR Play support
- Radioberry support
- Red Pitaya support
- Lime Suite support
- Airspy support
- Airspy HF+ support
- PlutoSDR support
- Skylark Iris module
- Funcube Dongle Pro+
- IC-R8600 Receiver
- Epiq Sidekiq
- NetSDR support
- XTRX support
- RTL TCP support
- SpyServer support