Streaming wideband data using Cyan
The purpose of this application note is to describe the mechanism used to stream wideband data streams from Cyan Rx channels to the FPGA. This application note assumes that you’ve purchased a complete host machine appropriate for your specific application. Per Vices recording solutions presently provide support for capturing instantaneous RF streams of between 4-24GHz. For more information, including upcoming support for wider capture bandwidths, please contact us.
The following instructions assume a host machine provisioned and configured dual NICs (Napatech NT200A02-SCC SmartNIC), and sufficient fast NVMe storage and bulk storage.
It refers to the following files;
- A utility to perform wideband capture of all packets on the interface, and save them to disk.
- A utility to parse the pcap files and convert them to binary sample files.
- Example python visualization script that plots the first 5000 samples.
You must make sure the following command works:
If this does not work, you will most likely need to follow the Network Configuration How-to.
You will also need to ensure that your NIC is configured for optimal performance, particularly with the MTU size and network buffer size. See sections four and five on the Performance Tuning How-to Guide.
When plotting with matplotlib and our script, you will need to have pcapng installed (note: you may need to use “pip3 install” for Python 3 in the above command). To install, please do the following:
$ sudo -i $ pip install python-pcapng
The firewall on your network may be an issue as well. To ensure that this is not an issue with all qSFP+ and MGMT ports, run the following with the name of the interface designated for qSFP+. To find the interfaces on your host system, run the following:
$ ip addr show
IMPORTANT NOTE: When configuring the firewall, you will need to turn the unit off and on again for it to work.
$ sudo firewall-cmd --zone=trusted --permanent --add-interface=enp73s0f0np0
Make sure to clone the examples repo at Per Vices Github, which is where the Python script for plotting is.
$ git clone https://github.com/pervices/examples.git
The wideband capturing of streams is implemented in two parts; first, we capture the packet stream from the Radio and record it to fast storage. Then, we parse the pcapng files to extract payload data for storage and display.
YOU MUST save all your pcap captures in the /example/sdr2disk folder otherwise the script will not run.
4.1. Start streaming
These instructions are made for the 3Gigasample/second RX boards. If you want to stream for 1Gigasample/second, please change the rate in the rx_start program flags. We will be streaming on channels A, B, C, and D.
To begin streaming run rx_start in uhd examples. On ubuntu it will be located in /lib/uhd/examples for the version of uhd installed in the system. If you are using a locally compiled version the examples will be found in host/build/examples. Use –help for an explaination of the arguments.
For baseband Rx streaming, with an RF input set at 310 MHz at -17dB:
$./rx_start --dsp-freq 0 --lo-freq 0 --rate 3000000000 --channels 0,1,2,3 --gain 64
For midband Rx streaming, with an RF input set at 510MHz at -3dB. (NOTE: this RF input is for Oracle. For Archlinux, the input power was -16dB to get similar results).
$ ./rx_start --dsp-freq 0 --lo-freq 500000000 --rate 3000000000 --channels 0,1,2,3 --gain 100
For highband Rx streaming, with an RF input set as 8.1GHz at -4dB.
$ ./rx_start --dsp-freq 0 --lo-freq 8000000000 --rate 3000000000 --channels 0,1,2,3 --gain 70
–dsp-freq adjusts the cordic shift, –lo-freq adjusts the lo shift, and –rate adjusts the sample rate. dsp-freq can be negative. If the command does not work correctly try running the command to stop streaming before trying again.
4.2. Option 1: Capturing Stream with Wireshark
This will work with any operating system with wireshark installed.
Open up wireshark when streaming data. In Wireshark, limit to 270 Kilobytes of capture. Save the data in the same folder as the plot_vita_pcapng.py file /examples/sdr2disk.
4.3. Option 2: Capturing Stream with sdr2disk
The sdr2disk script starts n2disk threads to capture the information being streamed to the sfp ports. Each n2disk thread has its own RAID controller to save the streamed data to, which can be found at /storage0, /storage1, /storage2 and /storage3. The n2disk settings can be tweaked to allow for different file sizes and setting a capture limit. To capture the data streaming off cyan, run sdr2disk as super user (ie. sudo ./sdr2disk) which is generally located in ~/scripts/sdr2disk, specifying the ports you want to capture from, duration of capture and filename for the capture:
Note 1: sfpA connects to ntxs0, sfpB connects to ntxs1, sfpC connects to ntxs2, sfpD connects to ntxs3.
Usage : ./sdr2disk -n [sfpA &| sfpB &| sfpC &| sfpD] -t [CAPTURE TIME IN SECONDS] -o [FILENAME] Any combination of ports can be used seperated by commas, please make sure you have enough storage for the specified capture time, filename will be followed by date and time of run. Examples: ./sdr2disk.sh -p sfpA,sfpB,sfpC,sfpD -t 10 -o run1 ./sdr2disk.sh -p sfpA,sfpB,sfpD -t 100 -o run2 ./sdr2disk.sh -p sfpC,sfpD -t 500 -o run3 ./sdr2disk.sh -p sfpA -t 1000 -o run4
Note 2: The captures are currently stored in sfpA:/storage0/storage, sfpB:/storage1/storage, sfpC:/storage2/storage, sfpD:/storage3/storage, under the most recent time stamped directory. This can be modified in the sdr2disk script.
4.4. Stop Streaming
To stop streaming run rx_stop (located in /lib/uhd/examples, the same as rx_start), specifying the channels you want to stop. For example to stop streaming on channel A, B, C and D, you would use the command:
or for all channels:
./rx_stop --channels 0,1,2,3
./rx_stop --channels 0,1,2,3,4,5,6,7
4.5. Plotting the Wireshark pcapng file
To plot the data captured in wireshark, run the following:
$ python plot_vita_pcapng.py File_name.pcapng Destination_IP destination_port 12bits
For 3gigasample/second Rx boards, you will need to ensure this is 12bits in the above command!
As an example, the following command would work:
$ python plot_vita_pcapng.py TMidBand-510MHz-rf.pcapng 10.10.10.10 42836 12bits
You will also be met with a series of prompts. You will need to answer as such (yes, no, yes):
$ Would you like to process all the packets ? y or n $ y $ Would you like to swap bytes of each samples ? y or n $ n $ Would you like to see the graph? y or n $ y
That is all!
4.6. Post Processing
To process the packets and extract the samples from the pcap files, run parse_pcap.sh (also installed in the ~/scripts/sdr2disk), specifying the complete location of the file, the destination address, port number, channel letter and output file header. The following examples show which destination addresses, ports and channel letters correspond to each other:
Note 1: If the script returns a message saying there exists no packets with the specified address and port, please double check the pcap file in wireshark to ensure you are trying to extract the right channels from the data capture.
Please provide; 1. Pcap or Pcapng file ( Provide complete location ie: /storage0/storage/1629230682.356592/1629230684.105763.pcap ) 2. Destination Address ( Channels A & B: 10.10.10.10 , Channels C & D: 10.10.11.10, Channels E & F: 10.10.12.10, Channels G & H: 10.10.13.10 ) 3. Desired Port number ( Channel A: 42836, Channel B: 42837, Channel C: 42838, Channel D: 42839, Channel E: 42840, Channel F: 42841, Channel G: 42842, Channel H: 42843 ) 4. Channel letter ( A, B, C, D, E, F, G, H ) 5. File header Example: bash parse_pcap.sh filename 10.10.10.10 42836 A test0 bash parse_pcap.sh filename 10.10.10.10 42837 B test1 bash parse_pcap.sh filename 10.10.11.10 42838 C test2 bash parse_pcap.sh filename 10.10.11.10 42839 D test3 bash parse_pcap.sh filename 10.10.12.10 42840 E test4 bash parse_pcap.sh filename 10.10.12.10 42841 F test5 bash parse_pcap.sh filename 10.10.13.10 42842 G test6 bash parse_pcap.sh filename 10.10.13.10 42843 H test7
Note 2: The binary values and an accompanying graph of the first 5000 samples will be found under ~/sdr2disk/bin_val_files
5. Example Data Capture
In this example, we will describe how to capture a single 500MHz stream consistening of a 10MHz sine wave, and then display it in gnradio.
As a quick start, to capture 50MHz of complex data on channels 0,1,2 at a center frequency of 701MHz, type the following command;
/lib/uhd/examples/rx_start --dsp-freq 25000000 --lo-freq 725000000 --rate 50000000 --gain 64 --channels 0,1,2
In this example, we are capturing from channels 0,1,2, and configuring the capture at 50MSPS, and saving it to the fast storage. Channels 0,1,2 correspond to sfpA and sfpB, in this example we are capturing 10 seconds of data, but the capture time is totally dependent on how much storage you have.
/home/jade/scripts/sdr2disk/sdr2disk.sh -p sfpA,sfpB -t 10 -o run11
After the stream has been successfully captured by the sdr2disk script, you can turn it off using the following command:
/lib/uhd/examples/rx_stop --channels 0,1,2
To support the fast throughputs, we save the payload data as pcapng files using the above script and use a seperate script to extract the samples after capture using parse_pcap.sh. This program parses the pcapfiles into complex binary files. The pcap files can be found in directories storage0/storage for sfpA, storage1/storage for sfpB, storage2/storage for sfpC, storage3/storage for sfpD. This example is extracting the channel A data from a pcap file. If streaming from channels A and B, the script must be run twice using the corresponding port to extract each channel.
cd /home/jade/scripts/sdr2disk/ bash parse_pcap.sh /storage0/storage/TIME/TIME.pcap 10.10.10.10 42836 A test0A bash parse_pcap.sh /storage0/storage/TIME/TIME.pcap 10.10.10.10 42837 B test0B bash parse_pcap.sh /storage1/storage/TIME/TIME.pcap 10.10.11.10 42838 C test0C bash parse_pcap.sh /storage1/storage/TIME/TIME.pcap 10.10.11.10 42838 D test0D bash parse_pcap.sh /storage2/storage/TIME/TIME.pcap 10.10.12.10 42838 E test0E bash parse_pcap.sh /storage2/storage/TIME/TIME.pcap 10.10.12.10 42838 F test0F bash parse_pcap.sh /storage3/storage/TIME/TIME.pcap 10.10.13.10 42838 G test0G bash parse_pcap.sh /storage3/storage/TIME/TIME.pcap 10.10.14.10 42838 H test0H
Note: you shall have to modify this command to the timestamp corresponding to your capture.
6. Common Errors
If you run into pf_ring errors, please update the kernel module using the following commands, or refer to the instructions at https://www.ntop.org/guides/pf_ring/get_started/git_installation.html.
To manually update pf_ring,
In the event of version mismatches, you may also be required to update ntopng, following the instructions available at: https://packages.ntop.org/apt-stable/
git clone https://github.com/ntop/PF_RING.git cd PF_RING/kernel sudo make sudo make install
By default, you can also run the following;
wget https://packages.ntop.org/apt-stable/20.04/all/apt-ntop-stable.deb sudo apt install ./apt-ntop-stable.deb
If you run into NetRxOpen errors about merging traffic on the interface, make sure netctl is stopped for the napatech interfaces using the following commands:
sudo netctl stop ntxs0 sudo netctl stop ntxs1 sudo netctl stop ntxs2 sudo netctl stop ntxs3
If you run into X11 connection errors, please add the following line to your environment or run the command in the terminal you are using:
When using this program in production, note that storing large amounts of data >12min, will cause VERY HEAVY NVMe drive usage. As throughput is a critical system requirement, the NVMe drives shipped with our host machines are heavily optimized for throughput, as opposed to reliability.
This is because the underlying system architecture needs to balance the available PCIe lanes that are connnected to each CPU with the largest possible storage and throughput. Based on extensive benchmarking, we’ve observed that enterprise NVMe drives, though providing substantially greater reliability and designed to sustain a high number of daily full disk writes, simply do not have the absolute performance requirement necessary to sustain the required disk throughput when streaming.
As a consequence of this design requirement, we strongly urge customers to treat the included NVMe drives as consumable items. Consider that a 10minute capture on two 40Gbps channels effectively consists of an entire full disk write. As a ballpark figure, consider that consumer NVMe drives generally aim to support, on average, around 600 FTW over their lifetime. However, as host machines generally require between 16-32 such SSD drives, the statistical likelyhood of any one of those NVMe drives failing is correspondingly higher. Thus, we suggest that customers replace all NVMe drives after around 300-400 runs, and should be aware of possible data corruption arising from NVMe failure.
If you have any additional questions about this topic, please feel free to reach out to us.