BorIP

From SpenchWiki
Jump to: navigation, search

Summary

BorIP is a server that acts as an interface between a USRP and a networked-client. This is particularly useful for the USRP 1, which requires a USB connection to a computer (the newer USRPs already use Ethernet).

The server allows you to situate your USRP closer to your antennas, control it remotely, and receive baseband data over your LAN. Therefore you can develop and test your SDR applications at a distance from your receiver, enabling it to be closer to outdoor antennas and minimising RF cable lengths.

Download it on the USRP Interfaces page (this also contains a demo video).

At the very least, you should read the Notes section below.

The main site also have a less-technical page with screenshots.

Clients

  • An ExtIO plugin for Winrad/HDSDR/WRplus: ExtIO_USRP
  • borip UDP source for GNU Radio allows for seamless use of remote devices, as well as use in GRC (a patch enables BorIP support in gr_udp_source, and baz.borip emulates usrp_source_c by transparently handling client communication).

Command-line arguments

  • Prepended with either / or -
    • port - set port to listen on (28888 by default)
    • device - supply without parameter to automatically create default UHD device, or give hint to specify which device to create
  • If you wish to apply these at Autorun time, append them to the registry key at:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\BorIP

Notes

  • Server limitations:
    • Only serves one client at a time. If an existing connection exists, other connections are disconnected (see Protocol for automatic BUSY response in this case).
    • Only connects to one device at a time.
    • Only sends baseband data to one UDP destination (no multiple destinations/broadcast/multicast... yet).
  • Cannot disconnect device once it has been 'created' in server. This will cause the server to crash (can't help this).
  • Packets can be sent with (the default), or without headers. ExtIO_USRP requires headers. If you want to stream directly to a destination that expects raw baseband data, remember to switch headers OFF (see below).

USB Driver Installation

Please refer to the USRP Zadig page.

Device creation (hint)

USRP

The hint is used to specify which device to create, and implies whether the UHD or Legacy interface is used:

  • A blank hint implies the default device, which depends on whether you are connecting to a local device, or a remote server:
    • For a local device, this means the default device that UHD will find.
    • For a remote server...
      ...that is not connected to a device, this also means the default UHD device
      ...this is already connected to a device, use that device.
  • Entering a hyphen ("-") will force a remote server to connect to the default UHD device, regardless of whether it is already connected to a device. Using it for a local device is the equivalent of leaving the hint blank.
  • To select the Legacy host interface, the following format must be used:
<device index> [sub-device[:side]] [FPGA image] [Firmware image]
  • Argument breakdown:
    • device index: a single digit (required, use 0 for the default Legacy device)
    • sub-device: a single digit, or single letter A-Z (e.g. B for USRP 1's B side)
    • side: a single digit, single letter A-Z, or AB (e.g. AB for BasicRX/LFRX)
    • FPGA image path: path (default is the Legacy default, usually std_2rxhb_2tx.rbf)
    • Firmware image path: path (default is the Legacy default, usually std.ihx)
  • Anything else is fed through to the UHD device factory (see UHD Device Identification Notes).
    • To supply a sub-device specification, simply follow the above sub-device/side format and append it to the comma-separated hint list - with the follow exception: it must conform to the UHD sub-device specification (e.g. the sub-device must be a letter, see UHD USRP 1 Application Notes).
    For example, to select the first available USRP 1 (assuming you also have other models of USRP connected) and use its B-side WBX daughterboard:
type=usrp1, B:0

FUNcube Dongle

FCD [<device index> [<I offset> [ [<gain offset> [<phase offset>]]]]] [mixergain={4,12}] [ifgain1={-3,6}]
  • Argument breakdown:
    • FCD is mandatory to select a FUNcube Dongle
    • If multiple dongles are connected, use an integer to specify the device index.
    • The offsets are expressed the same as in the FCHID application. If they are not supplied, the device's offsets will remain as they are.
    • The named key/value argument pairs can be specified in any order throughout the hint. If you wish to specify the offsets out of order, then you can also use the following key/value arguments keys: i=, q=, gain=, phase=.
      For example, to select the second FCD and set the offsets:
FCD 1 0.00156 0.00076 0.97586 0 mixergain=4 ifgain1=-3

RTL2832U-based DVB-T USB Dongle

RTL <options>

Please see the USRP Interfaces for all options.

Additional considerations & limitations

  • The clients and BorIP protocol are currently limited to complex short sample pairs
    • 2 x 16-bit samples = 4 bytes per complex sample
  • The supported frequency range of hardware is not currently checked. However, the success of a tune request is checked.
    • So for the moment, if you have a WBX for example, you will see tune requests succeed that are slightly outside the spec'ed range of the daughterboard.
  • Since the Legacy interface does not support querying what antennas are available on a specific daughterboard, it will always return the following list of possibilities:
    • TX/RX, RX2, RXA, RXB, RXAB
  • Both UHD and Legacy client ask from the host API what the FPGA clock rate is (i.e. 64MHz is not hardcoded in the client). However it may be hardcoded in the host layer (e.g. IIRC it is in Legacy), so if you are clocking your USRP at a different rate there are two options:
    1. Stick to UHD
    2. Let me know and I'll add an option that will override the clock rate

Client Protocol

Overview

  • Simple ASCII-encoded text requests and responses.
  • Most RF hardware-related numbers are stringified using float-point notation (i.e. there is a decimal point), so take care when parsing (see example protocol chat dump following the request/response definitions).
  • Each request is given a response (so one request/response pair at a time, no batching).

Example

Example (colour coding: sent to client, sent to server):

DEVICE -
DEVICE 0
DEVICE 4c69abc2|0.000000|50.500000|0.500000|64000000.000000|4096|TX/RX,RX2|4c69abc2
FREQ 123456789
FREQ OK 123456789.000000 123456735.500000 -53.504831 -53.500000
GAIN 25
GAIN OK
RATE 1000000
RATE OK 1000000.000
DEST 192.168.1.1
DEST OK
ANTENNA RX2
ANTENNA OK
GO
GO OK
STOP
STOP OK
DEVICE !
DEVICE -

Connection

  • Upon successful connection, the server will automatically send a DEVICE response (see below).
  • If the server is already in use (i.e. an existing connection exists), the following string will be sent to the new client and then the connection will be terminated:
BUSY<LF>
  • The destination for baseband data packets will be reset to the address of the connected client, and the port will be reset to 28888 (the default).
  • Baseband BorIP UDP packet headers are re-enabled if they were disabled in the previous session.

Disconnection

  • If a device is currently created, it will remain active (i.e. it is not automatically release on disconnection).

Format

  • Request format (COMMAND is case-insensitive):
<COMMAND> [<PARAMETERS>]<CR, LF or CRLF>
  • If a request is given...
    ...with parameters, it implies an action (i.e. the server should do something), and the success of the action (with any command-specific results) will be returned to the client. The exceptions are the DEVICE, GO and STOP commands.
    ...without parameters, it implies a state query of the server, and the requested state's value will be returned (there will be no indication of success or failure - this is implied in the returned value).
  • Response format (COMMAND is always UPPERCASE version that in previous request):
<COMMAND> [<SUCCESS>] [<COMMAND-SPECIFIC RESULT>]<LF>
  • Colour coding:
Request parameters
Success
An error

Generic action results

  • The following are the possible values of SUCCESS when a request is submitted with parameters:
OK      - Request was processed succesfully, and there is no further data
FAIL    - Request was processed, but an error occurred
UNKNOWN - Unknown command
DEVICE  - Request assumes a device is connected & created, but this is not the case
  • If an action request fails, and an error message is available, it will be appended to the above result.
  • There are some command-specific results not listed here, which are described below in the relevant section.

Commands & responses

DEVICE
  • The response version of this command is automatically sent when a client connects to an available server.

Parameters:

- (a hyphen) - Create default UHD device
!            - Release current device
<hint>       - See Device Hint specification

Response (this does not conform to the standard format as the SUCCESS field is never sent):

- (a hyphen) No device has been created, which is:
                an indication that no device is created (when a client first connects), or
                a failure response to attempted device creation (an error message will be appended)
If successful, the following information about the device is returned:
<DEVICE NAME>|<MIN GAIN>|<MAX GAIN>|<GAIN STEP>|<FPGA FREQ IN HZ>|<COMPLEX SAMPLE PAIRS PER PACKET>|<CSV LIST OF VALID ANTENNAS>[|<DEVICE SERIAL NUMBER>]

A COMPLEX SAMPLE PAIR is defined as a complex sample pair of (I,Q).

FREQ

Single parameter for action request:

<FREQUENCY IN HZ> - Frequency to tune to

Additional possible action request-specific success values:

LOW  - Too low for hardware
HIGH - Too high for hardware

Additional possible action request-specific results (when success is OK):

<TARGET IF IN HZ> <ACTUAL IF IN HZ> <TARGET DDC IN HZ> <ACTUAL DDC IN HZ>
     - Tune result as per UHD tune_result_t

Additional query request result (i.e. no request parameters):

<FREQUENCY IN HZ> - Frequency hardware is tuned to, or last frequency that was requested if host host interface does not support querying current tuner frequency
ANTENNA

Single parameter for action request:

<ANTENNA NAME> - Name of antenna to select

Additional query request result (i.e. no request parameters):

<ANTENNA NAME> - Currently selected antenna, or last antenna that was requested if interface does not support querying current antenna
UNKNOWN        - Host interface did not return an antenna
RATE

Single parameter for action request:

<SAMPLE RATE IN SAMPLES PER SECOND> - New rate to sample at

Additional possible action request-specific results (when success is OK):

<SAMPLE RATE IN SAMPLES PER SECOND> - Closest sampling rate that was selected by hardware following successful request above

Additional query request result (i.e. no request parameters):

<SAMPLE RATE IN SAMPLES PER SECOND> - Current sampling rate, or last rate that was requested if host interface does not support querying current rate
GAIN

Single parameter for action request:

<GAIN IN RANGE FROM DEVICE RESPONSE> - New gain/attenuation to set

Additional query request result (i.e. no request parameters):

<GAIN IN RANGE FROM DEVICE RESPONSE> - Current gain, or last gain that was requested if host interface does not support querying current gain
DEST

Single parameter for action request:

- (a hyphen)                 - Set destination to that of currently connected client on default port 28888.
<IP ADDRESS>[<:PORT NUMBER>] - IP address and optional port where baseband UDP packets will be streamed

Additional query request result (i.e. no request parameters):

<IP ADDRESS>:<PORT NUMBER> - IP address and port where baseband UDP packets will be streamed
HEADER
  • BorIP packet headers are enabled by default
  • Enable for clients that expect them, e.g. ExtIO USRP
  • Disable for clients that don't expect them, e.g. UDP Source block in GNU Radio/GRC

Single parameter for action request:

<ON|OFF> - Set whether BorIP packet headers are included in streaming UDP packets

Additional query request result (i.e. no request parameters):

<ON|OFF> - Whether BorIP packet headers will be included in streaming UDP packets
GO and STOP
  • Start and stop streaming baseband data to the pre-request destination (by default this is the client, on port 28888).
  • Neither commands take parameters.
  • If GO/STOP are issued when the server has already started/stopped, the following are appended to the resulting OK success return value respectively:
RUNNING - Already streaming data
STOPPED - Already stopped streaming data

Streaming UDP Protocol

There are two modes:

  1. BorIP packet header + raw data (default, use with ExtIO USRP)
  2. Raw data (no header) (use with UDP Source in GNU Radio/GRC)
  • See the HEADER client command on how to switch between them.
  • Raw data is limited to I/Q pairs of 16-bit short samples (i.e. 4 bytes per complex sample pair).
    • Therefore, the size of raw data in each UDP packet = 4 * <COMPLEX SAMPLE PAIRS PER PACKET (as returned from host interface)>
      This commonly means that UDP packets will be fragmented.

If BorIP packet headers are used, the following data is pre-pended to each transmitted packet:

#pragma pack(push)
#pragma pack(1)

typedef struct BorPacket {
	BYTE flags;        // BorFlags defined below
	BYTE notification; // Reserved (currently 0)
	USHORT idx;        // Sequence number (incremented each time a packet is sent, used by client to count dropped packets)
	BYTE data[1];      // First byte of raw data
} BOR_PACKET, *PBOR_PACKET;

#pragma pack(pop)

enum BorFlags
{
	BF_NONE			= 0x00,
	BF_HARDWARE_OVERRUN	= 0x01, // Used at hardware interface
	BF_NETWORK_OVERRUN	= 0x02, // Used at client (network too slow)
	BF_BUFFER_OVERRUN	= 0x04, // Used at client (client consumer too slow)
	BF_EMPTY_PAYLOAD	= 0x08, // Reserved
	BF_STREAM_START		= 0x10, // Used for first packet of newly started stream
	BF_STREAM_END		= 0x20, // Reserved (TO DO: Server sends BF_EMPTY_PAYLOAD | BF_STREAM_END)
	BF_BUFFER_UNDERRUN	= 0x40, // Used at hardware interface
	BF_HARDWARE_TIMEOUT	= 0x80  // Used at hardware interface
};

Bugs

  • On first creation of Legacy device, serial will fail to be fetched correctly (will remain blank), but device will still work.
    • If application is restarted while programmed USRP remains connected, creation of Legacy device will result in serial now being displayed.
  • Cannot start program, then connect Legacy device, then attempt to create
    • Must connect USRP first, then start program
  • Legacy is more efficient in this compilation than UHD at higher sampling rates

To Do

  • (Detect changes in power state and release device to prevent app crash when resuming.)
    • Apparently it still works if device is left connected and powered on.
  • Announce via Bounjour/custom broadcast
  • Ability to set up multiple streams
  • Buffer & request re-send of section that was dropped (e.g. lost packets)